5.7.4. SDP Modeling and Optimization in JAVA

In this chapter, we will use MindOpt JAVA API to model and solve the problem in Examples of semidefinite programming.

5.7.4.1. SDP Example I

Include the header file:

23import com.alibaba.damo.mindopt.*;

Step I: Create an optimization model

Create an empty optimization model:

40        // Create model
41        MDOEnv env = new MDOEnv(); 
42        MDOModel model = new MDOModel(env); 
43        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 the MDOMatrix.coo method. Note that the dimensions of the coefficient matrix should match the matrix variables.

  • The second argument is the name of the variable.

46            // Add variables.
47            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.

49            /* Add constraints. */
50            MDOPsdExpr psd_expr = new MDOPsdExpr(psd_var, MDOMatrix.coo(dim_mat, dim_mat, A_nz_indices, A_nz_values));
51            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).

53            /* Set objective function. */
54            MDOLinExpr objective = new MDOLinExpr();
55            model.setObjective(objective, MDO.MAXIMIZE); 

Step III: Solve SDP model

Solve the optimization problem via MDOModel.optimize.

57            // Step 3. Solve the problem and populate optimization result.
58            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.

60            if (model.get(MDO.IntAttr.Status) == MDO.OPTIMAL) {
61                System.out.println("Optimal objective value is: " + model.get(MDO.DoubleAttr.ObjVal));
62            }
63            else {
64                System.out.println("No feasible solution.");
65            }

The complete example code is provided in MdoSdoEx1.java :

 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 */
23import com.alibaba.damo.mindopt.*;
24import java.util.*;
25
26public class MdoSdoEx1 { 
27    public static void main(String[] args) throws MDOException {
28        /* Model data. */
29        int    num_mats = 1;
30        int    dim_mat = 3;                                 /* Dimension of the matrix variables. */
31
32        int      C_nnz = 4;
33        int[]    C_nz_indices = new int[]    {  0,   2,    4,    8    }; /* Nonzero vectorized index of obj coeff. */
34        double[] C_nz_values  = new double[] { -3.0, 1.0,  -2.0, -3.0 }; /* Nonzero values of obj coeff. */
35
36        int      A_nnz = 4;
37        int[]    A_nz_indices = new int[]    { 0,    2,    4,    8    }; /* Nonzero vectorized index of constr coeff. */
38        double[] A_nz_values  = new double[] { 3.0,  1.0,  4.0,  5.0  }; /* Nonzero values of constr coeff. */
39
40        // Create model
41        MDOEnv env = new MDOEnv(); 
42        MDOModel model = new MDOModel(env); 
43        model.set(MDO.StringAttr.ModelName, "SDP_01");
44
45        try {
46            // Add variables.
47            MDOPsdVar psd_var = model.addPsdVar(MDOMatrix.coo(dim_mat, dim_mat, C_nz_indices, C_nz_values), "X0");
48        
49            /* Add constraints. */
50            MDOPsdExpr psd_expr = new MDOPsdExpr(psd_var, MDOMatrix.coo(dim_mat, dim_mat, A_nz_indices, A_nz_values));
51            model.addPsdConstr(psd_expr, MDO.EQUAL, 1.0, "C0");
52
53            /* Set objective function. */
54            MDOLinExpr objective = new MDOLinExpr();
55            model.setObjective(objective, MDO.MAXIMIZE); 
56
57            // Step 3. Solve the problem and populate optimization result.
58            model.optimize();
59
60            if (model.get(MDO.IntAttr.Status) == MDO.OPTIMAL) {
61                System.out.println("Optimal objective value is: " + model.get(MDO.DoubleAttr.ObjVal));
62            }
63            else {
64                System.out.println("No feasible solution.");
65            }
66        } catch (Exception e) { 
67            System.out.println("Exception during optimization");
68            e.printStackTrace();
69        } finally { 
70            model.dispose();
71            env.dispose();
72        }
73    }
74}

5.7.4.2. SDP Example II

Include the header file:

30import com.alibaba.damo.mindopt.*;

Step I: Create an optimization model

Create an empty optimization model:

58        // Create model
59        MDOEnv env = new MDOEnv(); 
60        MDOModel model = new MDOModel(env); 
61        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.

65            MDOPsdVar psd_var0 = model.addPsdVar(MDOMatrix.coo(dim_mat[0], dim_mat[0], C0_nz_indices, C0_nz_values), "X0");
66            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.

67            MDOVar    var0     = model.addVar(0.0, MDO.INFINITY, 0.0, 'C', "x0");
68            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.

70            /* Add constraints. */
71            MDOPsdExpr psd_expr0 = new MDOPsdExpr(psd_var0, MDOMatrix.coo(dim_mat[0], dim_mat[0], A0_nz_indices, A0_nz_values));
72            MDOVar[] row0_vars = new MDOVar[] { var0 };
73            psd_expr0.addTerms(row0_values, row0_vars);
74            model.addPsdConstr(psd_expr0, MDO.EQUAL, 1.0, "C0");
75
76            MDOPsdExpr psd_expr1 = new MDOPsdExpr(psd_var1, MDOMatrix.coo(dim_mat[1], dim_mat[1], A1_nz_indices, A1_nz_values));
77            MDOVar[] row1_vars = new MDOVar[] { var1 };
78            psd_expr1.addTerms(row1_values, row1_vars);        
79            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).

81            /* Set objective function. */
82            MDOLinExpr objective = new MDOLinExpr();
83            model.setObjective(objective, MDO.MAXIMIZE); 

Step III: Solve SDP model

Solve the optimization problem via MDOModel.optimize.

85            // Step 3. Solve the problem and populate optimization result.
86            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.

88            if (model.get(MDO.IntAttr.Status) == MDO.OPTIMAL) {
89                System.out.println("Optimal objective value is: " + model.get(MDO.DoubleAttr.ObjVal));
90            }
91            else {
92                System.out.println("No feasible solution.");
93            }

The complete example code is provided in MdoSdoEx2.java :

  1/**
  2 *  Description
  3 *  -----------
  4 *
  5 *  Semidefinite optimization (row-wise input).
  6 *
  7 *  Formulation
  8 *  -----------
  9 *
 10 *  Maximize
 11 *  obj: tr(C0 X0)   + tr(C0 X1)    + 0 x0 + 0 x1
 12 *
 13 *  Subject To
 14 *   c0 : tr(A00 X0)                + 1 x0        = 1
 15 *   c1 :              tr(A00 X1)          + 1 x1 = 2
 16 *  Bounds
 17 *    0 <= x0
 18 *    0 <= x1
 19 *    X1, X2 are p.s.d.
 20 *
 21 *  Matrix
 22 *    C0 =  [ 2 1 ]   A00 = [ 3 1 ]
 23 *          [ 1 2 ]         [ 1 3 ]
 24 *
 25 *    C0 = [ 3 0 1 ]  A00 = [ 3 0 1 ]
 26 *         [ 0 2 0 ]        [ 0 4 0 ]
 27 *         [ 1 0 3 ]        [ 1 0 5 ]
 28 *  End
 29 */
 30import com.alibaba.damo.mindopt.*;
 31import java.util.*;
 32
 33public class MdoSdoEx2 { 
 34    public static void main(String[] args) throws MDOException {
 35        /* Model data. */
 36        int    num_mats = 1;
 37        int[]  dim_mat  = new int[] { 2, 3 };                 /* Dimension of the matrix variables. */
 38
 39        int      C0_nnz = 3;
 40        int[]    C0_nz_indices = new int[]    {  0,   1,   3   };  /* Nonzero vectorized index of obj coeff. */
 41        double[] C0_nz_values  = new double[] {  2.0, 1.0, 2.0 };  /* Nonzero values of obj coeff. */
 42        
 43        int      C1_nnz = 4;
 44        int[]    C1_nz_indices = new int[]    {  0,   2,   4,    8   };   /* Nonzero vectorized index of obj coeff. */
 45        double[] C1_nz_values  = new double[] {  3.0, 1.0, 2.0,  3.0 };   /* Nonzero values of obj coeff. */
 46
 47        int      A0_nnz = 3;
 48        int[]    A0_nz_indices = new int[]    {  0,   1,   3   };    /* Nonzero vectorized index of constr coeff. */
 49        double[] A0_nz_values  = new double[] {  3.0, 1.0, 3.0 };    /* Nonzero values of constr coeff. */
 50
 51        int      A1_nnz = 4;
 52        int[]    A1_nz_indices = new int[]    {  0,   2,   4,    8    };  /* Nonzero vectorized index of constr coeff. */
 53        double[] A1_nz_values  = new double[] {  3.0, 1.0, 4.0,  5.0  };  /* Nonzero values of constr coeff. */
 54        
 55        double[] row0_values = new double[] {  1.0 };
 56        double[] row1_values = new double[] {  1.0 };
 57
 58        // Create model
 59        MDOEnv env = new MDOEnv(); 
 60        MDOModel model = new MDOModel(env); 
 61        model.set(MDO.StringAttr.ModelName, "SDP_02");
 62
 63        try {
 64            // Add variables.
 65            MDOPsdVar psd_var0 = model.addPsdVar(MDOMatrix.coo(dim_mat[0], dim_mat[0], C0_nz_indices, C0_nz_values), "X0");
 66            MDOPsdVar psd_var1 = model.addPsdVar(MDOMatrix.coo(dim_mat[1], dim_mat[1], C1_nz_indices, C1_nz_values), "X1");
 67            MDOVar    var0     = model.addVar(0.0, MDO.INFINITY, 0.0, 'C', "x0");
 68            MDOVar    var1     = model.addVar(0.0, MDO.INFINITY, 0.0, 'C', "x1"); 
 69            
 70            /* Add constraints. */
 71            MDOPsdExpr psd_expr0 = new MDOPsdExpr(psd_var0, MDOMatrix.coo(dim_mat[0], dim_mat[0], A0_nz_indices, A0_nz_values));
 72            MDOVar[] row0_vars = new MDOVar[] { var0 };
 73            psd_expr0.addTerms(row0_values, row0_vars);
 74            model.addPsdConstr(psd_expr0, MDO.EQUAL, 1.0, "C0");
 75
 76            MDOPsdExpr psd_expr1 = new MDOPsdExpr(psd_var1, MDOMatrix.coo(dim_mat[1], dim_mat[1], A1_nz_indices, A1_nz_values));
 77            MDOVar[] row1_vars = new MDOVar[] { var1 };
 78            psd_expr1.addTerms(row1_values, row1_vars);        
 79            model.addPsdConstr(psd_expr1, MDO.EQUAL, 2.0, "C1");
 80             
 81            /* Set objective function. */
 82            MDOLinExpr objective = new MDOLinExpr();
 83            model.setObjective(objective, MDO.MAXIMIZE); 
 84
 85            // Step 3. Solve the problem and populate optimization result.
 86            model.optimize();
 87            
 88            if (model.get(MDO.IntAttr.Status) == MDO.OPTIMAL) {
 89                System.out.println("Optimal objective value is: " + model.get(MDO.DoubleAttr.ObjVal));
 90            }
 91            else {
 92                System.out.println("No feasible solution.");
 93            }
 94        } catch (Exception e) { 
 95            System.out.println("Exception during optimization");
 96            e.printStackTrace();
 97        } finally { 
 98            model.dispose();
 99            env.dispose();
100        }
101    }
102}