## mmquad

The

mmquadmodule extends the Mosel language with a new type for representing quadratic expressions.To use this module, the following line must be included in the header of the Mosel model file:uses 'mmquad'The first section presents the new functionality for the Mosel language that is provided by

mmquad, namely the new type qexp and a set of subroutines that may be applied to objects of this type.Via the inter-module communication interface, the module

mmquadpublishes several of its library functions. These are documented in the second section. By means of an example it is shown how the functions published bymmquadcan be used in another module for accessing quadratic expressions and working with them.## New functionality for the Mosel language

## The type qexp and its operators

The module

mmquaddefines the type qexp to represent quadratic expressions in the Mosel Language. As shown in the following example,mmquadalso defines the standard arithmetic operations that are required for working with objects of this type. By and large, these are the same operations as for linear expressions (type linctr of the Mosel language) with in addition the possibility to multiply two decision variables or one variable with itself. For the latter, the exponential notation x^2 may be used (assuming that x is of type mpvar).## Example: using

mmquadfor Quadratic ProgrammingQuadratic expressions as defined with the help of

mmquadmay be used to define quadratic objective functions for Quadratic Programming (QP) or Mixed Integer Quadratic Programming (MIQP) problems. The Xpress-Optimizer modulemmxprsfor instance accepts expressions of type qexp as arguments for its optimization subroutines minimize and maximize, and for the procedure loadprob (see also themmxprsReference Manual). The followingmodel "Small MIQP example" uses "mmxprs", "mmquad" declarations x: array(1..4) of mpvar Obj: qexp end-declarations ! Define some linear constraints x(1) + 2*x(2) - 4*x(4) >= 0 3*x(1) - 2*x(3) - x(4) <= 100 x(1) + 3*x(2) + 3*x(3) - 2*x(4) >= 10 x(1) + 3*x(2) + 3*x(3) - 2*x(4) <= 30 2 <= x(1); x(1) <= 20 x(2) is_integer; x(3) is_integer x(4) is_free ! The objective function is a quadratic expression Obj:= x(1) + x(1)^2 + 2*x(1)*x(2) + 2*x(2)^2 + x(4)^2 ! Solve the problem and print its solution minimize(Obj) writeln("Solution: ", getobjval) forall(i in 1..4) writeln(getsol(x(i))) end-model## Procedures and functions

The module

mmquadoverloads certain subroutines of the Mosel language, replacing an argument of type linctr by the type qexp.

exportprob Export a quadratic problem to a file.getsol Get the solution value of a quadratic expression.## Published library functions

The module

mmquadpublishes some of its library functions via the service IMCI for use by other modules (see the Mosel Native Interface Reference Manual for more detail about services). The list of published functions is contained in the interface structure mmquad_imci that is defined in the module header file mmquad.h.From another module, the context of

mmquadand its communication interface can be obtained using functions of the Mosel Native Interface as shown in the following example.static XPRMnifct mm; XPRMcontext mmctx; XPRMdsolib dso; mmquad_imci mq; void **quadctx; dso=mm->finddso("mmquad"); /* Retrieve the mmquad module*/ quadctx=*(mm->getdsoctx(mmctx, dso, (void **)(&mq))); /* Get the module context and the communication interface of mmquad */Typically, a module calling functions that are provided by

mmquadwill include this module into its list of dependencies in order to make sure thatmmquadwill be loaded by Mosel at the same time as the calling module. The ``dependency'' service of the Mosel Native Interface has to be used to set the list of module dependencies:static const char *deplist[]={"mmquad",NULL}; /* Module dependency list */ static XPRMdsoserv tabserv[]= /* Table of services */ { {XPRM_SRV_DEPLST, (void *)deplist} };## Complete module example

If the Mosel procedures write / writeln are applied to a quadratic expression, they print the address of the expression and not its contents (just the same would happen for types mpvar or linctr). Especially for debugging purposes, it may be useful to be able to display some more detailed information. The module example printed below defines the procedure printqexp that displays all the terms of a quadratic expression (for simplicity's sake, we do not retrieve the model names for the variables but simply print their addresses).

model "Test printqexp module" uses "printqexp" declarations x: array(1..5) of mpvar q: qexp end-declarations printqexp(10+x(1)*x(2)-3*x(3)^2) q:= x(1)*(sum(i in 1..5) i*x(i)) printqexp(q) end-modelNote that in this model it is not necessary to load explicitly the

mmquadmodule. This will be done by theprintqexpmodule becausemmquadappears in its dependency list.#include <stdlib.h> #include "xprm_ni.h" #include "mmquad.h" /**** Function prototypes ****/ static int printqexp(XPRMcontext ctx,void *libctx); /**** Structures for passing info to Mosel ****/ /* Subroutines */ static XPRMdsofct tabfct[]= { {"printqexp", 1000, XPRM_TYP_NOT, 1, "|qexp|", printqexp} }; static const char *deplist[]={"mmquad",NULL}; /* Module dependency list */ /* Services */ static XPRMdsoserv tabserv[]= { {XPRM_SRV_DEPLST, (void *)deplist} }; /* Interface structure */ static XPRMdsointer dsointer= { 0,NULL, sizeof(tabfct)/sizeof(XPRMdsofct),tabfct, 0,NULL, sizeof(tabserv)/sizeof(XPRMdsoserv),tabserv }; /**** Structures used by this module ****/ static XPRMnifct mm; /* For storing Mosel NI function table */ /**** Initialize the module library just after loading it ****/ DSO_INIT printqexp_init(XPRMnifct nifct, int *interver,int *libver, XPRMdsointer **interf) { mm=nifct; /* Save the table of Mosel NI functions */ *interver=MM_NIVERS; /* Mosel NI version */ *libver=MM_MKVER(0,0,1); /* Module version */ *interf=&dsointer; /* Pass info about module contents to Mosel */ return 0; } /**** Implementation of "printqexp" ****/ static int printqexp(XPRMcontext ctx, void *libctx) { XPRMdsolib dso; mmquad_imci mq; mmquad_qexp q; void **quadctx; void *prev; XPRMmpvar v1,v2; double coeff; int nlin,i; dso=mm->finddso("mmquad"); /* Retrieve reference to the mmquad module*/ quadctx=*(mm->getdsoctx(ctx, dso, (void **)(&mq))); /* Get the module context and the communication interface of mmquad */ q = XPRM_POP_REF(ctx); /* Get the quadratic expression from the stack */ /* Get the number of linear terms */ mq->getqexpstat(ctx, quadctx, q, &nlin, NULL, NULL, NULL); /* Get the first term (constant) */ prev=mq->getqexpnextterm(ctx, quadctx, q, NULL, &v1, &v2, &coeff); if(coeff!=0) mm->printf(ctx, "%g ", coeff); for(i=0;i<nlin;i++) /* Print all linear terms */ { prev=mq->getqexpnextterm(ctx, quadctx, q, prev, &v1, &v2, &coeff); mm->printf(ctx,"%+g %p ", coeff, v2); } while(prev!=NULL) /* Print all quadratic terms */ { prev=mq->getqexpnextterm(ctx, quadctx, q, prev, &v1, &v2, &coeff); mm->printf(ctx,"%+g %p * %p ", coeff, v1, v2); } mm->printf(ctx,"\n"); return XPRM_RT_OK; }## Description of the library functions

clearqexpstat Free the memory allocated by getqexpstat.getqexpnextterm Enumerate the terms of a quadratic expression.getqexpsol Evaluate a quadratic expression.getqexpstat Get information about a quadratic expression.

If you have any comments or suggestions about these pages, please send mail to support@fico.com.

© Copyright 2001-2013 Fair Isaac Corporation. All rights reserved.