5.7.6. SDP Modeling and Optimization in C#¶
In this chapter, we will use MindOpt C# API to model and solve the problem in Examples of semidefinite programming.
5.7.6.1. SDP Example I¶
Step I: Create an optimization model
Create an empty optimization model:
44 // Create model
45 MDOEnv env = new MDOEnv();
46 MDOModel model = new MDOModel(env);
47 model.Set(MDO.StringAttr.ModelName, "SDP_01");
Step II: SDP model input
We use MDOModel.AddPsdVar
to create a new semidefinite matrix variable representing \(\mathbf{X}\) in our example and simultaneously set its corresponding coefficient matrix \(\mathbf{C}\) in the objective function.
The first argument is the coefficient matrix, which is an instance of the
MDOMatrix
created using theMDOMatrix.Coo
method. Note that the dimensions of the coefficient matrix should match the matrix variables.The second argument is the name of the variable.
51 // Add variables.
52 MDOPsdVar psd_var = model.AddPsdVar(MDOMatrix.Coo(dim_mat, dim_mat, C_nz_indices, C_nz_values), "X0");
Next, we input the first constraint. We use MDOModel.AddPsdConstr
to establish a constraint with a semidefinite matrix variable.
The first argument is the semidefinite expression in the constraint, i.e., \(\langle \mathbf{A},\mathbf{X} \rangle\). We create it using the initialization method
MDOPsdExpr.MDOPsdExpr
.The second argument is the type of the constraint, where MDO.EQUAL (‘=’) represents an equality constraint.
The third argument is the right-hand side value of the constraint (in this case, 1.0). The last argument is the name of the constraint.
54 /* Add constraints. */
55 MDOPsdExpr psd_expr = new MDOPsdExpr(psd_var, MDOMatrix.Coo(dim_mat, dim_mat, A_nz_indices, A_nz_values));
56 model.AddPsdConstr(psd_expr, MDO.EQUAL, 1.0, "C0");
Finally, we use MDOModel.SetObjective
to set the rest of the objective function (in this case, 0), and change the optimization direction to maximization (-1).
58 /* Set objective function. */
59 MDOLinExpr obj = new MDOLinExpr();
60 model.SetObjective(obj, MDO.MAXIMIZE);
Step III: Solve SDP model
Solve the optimization problem via MDOModel.Optimize
.
62 // Solve the problem and populate optimization result.
63 model.Optimize();
Step IV: Obtain the solution of SDP problem
We use the generic function MDOModel.Get
to retrieve the optimal objective function value, i.e., the ObjVal attribute.
65 if (model.Get(MDO.IntAttr.Status) == MDO.Status.OPTIMAL)
66 {
67 Console.WriteLine($"Optimal objective value is: {model.Get(MDO.DoubleAttr.ObjVal)}");
68 }
69 else
70 {
71 Console.WriteLine("No feasible solution.");
72 }
The complete example code is provided in mdo_sdo_ex1.cs :
1/**
2 * Description
3 * -----------
4 *
5 * Semidefinite optimization (row-wise input).
6 *
7 * Formulation
8 * -----------
9 *
10 * Maximize
11 * obj: tr(C X)
12 *
13 * Subject To
14 * c0 : tr(A X) = 1
15 * X is p.s.d.
16 *
17 * Matrix
18 * C = [ -3 0 1 ] A = [ 3 0 1 ]
19 * [ 0 -2 0 ] [ 0 4 0 ]
20 * [ 1 0 -3 ] [ 1 0 5 ]
21 * End
22 */
23
24using Mindopt;
25
26namespace Example
27{
28 public class MdoSdoEx1
29 {
30 public static void Main(string[] args)
31 {
32 /* Model data. */
33 int num_mats = 1;
34 int dim_mat = 3; /* Dimension of the matrix variables. */
35
36 int C_nnz = 4;
37 int[] C_nz_indices = new int[] { 0, 2, 4, 8 }; /* Nonzero vectorized index of obj coeff. */
38 double[] C_nz_values = new double[] { -3.0, 1.0, -2.0, -3.0 }; /* Nonzero values of obj coeff. */
39
40 int A_nnz = 4;
41 int[] A_nz_indices = new int[] { 0, 2, 4, 8 }; /* Nonzero vectorized index of constr coeff. */
42 double[] A_nz_values = new double[] { 3.0, 1.0, 4.0, 5.0 }; /* Nonzero values of constr coeff. */
43
44 // Create model
45 MDOEnv env = new MDOEnv();
46 MDOModel model = new MDOModel(env);
47 model.Set(MDO.StringAttr.ModelName, "SDP_01");
48
49 try
50 {
51 // Add variables.
52 MDOPsdVar psd_var = model.AddPsdVar(MDOMatrix.Coo(dim_mat, dim_mat, C_nz_indices, C_nz_values), "X0");
53
54 /* Add constraints. */
55 MDOPsdExpr psd_expr = new MDOPsdExpr(psd_var, MDOMatrix.Coo(dim_mat, dim_mat, A_nz_indices, A_nz_values));
56 model.AddPsdConstr(psd_expr, MDO.EQUAL, 1.0, "C0");
57
58 /* Set objective function. */
59 MDOLinExpr obj = new MDOLinExpr();
60 model.SetObjective(obj, MDO.MAXIMIZE);
61
62 // Solve the problem and populate optimization result.
63 model.Optimize();
64
65 if (model.Get(MDO.IntAttr.Status) == MDO.Status.OPTIMAL)
66 {
67 Console.WriteLine($"Optimal objective value is: {model.Get(MDO.DoubleAttr.ObjVal)}");
68 }
69 else
70 {
71 Console.WriteLine("No feasible solution.");
72 }
73 }
74 catch (Exception e)
75 {
76 Console.WriteLine("Exception during optimization");
77 Console.WriteLine(e.Message);
78 }
79 finally
80 {
81 model.Dispose();
82 env.Dispose();
83 }
84 }
85 }
86}
5.7.6.2. SDP Example II¶
Step I: Create an optimization model
Create an empty optimization model:
61 // Create model
62 MDOEnv env = new MDOEnv();
63 MDOModel model = new MDOModel(env);
64 model.Set(MDO.StringAttr.ModelName, "SDP_02");
Step II: SDP model input
We use MDOModel.AddPsdVar
to create two new semidefinite matrix variables (in this case, \(\mathbf{X}_0, \mathbf{X}_1\)) and simultaneously set their corresponding coefficient matrices (in this case, \(\mathbf{C}_0, \mathbf{C}_1\)) in the objective function.
69 MDOPsdVar psd_var0 = model.AddPsdVar(MDOMatrix.Coo(dim_mat[0], dim_mat[0], C0_nz_indices, C0_nz_values), "X0");
70 MDOPsdVar psd_var1 = model.AddPsdVar(MDOMatrix.Coo(dim_mat[1], dim_mat[1], C1_nz_indices, C1_nz_values), "X1");
We then use MDOModel.AddVar
to create two linear variables representing \(x_0,x_1\) in this example.
The first and second arguments are the lower and upper bounds of the variables.
The third argument is the coefficient of the variable in the objective function.
The fourth argument is the type of the variable, which is continuous variable type (‘C’) in this case. The last argument is the name of the variable.
71 MDOVar var0 = model.AddVar(0.0, MDO.INFINITY, 0.0, 'C', "x0");
72 MDOVar var1 = model.AddVar(0.0, MDO.INFINITY, 0.0, 'C', "x1");
Next, we create constraints. We use MDOModel.AddPsdConstr
to establish constraints with semidefinite matrix variables.
The first argument is the semidefinite expression in the constraint. Since the constraint in this example contains both semidefinite variables and linear variables, we construct the semidefinite expression in two steps.
Firstly, we create the semidefinite term using the initialization method
MDOPsdExpr.MDOPsdExpr
.Then, we add the remaining linear term using the
MDOPsdExpr.AddTerms
method to obtain the final semidefinite expression for the constraint.The second argument is the type of the constraint, where MDO.EQUAL (‘=’) represents an equality constraint.
The third argument is the right-hand side value of the constraint (in this case, 1.0).
The last argument is the name of the constraint.
74 /* Add constraints. */
75 MDOPsdExpr psd_expr0 = new MDOPsdExpr(psd_var0, MDOMatrix.Coo(dim_mat[0], dim_mat[0], A0_nz_indices, A0_nz_values));
76 MDOVar[] row0_vars = new MDOVar[] { var0 };
77 psd_expr0.AddTerms(row0_values, row0_vars);
78 model.AddPsdConstr(psd_expr0, MDO.EQUAL, 1.0, "C0");
79
80 MDOPsdExpr psd_expr1 = new MDOPsdExpr(psd_var1, MDOMatrix.Coo(dim_mat[1], dim_mat[1], A1_nz_indices, A1_nz_values));
81 MDOVar[] row1_vars = new MDOVar[] { var1 };
82 psd_expr1.AddTerms(row1_values, row1_vars);
83 model.AddPsdConstr(psd_expr1, MDO.EQUAL, 2.0, "C1");
Finally, we use MDOModel.SetObjective
to set the rest of the objective function (in this case, 0), and change the optimization direction to maximization (-1).
85 /* Set objective function. */
86 MDOLinExpr obj = new MDOLinExpr();
87 model.SetObjective(obj, MDO.MAXIMIZE);
Step III: Solve SDP model
Solve the optimization problem via MDOModel.Optimize
.
89 // Solve the problem and populate optimization result.
90 model.Optimize();
Step IV: Obtain the solution of SDP problem
We use the generic function MDOModel.Get
to retrieve the optimal objective function value, i.e., the ObjVal attribute.
92 if (model.Get(MDO.IntAttr.Status) == MDO.Status.OPTIMAL)
93 {
94 Console.WriteLine($"Optimal objective value is: {model.Get(MDO.DoubleAttr.ObjVal)}");
95 }
96 else
97 {
98 Console.WriteLine("No feasible solution.");
99 }
The complete example code is provided in mdo_sdo_ex2.cs :
1/**
2 * Description
3 * -----------
4 *
5 * Semidefinite optimization (row-wise input).
6 *
7 * Formulation
8 * -----------
9 *
10 * Maximize
11 * obj:
12 * tr(C0 X0) + tr(C1 X1) + 0 x0 + 0 x1
13 * Subject To
14 * c0 : tr(A00 X0) + 1 x0 = 1
15 * c1 : tr(A11 X1) + 1 x1 = 2
16 * Bounds
17 * 0 <= x0
18 * 0 <= x1
19 * X0,X1 are p.s.d.
20 *
21 * Matrix
22 * C0 = [ 2 1 ] A00 = [ 3 1 ]
23 * [ 1 2 ] [ 1 3 ]
24 *
25 * C1 = [ 3 0 1 ] A11 = [ 3 0 1 ]
26 * [ 0 2 0 ] [ 0 4 0 ]
27 * [ 1 0 3 ] [ 1 0 5 ]
28 * End
29 */
30using Mindopt;
31
32namespace Example
33{
34 public class MdoSdoEx2
35 {
36 public static void Main(string[] args)
37 {
38 /* Model data. */
39 int num_mats = 1;
40 int[] dim_mat = new int[] { 2, 3 }; /* Dimension of the matrix variables. */
41
42 int C0_nnz = 3;
43 int[] C0_nz_indices = new int[] { 0, 1, 3 }; /* Nonzero vectorized index of obj coeff. */
44 double[] C0_nz_values = new double[] { 2.0, 1.0, 2.0 }; /* Nonzero values of obj coeff. */
45
46 int C1_nnz = 4;
47 int[] C1_nz_indices = new int[] { 0, 2, 4, 8 }; /* Nonzero vectorized index of obj coeff. */
48 double[] C1_nz_values = new double[] { 3.0, 1.0, 2.0, 3.0 }; /* Nonzero values of obj coeff. */
49
50 int A0_nnz = 3;
51 int[] A0_nz_indices = new int[] { 0, 1, 3 }; /* Nonzero vectorized index of constr coeff. */
52 double[] A0_nz_values = new double[] { 3.0, 1.0, 3.0 }; /* Nonzero values of constr coeff. */
53
54 int A1_nnz = 4;
55 int[] A1_nz_indices = new int[] { 0, 2, 4, 8 }; /* Nonzero vectorized index of constr coeff. */
56 double[] A1_nz_values = new double[] { 3.0, 1.0, 4.0, 5.0 }; /* Nonzero values of constr coeff. */
57
58 double[] row0_values = new double[] { 1.0 };
59 double[] row1_values = new double[] { 1.0 };
60
61 // Create model
62 MDOEnv env = new MDOEnv();
63 MDOModel model = new MDOModel(env);
64 model.Set(MDO.StringAttr.ModelName, "SDP_02");
65
66 try
67 {
68 // Add variables.
69 MDOPsdVar psd_var0 = model.AddPsdVar(MDOMatrix.Coo(dim_mat[0], dim_mat[0], C0_nz_indices, C0_nz_values), "X0");
70 MDOPsdVar psd_var1 = model.AddPsdVar(MDOMatrix.Coo(dim_mat[1], dim_mat[1], C1_nz_indices, C1_nz_values), "X1");
71 MDOVar var0 = model.AddVar(0.0, MDO.INFINITY, 0.0, 'C', "x0");
72 MDOVar var1 = model.AddVar(0.0, MDO.INFINITY, 0.0, 'C', "x1");
73
74 /* Add constraints. */
75 MDOPsdExpr psd_expr0 = new MDOPsdExpr(psd_var0, MDOMatrix.Coo(dim_mat[0], dim_mat[0], A0_nz_indices, A0_nz_values));
76 MDOVar[] row0_vars = new MDOVar[] { var0 };
77 psd_expr0.AddTerms(row0_values, row0_vars);
78 model.AddPsdConstr(psd_expr0, MDO.EQUAL, 1.0, "C0");
79
80 MDOPsdExpr psd_expr1 = new MDOPsdExpr(psd_var1, MDOMatrix.Coo(dim_mat[1], dim_mat[1], A1_nz_indices, A1_nz_values));
81 MDOVar[] row1_vars = new MDOVar[] { var1 };
82 psd_expr1.AddTerms(row1_values, row1_vars);
83 model.AddPsdConstr(psd_expr1, MDO.EQUAL, 2.0, "C1");
84
85 /* Set objective function. */
86 MDOLinExpr obj = new MDOLinExpr();
87 model.SetObjective(obj, MDO.MAXIMIZE);
88
89 // Solve the problem and populate optimization result.
90 model.Optimize();
91
92 if (model.Get(MDO.IntAttr.Status) == MDO.Status.OPTIMAL)
93 {
94 Console.WriteLine($"Optimal objective value is: {model.Get(MDO.DoubleAttr.ObjVal)}");
95 }
96 else
97 {
98 Console.WriteLine("No feasible solution.");
99 }
100 }
101 catch (Exception e)
102 {
103 Console.WriteLine("Exception during optimization");
104 Console.WriteLine(e.Message);
105 }
106 finally
107 {
108 model.Dispose();
109 env.Dispose();
110 }
111 }
112 }
113}