Using MOSEK from Python

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

Optimizer Python 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 Python 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. securities = [ "hardware", "software", "show-biz", "t-bills"
  3. # Mean returns on securities 
  4. mean = [ 8.0, 9.0, 12.0, 7.0
  5. # Target mean return 
  6. target = 10.0 
  7. # Factor of covariance matrix. 
  8. U = DenseMatrix([ [ 2.0 , 1.5 , -0.5 , 0.0 ], 
  9. [ 0.0 , 1.93649167, 0.90369611, 0.0 ], 
  10. [ 0.0 , 0.0 , 2.98886824, 0.0 ], 
  11. [ 0.0 , 0.0 , 0.0 , 0.0 ] ]) 
  12.  
  13. numsec = len(securities
Then we can create the Model object:
  1. with Model('alan') as M
Then we define the variables as
  1. x = M.variable("x", numsec, Domain.greaterThan(0.0)) 
  2. t = M.variable("t", 1, 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("t > ||Ux||"
  2. Expr.vstack(Expr.constTerm(1,0.5), 
  3. t.asExpr(), 
  4. Expr.mul(U,x)), Domain.inRotatedQCone()) 
We optimize the model using
  1. M.solve() 
  2. print "-------------Summary----------" 
and extract the x-solution as
  1. solx = x.level() 

Running the example

Assuming that MOSEK has been installed, to run the example, simply type
  1. python alan.py 

Example alan for fusion

  1. ## 
  2. # Copyright: Copyright (c) MOSEK ApS, Denmark. All rights reserved. 
  3. # 
  4. # File: alan.py 
  5. # 
  6. # Purpose: This file contains an implementation of the alan.gms (as 
  7. # found in the GAMS online model collection) using Java/Fusion.  
  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. import sys 
  25. import mosek.fusion 
  26. from mosek.fusion import
  27. from mosek.array import
  28.  
  29.  
  30. ########################################################### 
  31. ### Problem data: 
  32. #  
  33. # Security names 
  34. securities = [ "hardware", "software", "show-biz", "t-bills"
  35. # Mean returns on securities 
  36. mean = [ 8.0, 9.0, 12.0, 7.0
  37. # Target mean return 
  38. target = 10.0 
  39. # Factor of covariance matrix. 
  40. U = DenseMatrix([ [ 2.0 , 1.5 , -0.5 , 0.0 ], 
  41. [ 0.0 , 1.93649167, 0.90369611, 0.0 ], 
  42. [ 0.0 , 0.0 , 2.98886824, 0.0 ], 
  43. [ 0.0 , 0.0 , 0.0 , 0.0 ] ]) 
  44.  
  45. numsec = len(securities
  46.  
  47. ########################################################### 
  48.  
  49. def main(args): 
  50. with Model('alan') as M
  51. x = M.variable("x", numsec, Domain.greaterThan(0.0)) 
  52. t = M.variable("t", 1, Domain.greaterThan(0.0)) 
  53.  
  54. M.objective("minvar", ObjectiveSense.Minimize, t
  55.  
  56. # sum securities to 1.0 
  57. M.constraint("wealth", Expr.sum(x), Domain.equalsTo(1.0)) 
  58. # define target expected return  
  59. M.constraint("dmean", Expr.dot(mean, x), Domain.greaterThan(target)) 
  60.  
  61. M.constraint("t > ||Ux||"
  62. Expr.vstack(Expr.constTerm(1,0.5), 
  63. t.asExpr(), 
  64. Expr.mul(U,x)), Domain.inRotatedQCone()) 
  65. M.setLogHandler(sys.stdout
  66. print("Solve..."
  67. M.solve() 
  68. print "-------------Summary----------" 
  69. print("... Solved"
  70. solx = x.level() 
  71. print("Solution = " + ','.join([ str(v) for v in solx])) 
  72.  
  73. if __name__ == '__main__'
  74. main(sys.argv[1:]) 

Online documentation