1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
//!
//! Copyright : Copyright (c) MOSEK ApS, Denmark. All rights reserved.
//!
//! File : sdo_lmi.rs
//!
//! Purpose : To solve a problem with an LMI and an affine conic constrained problem with a PSD term
//!
//! minimize Tr [1, 0; 0, 1]*X + x(1) + x(2) + 1
//!
//! subject to Tr [0, 1; 1, 0]*X - x(1) - x(2) >= 0
//! x(1) [0, 1; 1, 3] + x(2) [3, 1; 1, 0] - [1, 0; 0, 1] >> 0
//! X >> 0
//!
extern crate mosek;
use mosek::{Task,Boundkey,Objsense,Streamtype,Solsta,Soltype};
const INF : f64 = 0.0;
fn main() -> Result<(),String> {
let numafe : i64 = 4; /* Number of affine expressions. */
let numvar : i32 = 2; /* Number of scalar variables */
let dimbarvar = &[2]; /* Dimension of semidefinite cone */
let lenbarvar = &[2 * (2 + 1) / 2]; /* Number of scalar SD variables */
let barc_j = &[0, 0];
let barc_k = &[0, 1];
let barc_l = &[0, 1];
let barc_v = &[1.0, 1.0];
let afeidx = &[0, 0, 1, 2, 2, 3];
let varidx = &[0, 1, 1, 0, 1, 0];
let f_val = &[-1.0, -1.0, 3.0, 2.0f64.sqrt(), 2.0f64.sqrt(), 3.0];
let g = &[0.0, -1.0, 0.0, -1.0];
let barf_i = &[0, 0];
let barf_j = &[0, 0];
let barf_k = &[0, 1];
let barf_l = &[0, 0];
let barf_v = &[0.0, 1.0];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'NUMAFE' empty affine expressions. */
task.append_afes(numafe)?;
/* Append 'NUMVAR' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Append 'NUMBARVAR' semidefinite variables. */
task.append_barvars(dimbarvar)?;
task.put_obj_sense(Objsense::MINIMIZE)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(1.0)?;
/* Set the linear term c_j in the objective.*/
task.put_c_j(0, 1.0)?;
task.put_c_j(1, 1.0)?;
task.put_var_bound_slice_const(0,numvar, Boundkey::FR, -INF,INF)?;
/* Set the linear term barc_j in the objective.*/
task.put_barc_block_triplet(barc_j, barc_k, barc_l, barc_v)?;
/* Set up the affine conic constraints */
/* Construct the affine expressions */
/* F matrix */
task.put_afe_f_entry_list(afeidx, varidx, f_val)?;
/* g vector */
task.put_afe_g_slice(0, 4, g)?;
/* barF block triplets */
task.put_afe_barf_block_triplet(barf_i, barf_j, barf_k, barf_l, barf_v)?;
/* Append R+ domain and the corresponding ACC */
{
let dom = task.append_rplus_domain(1)?;
task.append_acc(dom, &[0], &[0.0])?;
}
/* Append SVEC_PSD domain and the corresponding ACC */
{
let dom = task.append_svec_psd_cone_domain(3)?;
task.append_acc(dom, &[1,2,3], &[0.0,0.0,0.0])?;
}
/* Run optimizer */
let _ = task.optimize()?;
/* Print a summary containing information
about the solution for debugging purposes*/
task.solution_summary (mosek::Streamtype::MSG)?;
let solsta = task.get_sol_sta(mosek::Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
let mut barx = vec![0.0; lenbarvar[0]];
task.get_barx_j(Soltype::ITR, 0, barx.as_mut_slice())?; /* Request the interior solution. */
println!("Optimal primal solution");
println!(" x = {:?}",xx);
println!(" barx = {:?}",barx);
},
Solsta::DUAL_INFEAS_CER|Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility certificate found."),
Solsta::UNKNOWN =>
println!("The status of the solution could not be determined."),
_ =>
println!("Other solution status.")
}
Ok(())
}
#[cfg(test)]
mod tests {
#[test]
fn test() {
super::main().unwrap();
}
}