Using MOSEK from .NET

 
There are two ways to use MOSEK from .NET:
Since MOSEK 7.0 we recommend using the Fusion API unless fine-grained control over the generated model is required.

Optimizer .NET API

The flat API operatates on a model with one vector of variables and one vector of constraints. It allows adding or deleting elements and reoptimizing, and allows use of advanced call-back functions.
The flat API is fully documented in MOSEK optimizer .NET API.

MOSEK/Fusion

The Fusion API provides a model-oriented API with objects for representing variables and constraints, and mechanisms for handling sparse and multi-dimensional variable sets. The Fusion API is more restrictive than the optimizer API: Some properties of variables and constraints are immutable once created, and it is not possible to delete them.
The Fusion API allows a simple declaration of variables x \in{} D as well as affine functions (Ax-b)\in{} S where D and S are simple predefined convex sets. For example, for a given matrix A\in{}\mathbb{R}^{m{\times} n} and vector b\in{}\mathbb{R}^{m} we may have
 (Ax-b)\in{}\mathcal{Q}^{m}, {\ }{\ }{\ } x \geq{} 0
where
 \mathcal{Q}^{m} = \left\{{} {\ } x \in{}\mathbb{R}^{m} {\ } | {\ } x_{1} \geq{}\sqrt{x_{2}^{2} + \ldots{} + x_{m}^{2}}{\ }\right\}{}
is a standard quadratic cone. More generally, variables and affine functions of variables are specified as belonging to either
The following sections discuss a simple model implemented using the MOSEK Fusion API.

Example: Portfolio selection

The following simple portfolio selection model, “alan”, comes from the GAMS online model collection. The objective is to invest the total wealth of 1.0 in a number of assets such that we minimize the risk, while requiring a certain expected return d.
We operate with 4 assets, hardware, software, show-biz and the risk-less treasure bill. The risk is defined by the covariance matrix
 Q = \left[{} \begin{array}{rrrr} \displaystyle{} 4.0 &\displaystyle{} 3.0 &\displaystyle{} -1.0 &\displaystyle{} 0.0 \\[0pt] \displaystyle{} 3.0 &\displaystyle{} 6.0 &\displaystyle{} 1.0 &\displaystyle{} 0.0 \\[0pt] \displaystyle{} -1.0 &\displaystyle{} 1.0 &\displaystyle{} 10.0 &\displaystyle{} 0.0 \\[0pt] \displaystyle{} 0.0 &\displaystyle{} 0.0 &\displaystyle{} 0.0 &\displaystyle{} 0.0 \\[0pt] \end{array} \right]{}
and the expected returns
 r = ( 8.0, 9.0, 12.0, 7.0 ),
respectively. A mathematical description of the model is then given as the quadratic optimization problem:
 \begin{array}{ll} \displaystyle{} \mbox{minimize}&\displaystyle{} x^{T}Qx \\[0pt] \displaystyle{} \mbox{subject to}&\displaystyle{} r^{T}x = d \\[0pt] \displaystyle{} &\displaystyle{} \sum_{i=1}^{n} x_{i} = 1 \\[0pt] \displaystyle{} &\displaystyle{} x \geq{} 0 \\[0pt] \end{array}
This is not directly applicable to Fusion, which requires a conic formulation. To that end, let
 Q = U^{T} U
be a Cholesky factorization with Cholesky factor
 U = \left[{} \begin{array}{rrrr} \displaystyle{} 2.00 &\displaystyle{} 1.50 &\displaystyle{} -0.50 &\displaystyle{} 0.00 \\[0pt] \displaystyle{} 0.00 &\displaystyle{} 1.94 &\displaystyle{} 0.90 &\displaystyle{} 0.00 \\[0pt] \displaystyle{} 0.00 &\displaystyle{} 0.00 &\displaystyle{} 2.99 &\displaystyle{} 0.00 \\[0pt] \displaystyle{} 0.00 &\displaystyle{} 0.00 &\displaystyle{} 0.00 &\displaystyle{} 0.00 \\[0pt] \end{array} \right]{}.
An equivalent formulation is then
 \begin{array}{ll} \displaystyle{} \mbox{minimize}&\displaystyle{} t \\[0pt] \displaystyle{} \mbox{subject to}&\displaystyle{} r^{T} x = d \\[0pt] \displaystyle{} &\displaystyle{} \sum_{i=1}^{n} x_{i} = 1 \\[0pt] \displaystyle{} &\displaystyle{} t \geq{}\left\Vert{} U x \right\Vert{}^{2} \\[0pt] \displaystyle{} &\displaystyle{} x \geq{} 0, \\[0pt] \end{array}
which we can write explicitly in conic form as
 \begin{array}{ll} \displaystyle{} \mbox{minimize}&\displaystyle{} t \\[0pt] \displaystyle{} \mbox{subject to}&\displaystyle{} r^{T} x = d \\[0pt] \displaystyle{} &\displaystyle{} \sum_{i=1}^{n} x_{i} = 1 \\[0pt] \displaystyle{} &\displaystyle{} (t, \frac{1}{2}, Ux) \in{}\mathcal{Q}_{r}^{6} \\[0pt] \displaystyle{} &\displaystyle{} x\geq{} 0, \\[0pt] \end{array}
where
 \mathcal{Q}_{r}^{n} = \left\{{} x \in{}\mathbb{R}^{n} {\ } | {\ } 2 x_{1} x_{2} \geq{} x_{3}^{2} + \ldots{} + x_{n}^{2} \right\}{}
is a standard rotated quadratic cone.
To implement the model, we first define the data for the problem:
  1. // Security names 
  2. private static string[]  
  3. securities = { "hardware", "software", "show-biz", "t-bills" }; 
  4. // Mean returns on securities 
  5. private static double[]  
  6. mean = { 8.0, 9.0, 12.0, 7.0 }; 
  7. // Target mean return 
  8. private static double  
  9. target = 10.0
  10.  
  11. // Factor of covariance matrix. 
  12. private static Matrix U
  13. new DenseMatrix
  14. new double[][]  
  15. { new double[] { 2.0 , 1.5 , -0.5 , 0.0 }, 
  16. new double[] { 0.0 , 1.93649167, 0.90369611, 0.0 }, 
  17. new double[] { 0.0 , 0.0 , 2.98886824, 0.0 }, 
  18. new double[] { 0.0 , 0.0 , 0.0 , 0.0 } }); 
  19. private static int numsec = securities.Length; 
Then we can create the Model object:
  1. using (Model M = new Model("alan")) 
Then we define the variables as
  1. Variable x = M.Variable("x", numsec, Domain.GreaterThan(0.0)); 
  2. Variable t = M.Variable("variance", Domain.GreaterThan(0.0)); 
and the two linear constraints
  1. // sum securities to 1.0 
  2. M.Constraint("wealth", Expr.Sum(x), Domain.EqualsTo(1.0)); 
  3. // define target expected return  
  4. M.Constraint("dmean", Expr.Dot(mean, x), Domain.GreaterThan(target)); 
and the conic constraint
  1. M.Constraint(Expr.Vstack(Expr.ConstTerm(1,0.5), 
  2. t.AsExpr(),  
  3. Expr.Mul(U,x)),  
  4. Domain.InRotatedQCone()); 
We optimize the model using
  1. M.Solve(); 
and extract the x-solution as
  1. double[] solx = x.Level(); 

Compiling Using visual studio project files

Visual studio 2012 project files are available in
  1. C:\Program Files\mosek\7\tools\examples\fusion\dotnet\vs2012  
To compile these examples please first copy them to a directory where you have write permissions.

Compiling from the command prompt

First, copy the mosekdotnet.dll to the source directory.
Start a DOS box with the Visual Studio tools available and go to the source directory The example can now be compiled with
  1. csc /r:mosekdotnet.dll /t:exe /o:alan.exe alan.cs 
then, assuming that MOSEK has been correctly installed, run with
  1. alan.exe 

Example alan for fusion

  1. // 
  2. // Copyright: Copyright (c) MOSEK ApS, Denmark. All rights reserved. 
  3. // 
  4. // File: alan.cs 
  5. // 
  6. // Purpose: This file contains an implementation of the alan.gms (as 
  7. // found in the GAMS online model collection) using Fusion/.NET.  
  8. // 
  9. // The model is a simple portfolio choice model. The objective is to 
  10. // invest in a number of assets such that we minimize the risk, while 
  11. // requiring a certain expected return. 
  12. // 
  13. // We operate with 4 assets (hardware,software, show-biz and treasure 
  14. // bill). The risk is defined by the covariance matrix 
  15. // Q = [[ 4.0, 3.0, -1.0, 0.0 ], 
  16. // [ 3.0, 6.0, 1.0, 0.0 ], 
  17. // [ -1.0, 1.0, 10.0, 0.0 ], 
  18. // [ 0.0, 0.0, 0.0, 0.0 ]] 
  19. //  
  20. // 
  21. // We use the form Q = U^T * U, where U is a Cholesky factor of Q. 
  22. // 
  23.  
  24. using System
  25. using mosek.fusion
  26.  
  27. namespace mosek 
  28. namespace fusion 
  29. namespace example 
  30. public class alan 
  31. ///////////////////////////////////////////////////////////////////// 
  32. // Problem data. 
  33.  
  34. // Security names 
  35. private static string[]  
  36. securities = { "hardware", "software", "show-biz", "t-bills" }; 
  37. // Mean returns on securities 
  38. private static double[]  
  39. mean = { 8.0, 9.0, 12.0, 7.0 }; 
  40. // Target mean return 
  41. private static double  
  42. target = 10.0
  43.  
  44. // Factor of covariance matrix. 
  45. private static Matrix U
  46. new DenseMatrix
  47. new double[][]  
  48. { new double[] { 2.0 , 1.5 , -0.5 , 0.0 }, 
  49. new double[] { 0.0 , 1.93649167, 0.90369611, 0.0 }, 
  50. new double[] { 0.0 , 0.0 , 2.98886824, 0.0 }, 
  51. new double[] { 0.0 , 0.0 , 0.0 , 0.0 } }); 
  52. private static int numsec = securities.Length
  53. public static void Main(String[] args
  54. using (Model M = new Model("alan")) 
  55. Variable x = M.Variable("x", numsec, Domain.GreaterThan(0.0)); 
  56. Variable t = M.Variable("variance", Domain.GreaterThan(0.0)); 
  57. M.Objective("minvar", ObjectiveSense.Minimize, t.AsExpr()); 
  58.  
  59. // sum securities to 1.0 
  60. M.Constraint("wealth", Expr.Sum(x), Domain.EqualsTo(1.0)); 
  61. // define target expected return  
  62. M.Constraint("dmean", Expr.Dot(mean, x), Domain.GreaterThan(target)); 
  63.  
  64. M.Constraint(Expr.Vstack(Expr.ConstTerm(1,0.5), 
  65. t.AsExpr(),  
  66. Expr.Mul(U,x)),  
  67. Domain.InRotatedQCone()); 
  68. Console.WriteLine("Solve..."); 
  69. M.Solve(); 
  70. Console.WriteLine("... Solved."); 
  71. double[] solx = x.Level(); 
  72.  
  73. Console.WriteLine("Primal solution = {0}", solx[0]); 
  74. for (int i = 1; i < numsec; ++i
  75. Console.Write(", {0}", solx[i]); 
  76. Console.WriteLine(""); 
  77. } 

Online documentation