The simplest optimization problem is a purely linear problem. A
linear optimization problem is a problem of the following form:
Minimize or maximize the objective function
 | (1.1) |
subject to the linear constraints
 | (1.2) |
and the bounds
 | (1.3) |
where we have used the problem elements:

and

which are the number of constraints and variables respectively,
-
which is the variable vector of length

,
-
which is a coefficient vector of size

-
which is a constant,
-
which is a

matrix of coefficients is given by

and

which specify the lower and upper bounds on constraints respectively, and

and

which specifies the lower and upper bounds on variables respectively.
Please note the unconventional notation using

as the first index rather than

. Hence,

is the first element in variable vector

. This convention has been adapted from arrays which are indexed from 0.
The following is an example of a linear optimization problem:
having the bounds
To solve the problem above we go through the following steps:
Below we explain each of these steps. For the complete source code see section
1.2.
Create an environment.
Before setting up the optimization problem, a MOSEK environment must be created. All tasks in the program should share the same environment.
- r = MSK_makeenv(&env,NULL);
Create an optimization task.
Next, an empty task object is created:
-
- r = MSK_maketask(env,numcon,numvar,&task);
-
-
- if ( r==MSK_RES_OK )
- r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
We also connect a call-back function to the task log stream. Messages related to the task are passed to the call-back function. In this case the stream call-back function writes its messages to the standard output stream.
Load a problem into the task object.
Before any problem data can be set, variables and constraints must be added to the problem via calls to the functions MSK_appendcons and MSK_appendvars.
-
-
- if ( r == MSK_RES_OK )
- r = MSK_appendcons(task,numcon);
-
-
-
- if ( r == MSK_RES_OK )
- r = MSK_appendvars(task,numvar);
New variables can now be referenced from other functions with indexes in

and new constraints can be referenced with indexes in

. More variables / constraints can be appended later as needed, these will be assigned indexes from

/

and up.
Next step is to set the problem data. We loop over each variable index

calling functions to set problem data. We first set the objective coefficient
![c_{j} = \mathtt{c[j]}](math/math27.png)
by calling the function
MSK_putcj.
-
- if(r == MSK_RES_OK)
- r = MSK_putcj(task,j,c[j]);
The bounds on variables are stored in the arrays
- MSKboundkeye bkx[] = {MSK_BK_LO, MSK_BK_RA, MSK_BK_LO, MSK_BK_LO };
- double blx[] = {0.0, 0.0, 0.0, 0.0 };
- double bux[] = {+MSK_INFINITY, 10.0, +MSK_INFINITY, +MSK_INFINITY };
and are set with calls to MSK_putvarbound.
-
-
- if(r == MSK_RES_OK)
- r = MSK_putvarbound(task,
- j,
- bkx[j],
- blx[j],
- bux[j]);
The
Bound key stored in
bkx specify the type of the bound according to Table
1.1.1.1.
Bound key
| Type of bound
| Lower bound
| Upper bound
| MSK_BK_FX
|
| Finite
| Identical to the lower bound
| MSK_BK_FR
| Free
| Minus infinity
| Plus infinity
| MSK_BK_LO
|
| Finite
| Plus infinity
| MSK_BK_RA
|
| Finite
| Finite
| MSK_BK_UP
|
| Minus infinity
| Finite
|
|
Tab. 1.1.1.1. Interpretation of the bound keys. |
For instance
bkx[0]=MSK_BK_LO means that

. Finally, the numerical values of the bounds on variables are given by
and
Recall that in our example the

matrix is given by
This matrix is stored in sparse format in the arrays:
- MSKint32t aptrb[] = {0, 2, 5, 7},
- aptre[] = {2, 5, 7, 9},
- asub[] = { 0, 1,
- 0, 1, 2,
- 0, 1,
- 1, 2};
- double aval[] = { 3.0, 2.0,
- 1.0, 1.0, 2.0,
- 2.0, 3.0,
- 1.0, 3.0};
The
ptrb,
ptre,
asub, and
aval arguments define the constraint matrix

in the column ordered sparse format.
Using the function
MSK_putacol we set column

of

- r = MSK_putacol(task,
- j,
- aptre[j]-aptrb[j],
- asub+aptrb[j],
- aval+aptrb[j]);
Alternatively, the same

matrix can be set one row at a time; please see section
1.3 for an example.
Finally, the bounds on each constraint are set by looping over each constraint index

-
-
- for(i=0; i<numcon && r==MSK_RES_OK; ++i)
- r = MSK_putconbound(task,
- i,
- bkc[i],
- blc[i],
- buc[i]);
Optimization:
After the problem is set-up the task can be optimized by calling the function MSK_optimizetrm.
- r = MSK_optimizetrm(task,&trmcode);
Extracting the solution.
After optimizing the status of the solution is examined with a call to MSK_getsolsta. If the solution status is reported as MSK_SOL_STA_OPTIMAL or MSK_SOL_STA_NEAR_OPTIMAL the solution is extracted in the lines below:
- MSK_getxx(task,
- MSK_SOL_BAS,
- xx);
The MSK_getxx function obtains the solution. MOSEK may compute several solutions depending on the optimizer employed. In this example the basic solution is requested by setting the first argument to MSK_SOL_BAS.
The complete source code is listed in
lo1.
In the example above, the

matrix is set one column at a time. The same can be done one row at a time, or the two methods can be mixed. Example
lo2 shows how to set the

matrix by rows.
This section shows the commands necessary to compile the example lo1 above from a command line and run it.
We assume that MOSEK was installed in the default location
- C:\Program Files\mosek
Open a DOS box with the Visual Studio tool chain enabled: Usually there is under Microsoft Visual Studio 20xx/Visual Studio Tools a menu point ... x64 Tools Command Prompt.
Go to the location of your example file lo1.c, e.g.
- c:
- cd \Users\me\src\lo1
Compile the example:
- cl /c /I"C:\Program Files\mosek\7\tools\platform\win64x86\h" /Folo1.obj lo1.c
- link /libpath:"C:\Program Files\mosek\7\tools\platform\win64x86\bin" mosek64_7_0 /out:lo1.exe lo1.obj
If MOSEK was correctly installed, you can now run the example by entering
- lo1
If you want to make sure that your application can run even when MOSEK is not installed, you need to do two things: First copy the essential MOSEK DLLs into your application directory:
- copy "C:\Program Files\mosek\7\tools\platform\win64x86\bin\mosek64_7_0.dll" .
- copy "C:\Program Files\mosek\7\tools\platform\win64x86\bin\libiomp5md.dll" .
- copy "C:\Program Files\mosek\7\tools\platform\win64x86\bin\mosekglb64_7_0.dll" .
Secondly, make sure that your application knows a valid license file. Usually the license file is started at
- %USERPROFILE%\mosek.lic
or rewrite your application to pass the right path immediately after the environment is created as illustrated in:
- int main(int argc, char ** argv)
- {
- char * moseklifile = argv[1];
- MSKenv_t env;
- MSKrescodee r;
-
- r = MSK_makeenv(&env, NULL);
- if ( r==MSK_RES_OK )
- r = MSK_putlicensepath(env,moseklicfile);
- ...
Above we assumed that compilation was done on an x64 machine. If you are compiling on a 32-bit architecture, you must
Replace win64x86 by win32x86.
Replace mosek64_7_0.dll by mosek7_0.dll when building.
Copy mosek7_0.dll and mosekglb_7_0.dll instead of mosek64_7_0.dll and mosekglb64_7_0.dll.
We assume that MOSEK was installed in the user's home directory
- $HOME/mosek
Open a terminal and go to the location of your example file lo1.c, e.g.
- cd ~/src/lo1
Compile the example with gcc:
- gcc -o lo1 \
- -I$HOME/mosek/7/tools/platform/linux64x86/h \
- -L$HOME/mosek/7/tools/platform/linux64x86/bin \
- -Wl,-rpath-link=$HOME/mosek/7/tools/platform/linux64x86/bin \
- -lmosek64 \
- lo1.c
If MOSEK was correctly installed, you can now run the example by entering
- lo1
If you want to make sure that your application can run even when MOSEK is not installed, you need to do three things: First, add the parameter
- -Wl,-rpath=\$ORIGIN
to te build line. This will allow the application to look for shared library dependencies in the same directory as the application executable.
Secondly, copy the essential MOSEK libraries into your application directory:
- cp $HOME/mosek/7/tools/platform/linux64x86/bin/libmosek64.so.7.1 .
- cp $HOME/mosek/7/tools/platform/linux64x86/bin/libiomp5.so .
- cp $HOME/mosek/7/tools/platform/linux64x86/bin/libmosekglb64.so.7.1 .
Finally, make sure that your application knows a valid license file. Usually the license file is stored at
- $HOME/mosek/mosek.lic
or rewrite your application to pass the right path immediately after the environment is created, for example:
- int main(int argc, char ** argv)
- {
- char * moseklicfile = argv[1];
- MSKenv_t env;
- MSKrescodee r;
-
- r = MSK_makeenv(&env,NULL);
- if ( r==MSK_RES_OK )
- r = MSK_putlicensepath(env,moseklicfile);
- ...
Above we assumed that compilation was done on an x64 machine. If you are compiling on a 32-bit architecture, you must
Replace linux64x86 by linux32x86.
Replace mosek64 by mosek when building.
Copy libmosek.so.7.1 and libmosekglb.so instead of libmosek64.so.7.1 and libmosekglb64.so.
We assume that MOSEK was installed in the user's home directory
- $HOME/mosek
Open a terminal and go to the location of your example file lo1.c, e.g.
- cd ~/src/lo1
Compile the example with gcc:
- gcc -o lo1 \
- -I$HOME/mosek/7/tools/platform/linux64x86/h \
- -L$HOME/mosek/7/tools/platform/linux64x86/bin \
- -Wl,-rpath-link=$HOME/mosek/7/tools/platform/linux64x86/bin \
- -lmosek \
- lo1.c
If MOSEK was correctly installed, you can now run the example by entering
- lo1
If you want to make sure that your application can run even when MOSEK is not installed, you need to do three things: First, modify the built binary lo1
- install_name_tool -change libmosek64.7.1.dylib @executable_path/libmosek64.7.1.dylib
This will allow the application to look for libmosek64 in the same directory as the application executable.
Secondly, copy the essential MOSEK libraries into your application directory:
- cp $HOME/mosek/\mskmajorver/tools/platform/linux64x86/bin/libmosek64.\mskmajorver.\mskminorver.dylib .
- cp $HOME/mosek/\mskmajorver/tools/platform/linux64x86/bin/libiomp5.so .
- cp $HOME/mosek/\mskmajorver/tools/platform/linux64x86/bin/libmosekglb64.\mskmajorver.\mskminorver.dylib .
Finally, make sure that your application knows a valid license file. Usually the license file is stored at
- $HOME/mosek/mosek.lic
or rewrite your application to pass the right path immediately after the environment is created, for example:
- int main(int argc, char ** argv)
- {
- char * moseklicfile = argv[1];
- MSKenv_t env;
- MSKrescodee r;
- r = MSK_makeenv(&env,NULL);
- if ( r==MSK_RES_OK )
- r = MSK_putlicensepath(env,moseklicfile);
- ...
Above we assumed that compilation was done on an x64 machine. If you are compiling on a 32-bit architecture, you must
Replace win64x86 by win32x86.
Replace mosek64 by mosek when building.
Copy libmosek.7.1.dylib and libmosekglb.dylib instead of libmosek.7.1.dylib and libmosek.7.1.dylib.
For further documentation see
-
-
-
-
-
-
-
-
-
-
-
- #include <stdio.h>
- #include "mosek.h"
-
-
- static void MSKAPI printstr(void *handle,
- MSKCONST char str[])
- {
- printf("%s",str);
- }
-
- int main(int argc,char *argv[])
- {
- const MSKint32t numvar = 4,
- numcon = 3;
-
- double c[] = {3.0, 1.0, 5.0, 1.0};
-
-
- MSKint32t aptrb[] = {0, 2, 5, 7},
- aptre[] = {2, 5, 7, 9},
- asub[] = { 0, 1,
- 0, 1, 2,
- 0, 1,
- 1, 2};
- double aval[] = { 3.0, 2.0,
- 1.0, 1.0, 2.0,
- 2.0, 3.0,
- 1.0, 3.0};
-
-
- MSKboundkeye bkc[] = {MSK_BK_FX, MSK_BK_LO, MSK_BK_UP };
- double blc[] = {30.0, 15.0, -MSK_INFINITY};
- double buc[] = {30.0, +MSK_INFINITY, 25.0 };
-
- MSKboundkeye bkx[] = {MSK_BK_LO, MSK_BK_RA, MSK_BK_LO, MSK_BK_LO };
- double blx[] = {0.0, 0.0, 0.0, 0.0 };
- double bux[] = {+MSK_INFINITY, 10.0, +MSK_INFINITY, +MSK_INFINITY };
- MSKenv_t env = NULL;
- MSKtask_t task = NULL;
- MSKrescodee r;
- MSKint32t i,j;
-
-
- r = MSK_makeenv(&env,NULL);
-
- if ( r==MSK_RES_OK )
- {
-
- r = MSK_maketask(env,numcon,numvar,&task);
-
-
- if ( r==MSK_RES_OK )
- r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
-
-
-
- if ( r == MSK_RES_OK )
- r = MSK_appendcons(task,numcon);
-
-
-
- if ( r == MSK_RES_OK )
- r = MSK_appendvars(task,numvar);
-
- for(j=0; j<numvar && r == MSK_RES_OK; ++j)
- {
-
- if(r == MSK_RES_OK)
- r = MSK_putcj(task,j,c[j]);
-
-
-
- if(r == MSK_RES_OK)
- r = MSK_putvarbound(task,
- j,
- bkx[j],
- blx[j],
- bux[j]);
-
-
- if(r == MSK_RES_OK)
- r = MSK_putacol(task,
- j,
- aptre[j]-aptrb[j],
- asub+aptrb[j],
- aval+aptrb[j]);
- }
-
-
-
- for(i=0; i<numcon && r==MSK_RES_OK; ++i)
- r = MSK_putconbound(task,
- i,
- bkc[i],
- blc[i],
- buc[i]);
-
-
- if (r == MSK_RES_OK)
- r = MSK_putobjsense(task, MSK_OBJECTIVE_SENSE_MAXIMIZE);
-
- if ( r==MSK_RES_OK )
- {
- MSKrescodee trmcode;
-
-
- r = MSK_optimizetrm(task,&trmcode);
-
-
-
- MSK_solutionsummary (task,MSK_STREAM_LOG);
-
- if ( r==MSK_RES_OK )
- {
- MSKsolstae solsta;
-
- if ( r==MSK_RES_OK )
- r = MSK_getsolsta (task,
- MSK_SOL_BAS,
- &solsta);
- switch(solsta)
- {
- case MSK_SOL_STA_OPTIMAL:
- case MSK_SOL_STA_NEAR_OPTIMAL:
- {
- double *xx = (double*) calloc(numvar,sizeof(double));
- if ( xx )
- {
- MSK_getxx(task,
- MSK_SOL_BAS,
- xx);
-
- printf("Optimal primal solution\n");
- for(j=0; j<numvar; ++j)
- printf("x[%d]: %e\n",j,xx[j]);
-
- free(xx);
- }
- else
- r = MSK_RES_ERR_SPACE;
-
- break;
- }
- case MSK_SOL_STA_DUAL_INFEAS_CER:
- case MSK_SOL_STA_PRIM_INFEAS_CER:
- case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
- case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
- printf("Primal or dual infeasibility certificate found.\n");
- break;
- case MSK_SOL_STA_UNKNOWN:
- {
- char symname[MSK_MAX_STR_LEN];
- char desc[MSK_MAX_STR_LEN];
-
-
-
-
- MSK_getcodedesc(trmcode,
- symname,
- desc);
-
- printf("The solution status is unknown.\n");
- printf("The optimizer terminitated with code: %s\n",symname);
- break;
- }
- default:
- printf("Other solution status.\n");
- break;
- }
- }
- }
-
- if (r != MSK_RES_OK)
- {
-
- char symname[MSK_MAX_STR_LEN];
- char desc[MSK_MAX_STR_LEN];
-
- printf("An error occurred while optimizing.\n");
- MSK_getcodedesc (r,
- symname,
- desc);
- printf("Error %s - '%s'\n",symname,desc);
- }
-
-
- MSK_deletetask(&task);
- }
-
-
- MSK_deleteenv(&env);
-
- return r;
- }
-
-
-
-
-
-
-
-
-
-
-
- #include <stdio.h>
- #include "mosek.h"
-
-
- static void MSKAPI printstr(void *handle,
- MSKCONST char str[])
- {
- printf("%s",str);
- }
-
- int main(int argc,char *argv[])
- {
- const int numvar = 4,
- numcon = 3;
-
- double c[] = {3.0, 1.0, 5.0, 1.0};
-
-
- MSKlidxt aptrb[] = {0, 3, 7};
- MSKlidxt aptre[] = {3, 7, 9};
- MSKidxt asub[] = { 0,1,2,
- 0,1,2,3,
- 1,3};
- double aval[] = { 3.0, 1.0, 2.0,
- 2.0, 1.0, 3.0, 1.0,
- 2.0, 3.0};
-
-
- MSKboundkeye bkc[] = {MSK_BK_FX, MSK_BK_LO, MSK_BK_UP };
- double blc[] = {30.0, 15.0, -MSK_INFINITY};
- double buc[] = {30.0, +MSK_INFINITY, 25.0 };
-
- MSKboundkeye bkx[] = {MSK_BK_LO, MSK_BK_RA, MSK_BK_LO, MSK_BK_LO };
- double blx[] = {0.0, 0.0, 0.0, 0.0 };
- double bux[] = {+MSK_INFINITY, 10.0, +MSK_INFINITY, +MSK_INFINITY };
- MSKenv_t env = NULL;
- MSKtask_t task = NULL;
- MSKrescodee r;
- MSKidxt i,j;
-
-
- r = MSK_makeenv(&env,NULL);
-
- if ( r==MSK_RES_OK )
- {
-
- r = MSK_maketask(env,numcon,numvar,&task);
-
-
- if ( r==MSK_RES_OK )
- r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
-
-
-
- if ( r == MSK_RES_OK )
- r = MSK_appendcons(task,numcon);
-
-
-
- if ( r == MSK_RES_OK )
- r = MSK_appendvars(task,numvar);
-
- for(j=0; j<numvar && r == MSK_RES_OK; ++j)
- {
-
- if(r == MSK_RES_OK)
- r = MSK_putcj(task,j,c[j]);
-
-
-
- if(r == MSK_RES_OK)
- r = MSK_putvarbound(task,
- j,
- bkx[j],
- blx[j],
- bux[j]);
- }
-
-
-
- for(i=0; i<numcon && r==MSK_RES_OK; ++i)
- {
- r = MSK_putconbound(task,
- i,
- bkc[i],
- blc[i],
- buc[i]);
-
-
- if(r == MSK_RES_OK)
- r = MSK_putarow(task,
- i,
- aptre[i]-aptrb[i],
- asub+aptrb[i],
- aval+aptrb[i]);
- }
-
-
- if (r == MSK_RES_OK)
- r = MSK_putobjsense(task, MSK_OBJECTIVE_SENSE_MAXIMIZE);
-
- if ( r==MSK_RES_OK )
- {
- MSKrescodee trmcode;
-
-
- r = MSK_optimizetrm(task,&trmcode);
-
-
-
- MSK_solutionsummary (task,MSK_STREAM_LOG);
-
- if ( r==MSK_RES_OK )
- {
- MSKsolstae solsta;
-
- if (r == MSK_RES_OK)
- r = MSK_getsolsta (task,MSK_SOL_BAS,&solsta);
- switch(solsta)
- {
- case MSK_SOL_STA_OPTIMAL:
- case MSK_SOL_STA_NEAR_OPTIMAL:
- {
- double *xx = (double*) calloc(numvar,sizeof(double));
- if ( xx )
- {
- MSK_getxx(task,
- MSK_SOL_BAS,
- xx);
-
- printf("Optimal primal solution\n");
- for(j=0; j<numvar; ++j)
- printf("x[%d]: %e\n",j,xx[j]);
- }
- else
- {
- r = MSK_RES_ERR_SPACE;
- }
-
- free(xx);
- break;
- }
- case MSK_SOL_STA_DUAL_INFEAS_CER:
- case MSK_SOL_STA_PRIM_INFEAS_CER:
- case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
- case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
- printf("Primal or dual infeasibility certificate found.\n");
- break;
- case MSK_SOL_STA_UNKNOWN:
- {
- char symname[MSK_MAX_STR_LEN];
- char desc[MSK_MAX_STR_LEN];
-
-
-
-
- MSK_getcodedesc(trmcode,
- symname,
- desc);
-
- printf("The solutuion status is unknown.\n");
- printf("The optimizer terminitated with code: %s\n",symname);
- break;
- }
- default:
- printf("Other solution status.\n");
- break;
- }
- }
- }
-
- if (r != MSK_RES_OK)
- {
-
- char symname[MSK_MAX_STR_LEN];
- char desc[MSK_MAX_STR_LEN];
-
- printf("An error occurred while optimizing.\n");
- MSK_getcodedesc (r,
- symname,
- desc);
- printf("Error %s - '%s'\n",symname,desc);
- }
-
-
- MSK_deletetask(&task);
- }
-
-
- MSK_deleteenv(&env);
-
- return r;
- }