pub struct TaskCB { /* private fields */ }
Implementations§
source§impl TaskCB
impl TaskCB
sourcepub fn without_callbacks(self) -> Task
pub fn without_callbacks(self) -> Task
Convert a TaskCB
object into a Task
object.
sourcepub fn clone(&self) -> Option<Task>
pub fn clone(&self) -> Option<Task>
Clone a TaskCB
. Since callbacks are not shaerd between
cloned objects, this returns a plain Task
object.
sourcepub fn put_stream_callback<F>(
&mut self,
whichstream: i32,
func: F
) -> Result<(), String>
pub fn put_stream_callback<F>( &mut self, whichstream: i32, func: F ) -> Result<(), String>
Set a stream callback handler.
§Arguments
whichstream
defines which stream attach it to, use constantsMSK_STREAM_...
.func
is a function that receives a message to be printed.
Examples found in repository?
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
fn opt_server_sync(inputfile : FileOrText, addr : String, cert : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Load some data into the task
match inputfile {
FileOrText::File(filename) => task.read_data(filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Set OptServer URL
task.put_optserver_host(addr.as_str())?;
// Path to certificate, if any
if let Some(cert) = cert {
task.put_str_param(Sparam::REMOTE_TLS_CERT_PATH, cert.as_str())?;
}
// Optimize remotely, no access token
let _trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
Ok(())
}
More examples
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
fn feasrepairex1(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
match filename {
FileOrText::File(fname) => task.read_data(fname.as_str())?,
FileOrText::Text(data) => task.read_lp_string(data.as_str())?
}
task.put_int_param(mosek::Iparam::LOG_FEAS_REPAIR, 3)?;
let wc = vec![1.0; task.get_num_con()? as usize];
let wx = vec![1.0; task.get_num_var()? as usize];
task.primal_repair(wc.as_slice(),wc.as_slice(),wx.as_slice(),wx.as_slice())?;
let sum_viol = task.get_dou_inf(mosek::Dinfitem::PRIMAL_REPAIR_PENALTY_OBJ)?;
println!("Minimized sum of violations = {}", sum_viol);
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::MSG)?;
Ok(())
}
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
fn simple(filename : FileOrText, outfile : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(fname) => {
task.read_data(fname.as_str())?
},
FileOrText::Text(data) => {
task.read_ptf_string(data.as_str())?
}
}
// Solve the problem
let _ = task.optimize()?;
// Print a summary of the solution
task.solution_summary(Streamtype::LOG)?;
// If an output file was specified, save problem to file
if let Some(outfile) = outfile {
// If using OPF format, these parameters will specify what to include in output
task.put_int_param(Iparam::OPF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_PROBLEM, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_HINTS, Onoffkey::OFF)?;
task.put_int_param(Iparam::OPF_WRITE_PARAMETERS, Onoffkey::OFF)?;
task.put_int_param(Iparam::PTF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.write_data(outfile.as_str())?;
}
Ok(())
}
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 2;
let numvar : i32 = 2;
let aval = &[ -1.0 ,
1.0, 1.0 ];
let asub = &[ 1,
0, 1 ];
let ptrb = &[0, 1];
let ptre = &[1, 3];
// int[] bsub = new int[numvar];
// double[] b = new double[numvar];
// int[] basis = new int[numvar];
let mut task = Task::new().unwrap();
// Put A matrix and factor A. Call this function only once for a
// given task.
let basis = setup(& mut task,
aval,
asub,
ptrb,
ptre,
numvar)?;
let mut task = task.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* now solve rhs */
let mut b = vec![0.0; numvar as usize];
let mut bsub = vec![0; numvar as usize];
b[0] = 1.0; b[1] = -2.0;
bsub[0] = 0; bsub[1] = 1;
let nz = task.solve_with_basis(false, 2, bsub.as_mut_slice(), b.as_mut_slice())?;
println!("\nSolution to Bx = b:\n");
// Print solution and show correspondents to original variables in
// the problem
for &bsubi in bsub[..nz as usize].iter() {
if basis[bsubi as usize] < numcon {
println!("This should never happen");
}
else {
println!("x{} = {}",basis[bsubi as usize] - numcon, b[bsubi as usize]);
}
}
b[0] = 7.0;
bsub[0] = 0;
let nz = task.solve_with_basis(false, 1, bsub.as_mut_slice(), b.as_mut_slice())?;
println!("Solution to Bx = b:");
// Print solution and show correspondents to original variables in
// the problem
for &bsubi in bsub[..nz as usize].iter() {
if basis[bsubi as usize] < numcon {
println!("This should never happen");
}
else {
println!("x{} = {}",basis[bsubi as usize] - numcon,b[bsubi as usize]);
}
}
Ok(())
}
- examples/mico1.rs
- examples/mioinitsol.rs
- examples/acc1.rs
- examples/acc2.rs
- examples/pow1.rs
- examples/gp1.rs
- examples/portfolio_1_basic.rs
- examples/solvebasis.rs
- examples/djc1.rs
- examples/sdo_lmi.rs
- examples/lo2.rs
- examples/sdo2.rs
- examples/qo1.rs
- examples/qcqo1.rs
- examples/solutionquality.rs
- examples/portfolio_6_factor.rs
- examples/lo1.rs
- examples/cqo1.rs
- examples/sensitivity.rs
- examples/portfolio_4_transcost.rs
- examples/portfolio_3_impact.rs
- examples/sdo1.rs
sourcepub fn clear_stream_callback(&mut self, whichstream: i32) -> Result<(), String>
pub fn clear_stream_callback(&mut self, whichstream: i32) -> Result<(), String>
Clear stream callback handler at a given stream.
pub fn clear_callback(&mut self) -> Result<(), String>
sourcepub fn put_callback<F>(&mut self, func: F) -> Result<(), String>
pub fn put_callback<F>(&mut self, func: F) -> Result<(), String>
Sets an information callback handler in the task
§Arguments:
func
A function (caller,dinf,iinf,liinf) -> bool, that returns false to indicate that the solver should terminate as soon as possible, otherwise returns true.caller
indicates what the solver is currently doing (seeMSK_CALLBACK_...
constants)dinf
is a list of f64 information items (indexed withMSK_DINF_...
)iinf
is a list of i32 information items (indexed withMSK_IINF_...
)liinf
is a list of i64 information items (indexed withMSK_LIINF_...
)
pub fn put_codecallback<F>(&mut self, func: F) -> Result<(), String>
pub fn put_intsolcallback<F>(&mut self, func: F) -> Result<(), String>
sourcepub fn analyze_names(
&self,
whichstream_: i32,
nametype_: i32
) -> Result<(), String>
pub fn analyze_names( &self, whichstream_: i32, nametype_: i32 ) -> Result<(), String>
Analyze the names and issue an error for the first invalid name.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
-
nametype_
The type of names e.g. valid in MPS or LP files.See Nametype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.analyzenames
sourcepub fn analyze_problem(&self, whichstream_: i32) -> Result<(), String>
pub fn analyze_problem(&self, whichstream_: i32) -> Result<(), String>
Analyze the data of a task.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.analyzeproblem
sourcepub fn analyze_solution(
&self,
whichstream_: i32,
whichsol_: i32
) -> Result<(), String>
pub fn analyze_solution( &self, whichstream_: i32, whichsol_: i32 ) -> Result<(), String>
Print information related to the quality of the solution.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
-
whichsol_
Selects a solution.See Soltype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.analyzesolution
Examples found in repository?
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
fn solutionquality(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(filename) => task.read_data (filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Solve the problem
let _ = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut pobj : f64 = 0.0;
let mut pviolcon : f64 = 0.0;
let mut pviolvar : f64 = 0.0;
let mut pviolbarvar : f64 = 0.0;
let mut pviolcones : f64 = 0.0;
let mut pviolitg : f64 = 0.0;
let mut dobj : f64 = 0.0;
let mut dviolcon : f64 = 0.0;
let mut dviolvar : f64 = 0.0;
let mut dviolbarvar : f64 = 0.0;
let mut dviolcones : f64 = 0.0;
task.get_solution_info(Soltype::BAS,
& mut pobj, & mut pviolcon, & mut pviolvar, & mut pviolbarvar, & mut pviolcones, & mut pviolitg,
& mut dobj, & mut dviolcon, & mut dviolvar, & mut dviolbarvar, & mut dviolcones)?;
match solsta {
Solsta::OPTIMAL => {
let abs_obj_gap = (dobj-pobj).abs();
let rel_obj_gap = abs_obj_gap / (1.0 + f64::min(pobj.abs(), dobj.abs()));
let max_primal_viol = f64::max(pviolcon, pviolvar);
let max_primal_viol = f64::max(max_primal_viol , pviolbarvar);
let max_primal_viol = f64::max(max_primal_viol , pviolcones);
let max_dual_viol = f64::max(dviolcon, dviolvar);
let max_dual_viol = f64::max(max_dual_viol, dviolbarvar);
let max_dual_viol = f64::max(max_dual_viol, dviolcones);
// Assume the application needs the solution to be within
// 1e-6 ofoptimality in an absolute sense. Another approach
// would be looking at the relative objective gap
println!("Customized solution information.");
println!(" Absolute objective gap: {:.3e}", abs_obj_gap);
println!(" Relative objective gap: {:.3e}", rel_obj_gap);
println!(" Max primal violation : {:.3e}", max_primal_viol);
println!(" Max dual violation : {:.3e}", max_dual_viol);
let mut accepted = true;
if rel_obj_gap > 1e-6 {
println!("Warning: The relative objective gap is LARGE.");
accepted = false;
}
// We will accept a primal infeasibility of 1e-8 and
// dual infeasibility of 1e-6. These number should chosen problem
// dependent.
if max_primal_viol > 1e-8 {
println!("Warning: Primal violation is too LARGE");
accepted = false;
}
if max_dual_viol > 1e-6 {
println!("Warning: Dual violation is too LARGE.");
accepted = false;
}
if accepted {
let numvar = task.get_num_var()?;
println!("Optimal primal solution");
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS,xx.as_mut_slice())?;
for (j,&xj) in (0..numvar).zip(xx.iter()) {
println!("x[{}]: {}",j,xj);
}
} else {
// print etailed information about the solution
task.analyze_solution(Streamtype::LOG, Soltype::BAS)?;
}
},
Solsta::DUAL_INFEAS_CER => println!("Primal or dual infeasibility certificate found."),
Solsta::UNKNOWN => println!("The status of the solution is unknown."),
_ => println!("Other solution status"),
}
Ok(())
}
sourcepub fn append_acc(
&mut self,
domidx_: i64,
afeidxlist_: &[i64],
b_: &[f64]
) -> Result<(), String>
pub fn append_acc( &mut self, domidx_: i64, afeidxlist_: &[i64], b_: &[f64] ) -> Result<(), String>
Appends an affine conic constraint to the task.
§Arguments
domidx_
Domain index.afeidxlist_
List of affine expression indexes.b_
The vector of constant terms modifying affine expressions. Optional.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendacc
Examples found in repository?
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
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(())
}
sourcepub fn append_accs(
&mut self,
domidxs_: &[i64],
afeidxlist_: &[i64],
b_: &[f64]
) -> Result<(), String>
pub fn append_accs( &mut self, domidxs_: &[i64], afeidxlist_: &[i64], b_: &[f64] ) -> Result<(), String>
Appends a number of affine conic constraint to the task.
§Arguments
domidxs_
Domain indices.afeidxlist_
List of affine expression indexes.b_
The vector of constant terms modifying affine expressions. Optional.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendaccs
sourcepub fn append_acc_seq(
&mut self,
domidx_: i64,
afeidxfirst_: i64,
b_: &[f64]
) -> Result<(), String>
pub fn append_acc_seq( &mut self, domidx_: i64, afeidxfirst_: i64, b_: &[f64] ) -> Result<(), String>
Appends an affine conic constraint to the task.
§Arguments
domidx_
Domain index.afeidxfirst_
Index of the first affine expression.b_
The vector of constant terms modifying affine expressions. Optional.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendaccseq
Examples found in repository?
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
More examples
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
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
fn portfolio(w : f64,
mu : &[f64],
x0 : &[f64],
gammas : &[f64],
theta : &[f64],
GT : &Matrix) -> Result<Vec<(f64,f64)>,String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
let (kx,nx) = GT.size();
if mu.len() != nx { panic!("Mismatching data"); }
let k : i32 = kx.try_into().unwrap();
let n : i32 = nx.try_into().unwrap();
let total_budget : f64 = w + x0.iter().sum::<f64>();
//Offset of variables into the API variable.
let numvar = n;
let voff_x : i32 = 0;
// Constraint offset
let coff_bud : i32 = 0;
// Holding variable x of length n
// No other auxiliary variables are needed in this formulation
task.append_vars(numvar)?;
// Setting up variable x
for j in 0..n {
task.put_var_name(voff_x+j,format!("x[{}]",j+1).as_str())?;
}
task.put_var_bound_slice_const(voff_x,voff_x+n, Boundkey::LO,0.0, INF)?;
// One linear constraint: total budget
task.append_cons(1)?;
task.put_con_name(coff_bud, "budget")?;
/* Coefficients in the first row of A */
for j in 0..n {
task.put_aij(coff_bud,voff_x + j, 1.0)?;
}
task.put_con_bound(coff_bud, Boundkey::FX, total_budget, total_budget)?;
// Input (gamma, G_factor_T x, diag(sqrt(theta))*x) in the AFE (affine expression) storage
// We need k+n+1 rows and we fill them in in three parts
task.append_afes((k+n) as i64 + 1)?;
// 1. The first affine expression = gamma, will be specified later
// 2. The next k expressions comprise G_factor_T*x, we add them row by row
// transposing the matrix G_factor on the fly
task.put_afe_f_row_list((1..1+k as i64).collect::<Vec<i64>>().as_slice(), // f row idxs
vec![n; k as usize].as_slice(), // row lengths
(0..GT.len() as i64).step_by(n as usize).collect::<Vec<i64>>().as_slice(), // row ptr
iproduct!(0..k,0..n).map(|(_,b)| b).collect::<Vec<i32>>().as_slice(), // varidx, 0..n repeated k times
GT.data_by_row().as_slice())?;
// 3. The remaining n rows contain sqrt(theta) on the diagonal
for (i,thetai) in (0..n).zip(theta.iter()) {
task.put_afe_f_entry(i as i64 + 1 + k as i64, voff_x + i, thetai.sqrt())?;
}
// Input the affine conic constraint (gamma, GT*x) \in QCone
// Add the quadratic domain of dimension k+1
let qdom = task.append_quadratic_cone_domain(k as i64+ 1)?;
// Add the constraint
task.append_acc_seq(qdom, 0, vec![0.0; k as usize+1].as_slice())?;
task.put_acc_name(0, "risk")?;
// Objective: maximize expected return mu^T x
for (j,&muj) in (0..n).zip(mu.iter()) {
task.put_c_j(voff_x + j, muj)?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
Ok(gammas.iter().filter_map(|&gamma| {
// Specify gamma in ACC
task.put_afe_g(0, gamma).ok()?;
task.optimize().ok()?;
/* Display solution summary for quick inspection of results */
let _ = task.solution_summary(Streamtype::LOG);
let _ = task.write_data(format!("portfolio_6_factor-{}.ptf",gamma).as_str());
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR).ok()? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Read the results */
let mut xx = vec![0.0; n as usize];
task.get_xx_slice(Soltype::ITR, voff_x, voff_x + n, xx.as_mut_slice()).ok()?;
Some((gamma,xx.iter().zip(mu.iter()).map(|(&xj,&muj)| xj*muj).sum::<f64>()))
}).collect::<Vec<(f64,f64)>>())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
fn main() -> Result<(),String>
{
let dimbarvar = vec![3]; /* Dimension of semidefinite cone */
let bkc = &[ mosek::Boundkey::FX, mosek::Boundkey::FX ];
let blc = &[ 1.0, 0.5 ];
let buc = &[ 1.0, 0.5 ];
let barc_i = &[0, 1, 1, 2, 2];
let barc_j = &[0, 0, 1, 1, 2];
let barc_v = &[2.0, 1.0, 2.0, 1.0, 2.0];
let aptrb = &[0, 1];
let aptre = &[1, 3];
let asub = &[0, 1, 2]; /* column subscripts of A */
let aval = &[1.0, 1.0, 1.0];
let bara_i = &[0, 1, 2, 0, 1, 2, 1, 2, 2];
let bara_j = &[0, 1, 2, 0, 0, 0, 1, 1, 2];
let bara_v = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let falpha = 1.0;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'NUMCON' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Append 'NUMBARVAR' semidefinite variables. */
task.append_barvars(&dimbarvar[..])?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
/* Set the linear term c_j in the objective.*/
task.put_c_j(0,1.0)?;
for j in 0..NUMVAR {
task.put_var_bound(j as i32,
mosek::Boundkey::FR,
-INF,
INF)?;
}
/* Set the linear term barc_j in the objective.*/
let c_symmat_idx = task.append_sparse_sym_mat(dimbarvar[0],
barc_i,
barc_j,
barc_v)?;
task.put_barc_j(0, &[c_symmat_idx], &[falpha])?;
for i in 0..NUMCON
{
/* Input A row by row */
task.put_a_row(i as i32,
& asub[aptrb[i]..aptre[i]],
& aval[aptrb[i]..aptre[i]])?;
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
}
{
/* Append the conic quadratic cone */
let afei = task.get_num_afe()?;
task.append_afes(3)?;
task.put_afe_f_entry_list(&[0,1,2],
&[0,1,2],
&[1.0,1.0,1.0])?;
let dom = task.append_quadratic_cone_domain(3)?;
task.append_acc_seq(dom,afei,&[0.0,0.0,0.0])?;
}
/* Add the first row of barA */
let a_symmat_idx1 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[..3],
& bara_j[..3],
& bara_v[..3])?;
task.put_bara_ij(0, 0, &[a_symmat_idx1][..], &[falpha][..])?;
/* Add the second row of barA */
let a_symmat_idx2 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[3..9],
& bara_j[3..9],
& bara_v[3..9])?;
task.put_bara_ij(1, 0, &[a_symmat_idx2][..], &[falpha][..])?;
let _trmcode = task.optimize()?;
task.write_data("sdo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0,0.0,0.0];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
& mut xx[..])?;
let mut barx = vec![0.0,0.0,0.0,0.0,0.0,0.0];
task.get_barx_j(Soltype::ITR, /* Request the interior solution. */
0,
& mut barx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR as usize
{
println!("x[{}]: {}",j,xx[j]);
}
let n = dimbarvar[0] as usize;
for j in 0..n
{
for i in j..n
{
println!("barx[{},{}]: {}",i,j,barx[j*n+i-j*(j+1)/2]);
}
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN =>
{
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",solsta);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn append_accs_seq(
&mut self,
domidxs_: &[i64],
numafeidx_: i64,
afeidxfirst_: i64,
b_: &[f64]
) -> Result<(), String>
pub fn append_accs_seq( &mut self, domidxs_: &[i64], numafeidx_: i64, afeidxfirst_: i64, b_: &[f64] ) -> Result<(), String>
Appends a number of affine conic constraint to the task.
§Arguments
domidxs_
Domain indices.numafeidx_
Number of affine expressions in the affine expression list (must equal the sum of dimensions of the domains).afeidxfirst_
Index of the first affine expression.b_
The vector of constant terms modifying affine expressions. Optional.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendaccsseq
sourcepub fn append_afes(&mut self, num_: i64) -> Result<(), String>
pub fn append_afes(&mut self, num_: i64) -> Result<(), String>
Appends a number of empty affine expressions to the optimization task.
§Arguments
num_
Number of empty affine expressions which should be appended.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendafes
Examples found in repository?
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
sourcepub fn append_barvars(&mut self, dim_: &[i32]) -> Result<(), String>
pub fn append_barvars(&mut self, dim_: &[i32]) -> Result<(), String>
Appends semidefinite variables to the problem.
§Arguments
dim_
Dimensions of symmetric matrix variables to be added.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendbarvars
Examples found in repository?
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
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(())
}
More examples
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
fn main() -> Result<(),String> {
/* Input data */
let numcon : i32 = 2; /* Number of constraints. */
let dimbarvar : &[i32] = &[3, 4]; /* Dimension of semidefinite variables */
/* Objective coefficients concatenated */
let Cj : &[i32] = &[ 0, 0, 1, 1, 1, 1 ]; /* Which symmetric variable (j) */
let Ck : &[i32] = &[ 0, 2, 0, 1, 1, 2 ]; /* Which entry (k,l)->v */
let Cl : &[i32] = &[ 0, 2, 0, 0, 1, 2 ];
let Cv : &[f64] = &[ 1.0, 6.0, 1.0, -3.0, 2.0, 1.0 ];
/* Equality constraints coefficients concatenated */
let Ai : &[i32] = &[ 0, 0, 0, 0, 0, 0 ]; /* Which constraint (i = 0) */
let Aj : &[i32] = &[ 0, 0, 0, 1, 1, 1 ]; /* Which symmetric variable (j) */
let Ak : &[i32] = &[ 0, 2, 2, 1, 1, 3 ]; /* Which entry (k,l)->v */
let Al : &[i32] = &[ 0, 0, 2, 0, 1, 3 ];
let Av : &[f64] = &[ 1.0, 1.0, 2.0, 1.0, -1.0, -3.0 ];
/* The second constraint - one-term inequality */
let A2i : &[i32] = &[ 1 ]; /* Which constraint (i = 1) */
let A2j : &[i32] = &[ 1 ]; /* Which symmetric variable (j = 1) */
let A2k : &[i32] = &[ 1 ]; /* Which entry A(1,0) = A(0,1) = 0.5 */
let A2l : &[i32] = &[ 0 ];
let A2v : &[f64] = &[ 0.5 ];
let bkc = &[ mosek::Boundkey::FX,
mosek::Boundkey::UP ];
let blc = &[ 23.0, 0.0 ];
let buc = &[ 23.0, -3.0 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append numcon empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append numbarvar semidefinite variables. */
task.append_barvars(dimbarvar)?;
/* Set objective (6 nonzeros).*/
task.put_barc_block_triplet(Cj, Ck, Cl, Cv)?;
/* Set the equality constraint (6 nonzeros).*/
task.put_bara_block_triplet(Ai, Aj, Ak, Al, Av)?;
/* Set the inequality constraint (1 nonzero).*/
task.put_bara_block_triplet(A2i, A2j, A2k, A2l, A2v)?;
/* Set constraint bounds */
task.put_con_bound_slice(0, 2, bkc, blc, buc)?;
/* Run optimizer */
task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
//mosek.solsta[] solsta = new mosek.solsta[1];
let solsta = task.get_sol_sta (Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
/* Retrieve the soution for all symmetric variables */
println!("Solution (lower triangular part vectorized):");
for (i,dimbarvari) in dimbarvar.iter().enumerate() {
//let dim = dimbarvar[i] * (dimbarvar[i] + 1) / 2;
let dim = dimbarvari * (dimbarvari+1)/2;
//double[] barx = new double[dim];
let mut barx : Vec<f64> = vec![0.0; dim as usize];
task.get_barx_j(Soltype::ITR, i as i32, barx.as_mut_slice())?;
println!("X{}: {:?}",i+1,barx);
// for (int j = 0; j < dim; ++j)
// System.out.print(barx[j] + " ");
// System.out.println();
}
},
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(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
fn main() -> Result<(),String>
{
let dimbarvar = vec![3]; /* Dimension of semidefinite cone */
let bkc = &[ mosek::Boundkey::FX, mosek::Boundkey::FX ];
let blc = &[ 1.0, 0.5 ];
let buc = &[ 1.0, 0.5 ];
let barc_i = &[0, 1, 1, 2, 2];
let barc_j = &[0, 0, 1, 1, 2];
let barc_v = &[2.0, 1.0, 2.0, 1.0, 2.0];
let aptrb = &[0, 1];
let aptre = &[1, 3];
let asub = &[0, 1, 2]; /* column subscripts of A */
let aval = &[1.0, 1.0, 1.0];
let bara_i = &[0, 1, 2, 0, 1, 2, 1, 2, 2];
let bara_j = &[0, 1, 2, 0, 0, 0, 1, 1, 2];
let bara_v = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let falpha = 1.0;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'NUMCON' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Append 'NUMBARVAR' semidefinite variables. */
task.append_barvars(&dimbarvar[..])?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
/* Set the linear term c_j in the objective.*/
task.put_c_j(0,1.0)?;
for j in 0..NUMVAR {
task.put_var_bound(j as i32,
mosek::Boundkey::FR,
-INF,
INF)?;
}
/* Set the linear term barc_j in the objective.*/
let c_symmat_idx = task.append_sparse_sym_mat(dimbarvar[0],
barc_i,
barc_j,
barc_v)?;
task.put_barc_j(0, &[c_symmat_idx], &[falpha])?;
for i in 0..NUMCON
{
/* Input A row by row */
task.put_a_row(i as i32,
& asub[aptrb[i]..aptre[i]],
& aval[aptrb[i]..aptre[i]])?;
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
}
{
/* Append the conic quadratic cone */
let afei = task.get_num_afe()?;
task.append_afes(3)?;
task.put_afe_f_entry_list(&[0,1,2],
&[0,1,2],
&[1.0,1.0,1.0])?;
let dom = task.append_quadratic_cone_domain(3)?;
task.append_acc_seq(dom,afei,&[0.0,0.0,0.0])?;
}
/* Add the first row of barA */
let a_symmat_idx1 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[..3],
& bara_j[..3],
& bara_v[..3])?;
task.put_bara_ij(0, 0, &[a_symmat_idx1][..], &[falpha][..])?;
/* Add the second row of barA */
let a_symmat_idx2 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[3..9],
& bara_j[3..9],
& bara_v[3..9])?;
task.put_bara_ij(1, 0, &[a_symmat_idx2][..], &[falpha][..])?;
let _trmcode = task.optimize()?;
task.write_data("sdo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0,0.0,0.0];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
& mut xx[..])?;
let mut barx = vec![0.0,0.0,0.0,0.0,0.0,0.0];
task.get_barx_j(Soltype::ITR, /* Request the interior solution. */
0,
& mut barx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR as usize
{
println!("x[{}]: {}",j,xx[j]);
}
let n = dimbarvar[0] as usize;
for j in 0..n
{
for i in j..n
{
println!("barx[{},{}]: {}",i,j,barx[j*n+i-j*(j+1)/2]);
}
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN =>
{
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",solsta);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn append_cone(
&mut self,
ct_: i32,
conepar_: f64,
submem_: &[i32]
) -> Result<(), String>
pub fn append_cone( &mut self, ct_: i32, conepar_: f64, submem_: &[i32] ) -> Result<(), String>
Appends a new conic constraint to the problem.
§Arguments
-
ct_
Specifies the type of the cone.See Conetype
-
conepar_
For the power cone it denotes the exponent alpha. For other cone types it is unused and can be set to 0. -
submem_
Variable subscripts of the members in the cone.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendcone
sourcepub fn append_cone_seq(
&mut self,
ct_: i32,
conepar_: f64,
nummem_: i32,
j_: i32
) -> Result<(), String>
pub fn append_cone_seq( &mut self, ct_: i32, conepar_: f64, nummem_: i32, j_: i32 ) -> Result<(), String>
Appends a new conic constraint to the problem.
§Arguments
-
ct_
Specifies the type of the cone.See Conetype
-
conepar_
For the power cone it denotes the exponent alpha. For other cone types it is unused and can be set to 0. -
nummem_
Number of member variables in the cone. -
j_
Index of the first variable in the conic constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendconeseq
sourcepub fn append_cones_seq(
&mut self,
ct_: &[i32],
conepar_: &[f64],
nummem_: &[i32],
j_: i32
) -> Result<(), String>
pub fn append_cones_seq( &mut self, ct_: &[i32], conepar_: &[f64], nummem_: &[i32], j_: i32 ) -> Result<(), String>
Appends multiple conic constraints to the problem.
§Arguments
-
ct_
Specifies the type of the cone.See Conetype
-
conepar_
For the power cone it denotes the exponent alpha. For other cone types it is unused and can be set to 0. -
nummem_
Numbers of member variables in the cones. -
j_
Index of the first variable in the first cone to be appended.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendconesseq
sourcepub fn append_cons(&mut self, num_: i32) -> Result<(), String>
pub fn append_cons(&mut self, num_: i32) -> Result<(), String>
Appends a number of constraints to the optimization task.
§Arguments
num_
Number of constraints which should be appended.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendcons
Examples found in repository?
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
sourcepub fn append_djcs(&mut self, num_: i64) -> Result<(), String>
pub fn append_djcs(&mut self, num_: i64) -> Result<(), String>
Appends a number of empty disjunctive constraints to the task.
§Arguments
num_
Number of empty disjunctive constraints which should be appended.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appenddjcs
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
sourcepub fn append_dual_exp_cone_domain(&mut self) -> Result<i64, String>
pub fn append_dual_exp_cone_domain(&mut self) -> Result<i64, String>
Appends the dual exponential cone domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appenddualexpconedomain
sourcepub fn append_dual_geo_mean_cone_domain(
&mut self,
n_: i64
) -> Result<i64, String>
pub fn append_dual_geo_mean_cone_domain( &mut self, n_: i64 ) -> Result<i64, String>
Appends the dual geometric mean cone domain.
§Arguments
n_
Dimmension of the domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appenddualgeomeanconedomain
sourcepub fn append_dual_power_cone_domain(
&mut self,
n_: i64,
alpha_: &[f64]
) -> Result<i64, String>
pub fn append_dual_power_cone_domain( &mut self, n_: i64, alpha_: &[f64] ) -> Result<i64, String>
Appends the dual power cone domain.
§Arguments
n_
Dimension of the domain.alpha_
The sequence proportional to exponents. Must be positive.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appenddualpowerconedomain
sourcepub fn append_primal_exp_cone_domain(&mut self) -> Result<i64, String>
pub fn append_primal_exp_cone_domain(&mut self) -> Result<i64, String>
Appends the primal exponential cone domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendprimalexpconedomain
Examples found in repository?
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
More examples
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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 129 130
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
sourcepub fn append_primal_geo_mean_cone_domain(
&mut self,
n_: i64
) -> Result<i64, String>
pub fn append_primal_geo_mean_cone_domain( &mut self, n_: i64 ) -> Result<i64, String>
Appends the primal geometric mean cone domain.
§Arguments
n_
Dimmension of the domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendprimalgeomeanconedomain
sourcepub fn append_primal_power_cone_domain(
&mut self,
n_: i64,
alpha_: &[f64]
) -> Result<i64, String>
pub fn append_primal_power_cone_domain( &mut self, n_: i64, alpha_: &[f64] ) -> Result<i64, String>
Appends the primal power cone domain.
§Arguments
n_
Dimension of the domain.alpha_
The sequence proportional to exponents. Must be positive.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendprimalpowerconedomain
Examples found in repository?
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
More examples
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn append_quadratic_cone_domain(&mut self, n_: i64) -> Result<i64, String>
pub fn append_quadratic_cone_domain(&mut self, n_: i64) -> Result<i64, String>
Appends the n dimensional quadratic cone domain.
§Arguments
n_
Dimmension of the domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendquadraticconedomain
Examples found in repository?
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
More examples
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
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
fn portfolio(w : f64,
mu : &[f64],
x0 : &[f64],
gammas : &[f64],
theta : &[f64],
GT : &Matrix) -> Result<Vec<(f64,f64)>,String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
let (kx,nx) = GT.size();
if mu.len() != nx { panic!("Mismatching data"); }
let k : i32 = kx.try_into().unwrap();
let n : i32 = nx.try_into().unwrap();
let total_budget : f64 = w + x0.iter().sum::<f64>();
//Offset of variables into the API variable.
let numvar = n;
let voff_x : i32 = 0;
// Constraint offset
let coff_bud : i32 = 0;
// Holding variable x of length n
// No other auxiliary variables are needed in this formulation
task.append_vars(numvar)?;
// Setting up variable x
for j in 0..n {
task.put_var_name(voff_x+j,format!("x[{}]",j+1).as_str())?;
}
task.put_var_bound_slice_const(voff_x,voff_x+n, Boundkey::LO,0.0, INF)?;
// One linear constraint: total budget
task.append_cons(1)?;
task.put_con_name(coff_bud, "budget")?;
/* Coefficients in the first row of A */
for j in 0..n {
task.put_aij(coff_bud,voff_x + j, 1.0)?;
}
task.put_con_bound(coff_bud, Boundkey::FX, total_budget, total_budget)?;
// Input (gamma, G_factor_T x, diag(sqrt(theta))*x) in the AFE (affine expression) storage
// We need k+n+1 rows and we fill them in in three parts
task.append_afes((k+n) as i64 + 1)?;
// 1. The first affine expression = gamma, will be specified later
// 2. The next k expressions comprise G_factor_T*x, we add them row by row
// transposing the matrix G_factor on the fly
task.put_afe_f_row_list((1..1+k as i64).collect::<Vec<i64>>().as_slice(), // f row idxs
vec![n; k as usize].as_slice(), // row lengths
(0..GT.len() as i64).step_by(n as usize).collect::<Vec<i64>>().as_slice(), // row ptr
iproduct!(0..k,0..n).map(|(_,b)| b).collect::<Vec<i32>>().as_slice(), // varidx, 0..n repeated k times
GT.data_by_row().as_slice())?;
// 3. The remaining n rows contain sqrt(theta) on the diagonal
for (i,thetai) in (0..n).zip(theta.iter()) {
task.put_afe_f_entry(i as i64 + 1 + k as i64, voff_x + i, thetai.sqrt())?;
}
// Input the affine conic constraint (gamma, GT*x) \in QCone
// Add the quadratic domain of dimension k+1
let qdom = task.append_quadratic_cone_domain(k as i64+ 1)?;
// Add the constraint
task.append_acc_seq(qdom, 0, vec![0.0; k as usize+1].as_slice())?;
task.put_acc_name(0, "risk")?;
// Objective: maximize expected return mu^T x
for (j,&muj) in (0..n).zip(mu.iter()) {
task.put_c_j(voff_x + j, muj)?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
Ok(gammas.iter().filter_map(|&gamma| {
// Specify gamma in ACC
task.put_afe_g(0, gamma).ok()?;
task.optimize().ok()?;
/* Display solution summary for quick inspection of results */
let _ = task.solution_summary(Streamtype::LOG);
let _ = task.write_data(format!("portfolio_6_factor-{}.ptf",gamma).as_str());
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR).ok()? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Read the results */
let mut xx = vec![0.0; n as usize];
task.get_xx_slice(Soltype::ITR, voff_x, voff_x + n, xx.as_mut_slice()).ok()?;
Some((gamma,xx.iter().zip(mu.iter()).map(|(&xj,&muj)| xj*muj).sum::<f64>()))
}).collect::<Vec<(f64,f64)>>())
}
sourcepub fn append_r_domain(&mut self, n_: i64) -> Result<i64, String>
pub fn append_r_domain(&mut self, n_: i64) -> Result<i64, String>
Appends the n dimensional real number domain.
§Arguments
n_
Dimmension of the domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendrdomain
sourcepub fn append_rminus_domain(&mut self, n_: i64) -> Result<i64, String>
pub fn append_rminus_domain(&mut self, n_: i64) -> Result<i64, String>
Appends the n dimensional negative orthant to the list of domains.
§Arguments
n_
Dimmension of the domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendrminusdomain
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
sourcepub fn append_rplus_domain(&mut self, n_: i64) -> Result<i64, String>
pub fn append_rplus_domain(&mut self, n_: i64) -> Result<i64, String>
Appends the n dimensional positive orthant to the list of domains.
§Arguments
n_
Dimmension of the domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendrplusdomain
Examples found in repository?
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
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(())
}
sourcepub fn append_r_quadratic_cone_domain(&mut self, n_: i64) -> Result<i64, String>
pub fn append_r_quadratic_cone_domain(&mut self, n_: i64) -> Result<i64, String>
Appends the n dimensional rotated quadratic cone domain.
§Arguments
n_
Dimmension of the domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendrquadraticconedomain
Examples found in repository?
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
fn main() -> Result<(),String>
{
let numvar : i32 = 6;
let numcon : i32 = 1;
let bkc = &[ mosek::Boundkey::FX ];
let blc = &[ 1.0 ];
let buc = &[ 1.0 ];
let bkx = &[ mosek::Boundkey::LO,
mosek::Boundkey::LO,
mosek::Boundkey::LO,
mosek::Boundkey::FR,
mosek::Boundkey::FR,
mosek::Boundkey::FR];
let blx = &[ 0.0, 0.0, 0.0, -INF, -INF, -INF ];
let bux = &[ INF, INF, INF, INF, INF, INF ];
let c = &[ 0.0, 0.0, 0.0, 1.0, 1.0, 1.0 ];
let asub = &[0, 1, 2];
let aval = &[1.0, 1.0, 1.0];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
for (j,&cj,&bkj,&blj,&buj) in izip!(0..numvar,c,bkx,blx,bux) {
/* Set the linear term c_j in the objective.*/
task.put_c_j(j,cj)?;
/* Set the bounds on variable j.
* blx[j] <= x_j <= bux[j] */
task.put_var_bound( j, /* Index of variable.*/
bkj, /* Bound key.*/
blj, /* Numerical value of lower bound.*/
buj)?; /* Numerical value of upper bound.*/
}
/* Input columns of A */
task.put_a_row(0, asub, aval)?;
/* Set the bounds on constraints.
* for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for (i,&bki,&bli,&bui) in izip!(0..numcon,bkc,blc,buc) {
task.put_con_bound( i, /* Index of constraint.*/
bki, /* Bound key.*/
bli, /* Numerical value of lower bound.*/
bui)?; /* Numerical value of upper bound.*/
}
/* Append the first cone. */
// Create a matrix F such that F * x = [x(3),x(0),x(1),x(4),x(5),x(2)]
{
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0,1,2,3,4,5], // Rows
&[3, 0, 1, 4, 5, 2], // Columns
&[1.0,1.0,1.0,1.0,1.0,1.0])?;
// Quadratic cone (x(3),x(0),x(1)) \in QUAD_3
let qconedom = task.append_quadratic_cone_domain(3)?;
task.append_acc(qconedom, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
// Rotated quadratic cone (x(4),x(5),x(2)) \in RQUAD_3
let rqconedom = task.append_r_quadratic_cone_domain(3)?;
task.append_acc(rqconedom, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
}
/* Run optimizer */
let trm = task.optimize()?;
task.write_data("cqo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,xj) in izip!(0..numvar,xx) {
println!("x[{}]: {}",j,xj);
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN => {
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",trm);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn append_rzero_domain(&mut self, n_: i64) -> Result<i64, String>
pub fn append_rzero_domain(&mut self, n_: i64) -> Result<i64, String>
Appends the n dimensional 0 domain.
§Arguments
n_
Dimmension of the domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendrzerodomain
Examples found in repository?
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
More examples
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
sourcepub fn append_sparse_sym_mat(
&mut self,
dim_: i32,
subi_: &[i32],
subj_: &[i32],
valij_: &[f64]
) -> Result<i64, String>
pub fn append_sparse_sym_mat( &mut self, dim_: i32, subi_: &[i32], subj_: &[i32], valij_: &[f64] ) -> Result<i64, String>
Appends a general sparse symmetric matrix to the storage of symmetric matrices.
§Arguments
dim_
Dimension of the symmetric matrix that is appended.subi_
Row subscript in the triplets.subj_
Column subscripts in the triplets.valij_
Values of each triplet.
§Returns
idx
Unique index assigned to the inputted matrix.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendsparsesymmat
Examples found in repository?
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
fn main() -> Result<(),String>
{
let dimbarvar = vec![3]; /* Dimension of semidefinite cone */
let bkc = &[ mosek::Boundkey::FX, mosek::Boundkey::FX ];
let blc = &[ 1.0, 0.5 ];
let buc = &[ 1.0, 0.5 ];
let barc_i = &[0, 1, 1, 2, 2];
let barc_j = &[0, 0, 1, 1, 2];
let barc_v = &[2.0, 1.0, 2.0, 1.0, 2.0];
let aptrb = &[0, 1];
let aptre = &[1, 3];
let asub = &[0, 1, 2]; /* column subscripts of A */
let aval = &[1.0, 1.0, 1.0];
let bara_i = &[0, 1, 2, 0, 1, 2, 1, 2, 2];
let bara_j = &[0, 1, 2, 0, 0, 0, 1, 1, 2];
let bara_v = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let falpha = 1.0;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'NUMCON' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Append 'NUMBARVAR' semidefinite variables. */
task.append_barvars(&dimbarvar[..])?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
/* Set the linear term c_j in the objective.*/
task.put_c_j(0,1.0)?;
for j in 0..NUMVAR {
task.put_var_bound(j as i32,
mosek::Boundkey::FR,
-INF,
INF)?;
}
/* Set the linear term barc_j in the objective.*/
let c_symmat_idx = task.append_sparse_sym_mat(dimbarvar[0],
barc_i,
barc_j,
barc_v)?;
task.put_barc_j(0, &[c_symmat_idx], &[falpha])?;
for i in 0..NUMCON
{
/* Input A row by row */
task.put_a_row(i as i32,
& asub[aptrb[i]..aptre[i]],
& aval[aptrb[i]..aptre[i]])?;
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
}
{
/* Append the conic quadratic cone */
let afei = task.get_num_afe()?;
task.append_afes(3)?;
task.put_afe_f_entry_list(&[0,1,2],
&[0,1,2],
&[1.0,1.0,1.0])?;
let dom = task.append_quadratic_cone_domain(3)?;
task.append_acc_seq(dom,afei,&[0.0,0.0,0.0])?;
}
/* Add the first row of barA */
let a_symmat_idx1 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[..3],
& bara_j[..3],
& bara_v[..3])?;
task.put_bara_ij(0, 0, &[a_symmat_idx1][..], &[falpha][..])?;
/* Add the second row of barA */
let a_symmat_idx2 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[3..9],
& bara_j[3..9],
& bara_v[3..9])?;
task.put_bara_ij(1, 0, &[a_symmat_idx2][..], &[falpha][..])?;
let _trmcode = task.optimize()?;
task.write_data("sdo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0,0.0,0.0];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
& mut xx[..])?;
let mut barx = vec![0.0,0.0,0.0,0.0,0.0,0.0];
task.get_barx_j(Soltype::ITR, /* Request the interior solution. */
0,
& mut barx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR as usize
{
println!("x[{}]: {}",j,xx[j]);
}
let n = dimbarvar[0] as usize;
for j in 0..n
{
for i in j..n
{
println!("barx[{},{}]: {}",i,j,barx[j*n+i-j*(j+1)/2]);
}
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN =>
{
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",solsta);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn append_sparse_sym_mat_list(
&mut self,
dims_: &[i32],
nz_: &[i64],
subi_: &[i32],
subj_: &[i32],
valij_: &[f64],
idx_: &mut [i64]
) -> Result<(), String>
pub fn append_sparse_sym_mat_list( &mut self, dims_: &[i32], nz_: &[i64], subi_: &[i32], subj_: &[i32], valij_: &[f64], idx_: &mut [i64] ) -> Result<(), String>
Appends a general sparse symmetric matrix to the storage of symmetric matrices.
§Arguments
dims_
Dimensions of the symmetric matrixes.nz_
Number of nonzeros for each matrix.subi_
Row subscript in the triplets.subj_
Column subscripts in the triplets.valij_
Values of each triplet.idx_
Unique index assigned to the inputted matrix.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendsparsesymmatlist
sourcepub fn append_svec_psd_cone_domain(&mut self, n_: i64) -> Result<i64, String>
pub fn append_svec_psd_cone_domain(&mut self, n_: i64) -> Result<i64, String>
Appends the vectorized SVEC PSD cone domain.
§Arguments
n_
Dimension of the domain.
§Returns
domidx
Index of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendsvecpsdconedomain
Examples found in repository?
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
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(())
}
sourcepub fn append_vars(&mut self, num_: i32) -> Result<(), String>
pub fn append_vars(&mut self, num_: i32) -> Result<(), String>
Appends a number of variables to the optimization task.
§Arguments
num_
Number of variables which should be appended.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.appendvars
Examples found in repository?
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
sourcepub fn async_get_log(
&mut self,
addr_: &str,
accesstoken_: &str,
token_: &str
) -> Result<(), String>
pub fn async_get_log( &mut self, addr_: &str, accesstoken_: &str, token_: &str ) -> Result<(), String>
Get the optimizer log from a remote job.
§Arguments
addr_
Address of the solver serveraccesstoken_
Access token string.token_
Job token
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.asyncgetlog
sourcepub fn async_get_result(
&mut self,
address_: &str,
accesstoken_: &str,
token_: &str,
resp_: &mut i32,
trm_: &mut i32
) -> Result<bool, String>
pub fn async_get_result( &mut self, address_: &str, accesstoken_: &str, token_: &str, resp_: &mut i32, trm_: &mut i32 ) -> Result<bool, String>
Request a solution from a remote job.
§Arguments
-
address_
Address of the OptServer. -
accesstoken_
Access token. -
token_
The task token. -
resp_
Is the response code from the remote solver.See Rescode
-
trm_
Is either OK or a termination response code.See Rescode
§Returns
respavailable
Indicates if a remote response is available.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.asyncgetresult
sourcepub fn async_optimize(
&mut self,
address_: &str,
accesstoken_: &str
) -> Result<String, String>
pub fn async_optimize( &mut self, address_: &str, accesstoken_: &str ) -> Result<String, String>
Offload the optimization task to a solver server in asynchronous mode.
§Arguments
address_
Address of the OptServer.accesstoken_
Access token.
§Returns
token
Returns the task token.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.asyncoptimize
sourcepub fn async_poll(
&mut self,
address_: &str,
accesstoken_: &str,
token_: &str,
resp_: &mut i32,
trm_: &mut i32
) -> Result<bool, String>
pub fn async_poll( &mut self, address_: &str, accesstoken_: &str, token_: &str, resp_: &mut i32, trm_: &mut i32 ) -> Result<bool, String>
Requests information about the status of the remote job.
§Arguments
-
address_
Address of the OptServer. -
accesstoken_
Access token. -
token_
The task token. -
resp_
Is the response code from the remote solver.See Rescode
-
trm_
Is either OK or a termination response code.See Rescode
§Returns
respavailable
Indicates if a remote response is available.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.asyncpoll
sourcepub fn async_stop(
&mut self,
address_: &str,
accesstoken_: &str,
token_: &str
) -> Result<(), String>
pub fn async_stop( &mut self, address_: &str, accesstoken_: &str, token_: &str ) -> Result<(), String>
Request that the job identified by the token is terminated.
§Arguments
address_
Address of the OptServer.accesstoken_
Access token.token_
The task token.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.asyncstop
sourcepub fn basis_cond(
&mut self,
nrmbasis_: &mut f64,
nrminvbasis_: &mut f64
) -> Result<(), String>
pub fn basis_cond( &mut self, nrmbasis_: &mut f64, nrminvbasis_: &mut f64 ) -> Result<(), String>
Computes conditioning information for the basis matrix.
§Arguments
nrmbasis_
An estimate for the 1-norm of the basis.nrminvbasis_
An estimate for the 1-norm of the inverse of the basis.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.basiscond
sourcepub fn check_mem(&mut self, file_: &str, line_: i32) -> Result<(), String>
pub fn check_mem(&mut self, file_: &str, line_: i32) -> Result<(), String>
Checks the memory allocated by the task.
§Arguments
file_
File from which the function is called.line_
Line in the file from which the function is called.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.checkmemtask
sourcepub fn chg_con_bound(
&mut self,
i_: i32,
lower_: i32,
finite_: i32,
value_: f64
) -> Result<(), String>
pub fn chg_con_bound( &mut self, i_: i32, lower_: i32, finite_: i32, value_: f64 ) -> Result<(), String>
Changes the bounds for one constraint.
§Arguments
i_
Index of the constraint for which the bounds should be changed.lower_
If non-zero, then the lower bound is changed, otherwise the upper bound is changed.finite_
If non-zero, then the given value is assumed to be finite.value_
New value for the bound.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.chgconbound
sourcepub fn chg_var_bound(
&mut self,
j_: i32,
lower_: i32,
finite_: i32,
value_: f64
) -> Result<(), String>
pub fn chg_var_bound( &mut self, j_: i32, lower_: i32, finite_: i32, value_: f64 ) -> Result<(), String>
Changes the bounds for one variable.
§Arguments
j_
Index of the variable for which the bounds should be changed.lower_
If non-zero, then the lower bound is changed, otherwise the upper bound is changed.finite_
If non-zero, then the given value is assumed to be finite.value_
New value for the bound.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.chgvarbound
sourcepub fn commit_changes(&mut self) -> Result<(), String>
pub fn commit_changes(&mut self) -> Result<(), String>
Commits all cached problem changes.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.commitchanges
sourcepub fn delete_solution(&mut self, whichsol_: i32) -> Result<(), String>
pub fn delete_solution(&mut self, whichsol_: i32) -> Result<(), String>
Undefine a solution and free the memory it uses.
§Arguments
-
whichsol_
Selects a solution.See Soltype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.deletesolution
sourcepub fn dual_sensitivity(
&self,
subj_: &[i32],
leftpricej_: &mut [f64],
rightpricej_: &mut [f64],
leftrangej_: &mut [f64],
rightrangej_: &mut [f64]
) -> Result<(), String>
pub fn dual_sensitivity( &self, subj_: &[i32], leftpricej_: &mut [f64], rightpricej_: &mut [f64], leftrangej_: &mut [f64], rightrangej_: &mut [f64] ) -> Result<(), String>
Performs sensitivity analysis on objective coefficients.
§Arguments
subj_
Indexes of objective coefficients to analyze.leftpricej_
Left shadow prices for requested coefficients.rightpricej_
Right shadow prices for requested coefficients.leftrangej_
Left range for requested coefficients.rightrangej_
Right range for requested coefficients.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.dualsensitivity
Examples found in repository?
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
fn main() -> Result<(),String> {
let bkc = vec![
Boundkey::UP, Boundkey::UP,
Boundkey::UP, Boundkey::FX,
Boundkey::FX, Boundkey::FX,
Boundkey::FX ];
let bkx = vec![
Boundkey::LO, Boundkey::LO,
Boundkey::LO, Boundkey::LO,
Boundkey::LO, Boundkey::LO,
Boundkey::LO ];
let ptr = [0i64, 2, 4, 6, 8, 10, 12, 14];
let sub = [0i32, 3, 0, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6];
let blc = [ -INFINITY, -INFINITY, -INFINITY, 800.0, 100.0, 500.0, 500.0 ];
let buc = [400.0, 1200.0, 1000.0, 800.0, 100.0, 500.0, 500.0];
let c = [1.0, 2.0, 5.0, 2.0, 1.0, 2.0, 1.0];
let blx = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
let bux = [INFINITY, INFINITY,
INFINITY, INFINITY,
INFINITY, INFINITY,
INFINITY];
let val = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let numcon = 7; /* Number of constraints. */
let numvar = 7; /* Number of variables. */
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
/* Directs the log task stream to the 'printstr' function. */
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon as i32, numvar as i32,
&c,
0.0,
&ptr[0..numvar as usize],
&ptr[1..numvar as usize+1],
&sub,
&val,
&bkc,
&blc,
&buc,
&bkx,
&blx,
&bux)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MINIMIZE)?;
task.optimize()?;
/* Analyze upper bound on c1 and the equality constraint on c4 */
let mut subi = vec![0i32, 3i32];
let mut marki = vec![Mark::UP, Mark::UP];
/* Analyze lower bound on the variables x12 and x31 */
let mut subj = vec![1i32, 4];
let mut markj = vec![Mark::LO, Mark::LO];
let mut leftpricei = vec![0.0; 2];
let mut rightpricei = vec![0.0; 2];
let mut leftrangei = vec![0.0; 2];
let mut rightrangei = vec![0.0; 2];
let mut leftpricej = vec![0.0; 2];
let mut rightpricej = vec![0.0; 2];
let mut leftrangej = vec![0.0; 2];
let mut rightrangej = vec![0.0; 2];
task.primal_sensitivity(subi.as_mut_slice(),
marki.as_mut_slice(),
subj.as_mut_slice(),
markj.as_mut_slice(),
leftpricei.as_mut_slice(),
rightpricei.as_mut_slice(),
leftrangei.as_mut_slice(),
rightrangei.as_mut_slice(),
leftpricej.as_mut_slice(),
rightpricej.as_mut_slice(),
leftrangej.as_mut_slice(),
rightrangej.as_mut_slice())?;
println!("Results from sensitivity analysis on bounds:");
println!("For constraints:");
for i in 0..2 {
println!("leftprice = {:.5e}, rightprice = {:.5e}, leftrange = {:.5e}, rightrange = {:.5e}",
leftpricei[i], rightpricei[i], leftrangei[i], rightrangei[i]);
}
println!("For variables:\n");
for i in 0..2 {
println!("leftprice = {:.5e}, rightprice = {:.5e}, leftrange = {:.5e}, rightrange = {:.5e}",
leftpricej[i], rightpricej[i], leftrangej[i], rightrangej[i]);
}
let mut leftprice = vec![0.0; 2];
let mut rightprice = vec![0.0; 2];
let mut leftrange = vec![0.0; 2];
let mut rightrange = vec![0.0; 2];
let subc = [2i32, 5i32];
task.dual_sensitivity(&subc,
leftprice.as_mut_slice(),
rightprice.as_mut_slice(),
leftrange.as_mut_slice(),
rightrange.as_mut_slice())?;
println!("Results from sensitivity analysis on objective coefficients:");
for i in 0..2 {
println!("leftprice = {:.5e}, rightprice = {:.5e}, leftrange = {:.5e}, rightrange = {:.5e}",
leftprice[i], rightprice[i], leftrange[i], rightrange[i]);
}
return Result::Ok(());
}
sourcepub fn empty_afe_barf_row(&mut self, afeidx_: i64) -> Result<(), String>
pub fn empty_afe_barf_row(&mut self, afeidx_: i64) -> Result<(), String>
Clears a row in barF
§Arguments
afeidx_
Row index of barF.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.emptyafebarfrow
sourcepub fn empty_afe_barf_row_list(
&mut self,
afeidxlist_: &[i64]
) -> Result<(), String>
pub fn empty_afe_barf_row_list( &mut self, afeidxlist_: &[i64] ) -> Result<(), String>
Clears rows in barF.
§Arguments
afeidxlist_
Indices of rows in barF to clear.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.emptyafebarfrowlist
sourcepub fn empty_afe_f_col(&mut self, varidx_: i32) -> Result<(), String>
pub fn empty_afe_f_col(&mut self, varidx_: i32) -> Result<(), String>
Clears a column in F.
§Arguments
varidx_
Variable index.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.emptyafefcol
sourcepub fn empty_afe_f_col_list(&mut self, varidx_: &[i32]) -> Result<(), String>
pub fn empty_afe_f_col_list(&mut self, varidx_: &[i32]) -> Result<(), String>
Clears columns in F.
§Arguments
varidx_
Indices of variables in F to clear.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.emptyafefcollist
sourcepub fn empty_afe_f_row(&mut self, afeidx_: i64) -> Result<(), String>
pub fn empty_afe_f_row(&mut self, afeidx_: i64) -> Result<(), String>
Clears a row in F.
§Arguments
afeidx_
Row index.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.emptyafefrow
sourcepub fn empty_afe_f_row_list(&mut self, afeidx_: &[i64]) -> Result<(), String>
pub fn empty_afe_f_row_list(&mut self, afeidx_: &[i64]) -> Result<(), String>
Clears rows in F.
§Arguments
afeidx_
Indices of rows in F to clear.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.emptyafefrowlist
sourcepub fn evaluate_acc(
&self,
whichsol_: i32,
accidx_: i64,
activity_: &mut [f64]
) -> Result<(), String>
pub fn evaluate_acc( &self, whichsol_: i32, accidx_: i64, activity_: &mut [f64] ) -> Result<(), String>
Evaluates the activity of an affine conic constraint.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
accidx_
The index of the affine conic constraint. -
activity_
The activity of the affine conic constraint. The array should have length equal to the dimension of the constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.evaluateacc
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
sourcepub fn evaluate_accs(
&self,
whichsol_: i32,
activity_: &mut [f64]
) -> Result<(), String>
pub fn evaluate_accs( &self, whichsol_: i32, activity_: &mut [f64] ) -> Result<(), String>
Evaluates the activities of all affine conic constraints.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
activity_
The activity of affine conic constraints. The array should have length equal to the sum of dimensions of all affine conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.evaluateaccs
sourcepub fn generate_acc_names(
&mut self,
sub_: &[i64],
fmt_: &str,
dims_: &[i32],
sp_: &[i64],
namedaxisidxs_: &[i32],
names_: &[String]
) -> Result<(), String>
pub fn generate_acc_names( &mut self, sub_: &[i64], fmt_: &str, dims_: &[i32], sp_: &[i64], namedaxisidxs_: &[i32], names_: &[String] ) -> Result<(), String>
Generates systematic names for affine conic constraints.
§Arguments
sub_
Indexes of the affine conic constraints.fmt_
The variable name formatting string.dims_
Dimensions in the shape.sp_
Items that should be named.namedaxisidxs_
List if named index axesnames_
All axis names.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.generateaccnames
sourcepub fn generate_barvar_names(
&mut self,
subj_: &[i32],
fmt_: &str,
dims_: &[i32],
sp_: &[i64],
namedaxisidxs_: &[i32],
names_: &[String]
) -> Result<(), String>
pub fn generate_barvar_names( &mut self, subj_: &[i32], fmt_: &str, dims_: &[i32], sp_: &[i64], namedaxisidxs_: &[i32], names_: &[String] ) -> Result<(), String>
Generates systematic names for variables.
§Arguments
subj_
Indexes of the variables.fmt_
The variable name formatting string.dims_
Dimensions in the shape.sp_
Items that should be named.namedaxisidxs_
List if named index axesnames_
All axis names.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.generatebarvarnames
sourcepub fn generate_cone_names(
&mut self,
subk_: &[i32],
fmt_: &str,
dims_: &[i32],
sp_: &[i64],
namedaxisidxs_: &[i32],
names_: &[String]
) -> Result<(), String>
pub fn generate_cone_names( &mut self, subk_: &[i32], fmt_: &str, dims_: &[i32], sp_: &[i64], namedaxisidxs_: &[i32], names_: &[String] ) -> Result<(), String>
Generates systematic names for cone.
§Arguments
subk_
Indexes of the cone.fmt_
The cone name formatting string.dims_
Dimensions in the shape.sp_
Items that should be named.namedaxisidxs_
List if named index axesnames_
All axis names.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.generateconenames
sourcepub fn generate_con_names(
&mut self,
subi_: &[i32],
fmt_: &str,
dims_: &[i32],
sp_: &[i64],
namedaxisidxs_: &[i32],
names_: &[String]
) -> Result<(), String>
pub fn generate_con_names( &mut self, subi_: &[i32], fmt_: &str, dims_: &[i32], sp_: &[i64], namedaxisidxs_: &[i32], names_: &[String] ) -> Result<(), String>
Generates systematic names for constraints.
§Arguments
subi_
Indexes of the constraints.fmt_
The constraint name formatting string.dims_
Dimensions in the shape.sp_
Items that should be named.namedaxisidxs_
List if named index axesnames_
All axis names.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.generateconnames
sourcepub fn generate_djc_names(
&mut self,
sub_: &[i64],
fmt_: &str,
dims_: &[i32],
sp_: &[i64],
namedaxisidxs_: &[i32],
names_: &[String]
) -> Result<(), String>
pub fn generate_djc_names( &mut self, sub_: &[i64], fmt_: &str, dims_: &[i32], sp_: &[i64], namedaxisidxs_: &[i32], names_: &[String] ) -> Result<(), String>
Generates systematic names for affine conic constraints.
§Arguments
sub_
Indexes of the disjunctive constraints.fmt_
The variable name formatting string.dims_
Dimensions in the shape.sp_
Items that should be named.namedaxisidxs_
List if named index axesnames_
All axis names.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.generatedjcnames
sourcepub fn generate_var_names(
&mut self,
subj_: &[i32],
fmt_: &str,
dims_: &[i32],
sp_: &[i64],
namedaxisidxs_: &[i32],
names_: &[String]
) -> Result<(), String>
pub fn generate_var_names( &mut self, subj_: &[i32], fmt_: &str, dims_: &[i32], sp_: &[i64], namedaxisidxs_: &[i32], names_: &[String] ) -> Result<(), String>
Generates systematic names for variables.
§Arguments
subj_
Indexes of the variables.fmt_
The variable name formatting string.dims_
Dimensions in the shape.sp_
Items that should be named.namedaxisidxs_
List if named index axesnames_
All axis names.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.generatevarnames
sourcepub fn get_acc_afe_idx_list(
&self,
accidx_: i64,
afeidxlist_: &mut [i64]
) -> Result<(), String>
pub fn get_acc_afe_idx_list( &self, accidx_: i64, afeidxlist_: &mut [i64] ) -> Result<(), String>
Obtains the list of affine expressions appearing in the affine conic constraint.
§Arguments
accidx_
Index of the affine conic constraint.afeidxlist_
List of indexes of affine expressions appearing in the constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccafeidxlist
sourcepub fn get_acc_b(&self, accidx_: i64, b_: &mut [f64]) -> Result<(), String>
pub fn get_acc_b(&self, accidx_: i64, b_: &mut [f64]) -> Result<(), String>
Obtains the additional constant term vector appearing in the affine conic constraint.
§Arguments
accidx_
Index of the affine conic constraint.b_
The vector b appearing in the constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccb
sourcepub fn get_acc_barf_block_triplet(
&self,
acc_afe_: &mut [i64],
bar_var_: &mut [i32],
blk_row_: &mut [i32],
blk_col_: &mut [i32],
blk_val_: &mut [f64]
) -> Result<i64, String>
pub fn get_acc_barf_block_triplet( &self, acc_afe_: &mut [i64], bar_var_: &mut [i32], blk_row_: &mut [i32], blk_col_: &mut [i32], blk_val_: &mut [f64] ) -> Result<i64, String>
Obtains barF, implied by the ACCs, in block triplet form.
§Arguments
acc_afe_
Index of the AFE within the concatenated list of AFEs in ACCs.bar_var_
Symmetric matrix variable index.blk_row_
Block row index.blk_col_
Block column index.blk_val_
The numerical value associated with each block triplet.
§Returns
numtrip
Number of elements in the block triplet form.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccbarfblocktriplet
sourcepub fn get_acc_barf_num_block_triplets(&self) -> Result<i64, String>
pub fn get_acc_barf_num_block_triplets(&self) -> Result<i64, String>
Obtains an upper bound on the number of elements in the block triplet form of barf, as used within the ACCs.
§Returns
numtrip
An upper bound on the number of elements in the block triplet form of barf, as used within the ACCs.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccbarfnumblocktriplets
sourcepub fn get_acc_domain(&mut self, accidx_: i64) -> Result<i64, String>
pub fn get_acc_domain(&mut self, accidx_: i64) -> Result<i64, String>
Obtains the domain appearing in the affine conic constraint.
§Arguments
accidx_
The index of the affine conic constraint.
§Returns
domidx
The index of domain in the affine conic constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccdomain
sourcepub fn get_acc_dot_y(
&self,
whichsol_: i32,
accidx_: i64,
doty_: &mut [f64]
) -> Result<(), String>
pub fn get_acc_dot_y( &self, whichsol_: i32, accidx_: i64, doty_: &mut [f64] ) -> Result<(), String>
Obtains the doty vector for an affine conic constraint.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
accidx_
The index of the affine conic constraint. -
doty_
The dual values for this affine conic constraint. The array should have length equal to the dimension of the constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccdoty
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
sourcepub fn get_acc_dot_y_s(
&self,
whichsol_: i32,
doty_: &mut [f64]
) -> Result<(), String>
pub fn get_acc_dot_y_s( &self, whichsol_: i32, doty_: &mut [f64] ) -> Result<(), String>
Obtains the doty vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
doty_
The dual values of affine conic constraints. The array should have length equal to the sum of dimensions of all affine conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccdotys
sourcepub fn get_acc_f_numnz(&mut self) -> Result<i64, String>
pub fn get_acc_f_numnz(&mut self) -> Result<i64, String>
Obtains the total number of nonzeros in the ACC implied F matrix.
§Returns
accfnnz
Number of nonzeros in the F matrix implied by ACCs.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccfnumnz
sourcepub fn get_acc_f_trip(
&mut self,
frow_: &mut [i64],
fcol_: &mut [i32],
fval_: &mut [f64]
) -> Result<(), String>
pub fn get_acc_f_trip( &mut self, frow_: &mut [i64], fcol_: &mut [i32], fval_: &mut [f64] ) -> Result<(), String>
Obtains the F matrix (implied by the AFE ordering within the ACCs) in triplet format.
§Arguments
frow_
Row indices of nonzeros in the implied F matrix.fcol_
Column indices of nonzeros in the implied F matrix.fval_
Values of nonzero entries in the implied F matrix.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccftrip
sourcepub fn get_acc_g_vector(&self, g_: &mut [f64]) -> Result<(), String>
pub fn get_acc_g_vector(&self, g_: &mut [f64]) -> Result<(), String>
The g vector as used within the ACCs.
§Arguments
g_
The g vector as used within the ACCs.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccgvector
sourcepub fn get_acc_n(&mut self, accidx_: i64) -> Result<i64, String>
pub fn get_acc_n(&mut self, accidx_: i64) -> Result<i64, String>
Obtains the dimension of the affine conic constraint.
§Arguments
accidx_
The index of the affine conic constraint.
§Returns
n
The dimension of the affine conic constraint (equal to the dimension of its domain).
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccn
sourcepub fn get_acc_name(&self, accidx_: i64) -> Result<String, String>
pub fn get_acc_name(&self, accidx_: i64) -> Result<String, String>
Obtains the name of an affine conic constraint.
§Arguments
accidx_
Index of an affine conic constraint.
§Returns
name
Returns the required name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccname
sourcepub fn get_acc_name_len(&self, accidx_: i64) -> Result<i32, String>
pub fn get_acc_name_len(&self, accidx_: i64) -> Result<i32, String>
Obtains the length of the name of an affine conic constraint.
§Arguments
accidx_
Index of an affine conic constraint.
§Returns
len
Returns the length of the indicated name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccnamelen
sourcepub fn get_acc_n_tot(&mut self) -> Result<i64, String>
pub fn get_acc_n_tot(&mut self) -> Result<i64, String>
Obtains the total dimension of all affine conic constraints.
§Returns
n
The total dimension of all affine conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccntot
sourcepub fn get_accs(
&self,
domidxlist_: &mut [i64],
afeidxlist_: &mut [i64],
b_: &mut [f64]
) -> Result<(), String>
pub fn get_accs( &self, domidxlist_: &mut [i64], afeidxlist_: &mut [i64], b_: &mut [f64] ) -> Result<(), String>
Obtains full data of all affine conic constraints.
§Arguments
domidxlist_
The list of domains appearing in all affine conic constraints.afeidxlist_
The concatenation of index lists of affine expressions appearing in all affine conic constraints.b_
The concatenation of vectors b appearing in all affine conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaccs
sourcepub fn get_a_col(
&self,
j_: i32,
nzj_: &mut i32,
subj_: &mut [i32],
valj_: &mut [f64]
) -> Result<(), String>
pub fn get_a_col( &self, j_: i32, nzj_: &mut i32, subj_: &mut [i32], valj_: &mut [f64] ) -> Result<(), String>
Obtains one column of the linear constraint matrix.
§Arguments
j_
Index of the column.nzj_
Number of non-zeros in the column obtained.subj_
Row indices of the non-zeros in the column obtained.valj_
Numerical values in the column obtained.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getacol
sourcepub fn get_a_col_num_nz(&self, i_: i32) -> Result<i32, String>
pub fn get_a_col_num_nz(&self, i_: i32) -> Result<i32, String>
Obtains the number of non-zero elements in one column of the linear constraint matrix
§Arguments
i_
Index of the column.
§Returns
nzj
Number of non-zeros in the j’th column of (A).
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getacolnumnz
sourcepub fn get_a_col_slice(
&self,
first_: i32,
last_: i32,
ptrb_: &mut [i64],
ptre_: &mut [i64],
sub_: &mut [i32],
val_: &mut [f64]
) -> Result<(), String>
pub fn get_a_col_slice( &self, first_: i32, last_: i32, ptrb_: &mut [i64], ptre_: &mut [i64], sub_: &mut [i32], val_: &mut [f64] ) -> Result<(), String>
Obtains a sequence of columns from the coefficient matrix.
§Arguments
first_
Index of the first column in the sequence.last_
Index of the last column in the sequence plus one.ptrb_
Column start pointers.ptre_
Column end pointers.sub_
Contains the row subscripts.val_
Contains the coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getacolslice64
sourcepub fn get_a_col_slice_num_nz(
&self,
first_: i32,
last_: i32
) -> Result<i64, String>
pub fn get_a_col_slice_num_nz( &self, first_: i32, last_: i32 ) -> Result<i64, String>
Obtains the number of non-zeros in a slice of columns of the coefficient matrix.
§Arguments
first_
Index of the first column in the sequence.last_
Index of the last column plus one in the sequence.
§Returns
numnz
Number of non-zeros in the slice.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getacolslicenumnz64
sourcepub fn get_a_col_slice_trip(
&self,
first_: i32,
last_: i32,
subi_: &mut [i32],
subj_: &mut [i32],
val_: &mut [f64]
) -> Result<(), String>
pub fn get_a_col_slice_trip( &self, first_: i32, last_: i32, subi_: &mut [i32], subj_: &mut [i32], val_: &mut [f64] ) -> Result<(), String>
Obtains a sequence of columns from the coefficient matrix in triplet format.
§Arguments
first_
Index of the first column in the sequence.last_
Index of the last column in the sequence plus one.subi_
Constraint subscripts.subj_
Column subscripts.val_
Values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getacolslicetrip
sourcepub fn get_afe_barf_block_triplet(
&self,
afeidx_: &mut [i64],
barvaridx_: &mut [i32],
subk_: &mut [i32],
subl_: &mut [i32],
valkl_: &mut [f64]
) -> Result<i64, String>
pub fn get_afe_barf_block_triplet( &self, afeidx_: &mut [i64], barvaridx_: &mut [i32], subk_: &mut [i32], subl_: &mut [i32], valkl_: &mut [f64] ) -> Result<i64, String>
Obtains barF in block triplet form.
§Arguments
afeidx_
Constraint index.barvaridx_
Symmetric matrix variable index.subk_
Block row index.subl_
Block column index.valkl_
The numerical value associated with each block triplet.
§Returns
numtrip
Number of elements in the block triplet form.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafebarfblocktriplet
sourcepub fn get_afe_barf_num_block_triplets(&self) -> Result<i64, String>
pub fn get_afe_barf_num_block_triplets(&self) -> Result<i64, String>
Obtains an upper bound on the number of elements in the block triplet form of barf.
§Returns
numtrip
An upper bound on the number of elements in the block triplet form of barf.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafebarfnumblocktriplets
sourcepub fn get_afe_barf_num_row_entries(
&mut self,
afeidx_: i64
) -> Result<i32, String>
pub fn get_afe_barf_num_row_entries( &mut self, afeidx_: i64 ) -> Result<i32, String>
Obtains the number of nonzero entries in a row of barF.
§Arguments
afeidx_
Row index of barF.
§Returns
numentr
Number of nonzero entries in a row of barF.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafebarfnumrowentries
sourcepub fn get_afe_barf_row(
&mut self,
afeidx_: i64,
barvaridx_: &mut [i32],
ptrterm_: &mut [i64],
numterm_: &mut [i64],
termidx_: &mut [i64],
termweight_: &mut [f64]
) -> Result<(), String>
pub fn get_afe_barf_row( &mut self, afeidx_: i64, barvaridx_: &mut [i32], ptrterm_: &mut [i64], numterm_: &mut [i64], termidx_: &mut [i64], termweight_: &mut [f64] ) -> Result<(), String>
Obtains nonzero entries in one row of barF.
§Arguments
afeidx_
Row index of barF.barvaridx_
Semidefinite variable indices.ptrterm_
Pointers to the description of entries.numterm_
Number of terms in each entry.termidx_
Indices of semidefinite matrices from E.termweight_
Weights appearing in the weighted sum representation.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafebarfrow
sourcepub fn get_afe_barf_row_info(
&mut self,
afeidx_: i64,
numentr_: &mut i32,
numterm_: &mut i64
) -> Result<(), String>
pub fn get_afe_barf_row_info( &mut self, afeidx_: i64, numentr_: &mut i32, numterm_: &mut i64 ) -> Result<(), String>
Obtains information about one row of barF.
§Arguments
afeidx_
Row index of barF.numentr_
Number of nonzero entries in a row of barF.numterm_
Number of terms in the weighted sums representation of the row of barF.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafebarfrowinfo
sourcepub fn get_afe_f_num_nz(&mut self) -> Result<i64, String>
pub fn get_afe_f_num_nz(&mut self) -> Result<i64, String>
Obtains the total number of nonzeros in F.
§Returns
numnz
Number of nonzeros in F.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafefnumnz
sourcepub fn get_afe_f_row(
&mut self,
afeidx_: i64,
numnz_: &mut i32,
varidx_: &mut [i32],
val_: &mut [f64]
) -> Result<(), String>
pub fn get_afe_f_row( &mut self, afeidx_: i64, numnz_: &mut i32, varidx_: &mut [i32], val_: &mut [f64] ) -> Result<(), String>
Obtains one row of F in sparse format.
§Arguments
afeidx_
Row index.numnz_
Number of non-zeros in the row obtained.varidx_
Column indices of the non-zeros in the row obtained.val_
Values of the non-zeros in the row obtained.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafefrow
sourcepub fn get_afe_f_row_num_nz(&mut self, afeidx_: i64) -> Result<i32, String>
pub fn get_afe_f_row_num_nz(&mut self, afeidx_: i64) -> Result<i32, String>
Obtains the number of nonzeros in a row of F.
§Arguments
afeidx_
Row index.
§Returns
numnz
Number of non-zeros in the row.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafefrownumnz
sourcepub fn get_afe_f_trip(
&mut self,
afeidx_: &mut [i64],
varidx_: &mut [i32],
val_: &mut [f64]
) -> Result<(), String>
pub fn get_afe_f_trip( &mut self, afeidx_: &mut [i64], varidx_: &mut [i32], val_: &mut [f64] ) -> Result<(), String>
Obtains the F matrix in triplet format.
§Arguments
afeidx_
Row indices of nonzeros.varidx_
Column indices of nonzeros.val_
Values of nonzero entries.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafeftrip
sourcepub fn get_afe_g(&mut self, afeidx_: i64) -> Result<f64, String>
pub fn get_afe_g(&mut self, afeidx_: i64) -> Result<f64, String>
Obtains a single coefficient in g.
§Arguments
afeidx_
Element index.
§Returns
g
The entry in g.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafeg
sourcepub fn get_afe_g_slice(
&self,
first_: i64,
last_: i64,
g_: &mut [f64]
) -> Result<(), String>
pub fn get_afe_g_slice( &self, first_: i64, last_: i64, g_: &mut [f64] ) -> Result<(), String>
Obtains a sequence of coefficients from the vector g.
§Arguments
first_
First index in the sequence.last_
Last index plus 1 in the sequence.g_
The slice of g as a dense vector.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getafegslice
sourcepub fn get_aij(&self, i_: i32, j_: i32) -> Result<f64, String>
pub fn get_aij(&self, i_: i32, j_: i32) -> Result<f64, String>
Obtains a single coefficient in linear constraint matrix.
§Arguments
i_
Row index of the coefficient to be returned.j_
Column index of the coefficient to be returned.
§Returns
aij
Returns the requested coefficient.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getaij
sourcepub fn get_a_piece_num_nz(
&self,
firsti_: i32,
lasti_: i32,
firstj_: i32,
lastj_: i32
) -> Result<i32, String>
pub fn get_a_piece_num_nz( &self, firsti_: i32, lasti_: i32, firstj_: i32, lastj_: i32 ) -> Result<i32, String>
Obtains the number non-zeros in a rectangular piece of the linear constraint matrix.
§Arguments
firsti_
Index of the first row in the rectangular piece.lasti_
Index of the last row plus one in the rectangular piece.firstj_
Index of the first column in the rectangular piece.lastj_
Index of the last column plus one in the rectangular piece.
§Returns
numnz
Number of non-zero elements in the rectangular piece of the linear constraint matrix.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getapiecenumnz
sourcepub fn get_a_row(
&self,
i_: i32,
nzi_: &mut i32,
subi_: &mut [i32],
vali_: &mut [f64]
) -> Result<(), String>
pub fn get_a_row( &self, i_: i32, nzi_: &mut i32, subi_: &mut [i32], vali_: &mut [f64] ) -> Result<(), String>
Obtains one row of the linear constraint matrix.
§Arguments
i_
Index of the row.nzi_
Number of non-zeros in the row obtained.subi_
Column indices of the non-zeros in the row obtained.vali_
Numerical values of the row obtained.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getarow
sourcepub fn get_a_row_num_nz(&self, i_: i32) -> Result<i32, String>
pub fn get_a_row_num_nz(&self, i_: i32) -> Result<i32, String>
Obtains the number of non-zero elements in one row of the linear constraint matrix
§Arguments
i_
Index of the row.
§Returns
nzi
Number of non-zeros in the i’th row ofA
.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getarownumnz
sourcepub fn get_a_row_slice(
&self,
first_: i32,
last_: i32,
ptrb_: &mut [i64],
ptre_: &mut [i64],
sub_: &mut [i32],
val_: &mut [f64]
) -> Result<(), String>
pub fn get_a_row_slice( &self, first_: i32, last_: i32, ptrb_: &mut [i64], ptre_: &mut [i64], sub_: &mut [i32], val_: &mut [f64] ) -> Result<(), String>
Obtains a sequence of rows from the coefficient matrix.
§Arguments
first_
Index of the first row in the sequence.last_
Index of the last row in the sequence plus one.ptrb_
Row start pointers.ptre_
Row end pointers.sub_
Contains the column subscripts.val_
Contains the coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getarowslice64
sourcepub fn get_a_row_slice_num_nz(
&self,
first_: i32,
last_: i32
) -> Result<i64, String>
pub fn get_a_row_slice_num_nz( &self, first_: i32, last_: i32 ) -> Result<i64, String>
Obtains the number of non-zeros in a slice of rows of the coefficient matrix.
§Arguments
first_
Index of the first row in the sequence.last_
Index of the last row plus one in the sequence.
§Returns
numnz
Number of non-zeros in the slice.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getarowslicenumnz64
sourcepub fn get_a_row_slice_trip(
&self,
first_: i32,
last_: i32,
subi_: &mut [i32],
subj_: &mut [i32],
val_: &mut [f64]
) -> Result<(), String>
pub fn get_a_row_slice_trip( &self, first_: i32, last_: i32, subi_: &mut [i32], subj_: &mut [i32], val_: &mut [f64] ) -> Result<(), String>
Obtains a sequence of rows from the coefficient matrix in sparse triplet format.
§Arguments
first_
Index of the first row in the sequence.last_
Index of the last row in the sequence plus one.subi_
Constraint subscripts.subj_
Column subscripts.val_
Values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getarowslicetrip
sourcepub fn get_a_trip(
&self,
subi_: &mut [i32],
subj_: &mut [i32],
val_: &mut [f64]
) -> Result<(), String>
pub fn get_a_trip( &self, subi_: &mut [i32], subj_: &mut [i32], val_: &mut [f64] ) -> Result<(), String>
Obtains the A matrix in sparse triplet format.
§Arguments
subi_
Constraint subscripts.subj_
Column subscripts.val_
Values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getatrip
sourcepub fn get_a_truncate_tol(&self, tolzero_: &mut [f64]) -> Result<(), String>
pub fn get_a_truncate_tol(&self, tolzero_: &mut [f64]) -> Result<(), String>
Gets the current A matrix truncation threshold.
§Arguments
tolzero_
Truncation tolerance.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getatruncatetol
sourcepub fn get_bara_block_triplet(
&self,
subi_: &mut [i32],
subj_: &mut [i32],
subk_: &mut [i32],
subl_: &mut [i32],
valijkl_: &mut [f64]
) -> Result<i64, String>
pub fn get_bara_block_triplet( &self, subi_: &mut [i32], subj_: &mut [i32], subk_: &mut [i32], subl_: &mut [i32], valijkl_: &mut [f64] ) -> Result<i64, String>
Obtains barA in block triplet form.
§Arguments
subi_
Constraint index.subj_
Symmetric matrix variable index.subk_
Block row index.subl_
Block column index.valijkl_
The numerical value associated with each block triplet.
§Returns
num
Number of elements in the block triplet form.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarablocktriplet
sourcepub fn get_bara_idx(
&self,
idx_: i64,
i_: &mut i32,
j_: &mut i32,
sub_: &mut [i64],
weights_: &mut [f64]
) -> Result<i64, String>
pub fn get_bara_idx( &self, idx_: i64, i_: &mut i32, j_: &mut i32, sub_: &mut [i64], weights_: &mut [f64] ) -> Result<i64, String>
Obtains information about an element in barA.
§Arguments
idx_
Position of the element in the vectorized form.i_
Row index of the element at position idx.j_
Column index of the element at position idx.sub_
A list indexes of the elements from symmetric matrix storage that appear in the weighted sum.weights_
The weights associated with each term in the weighted sum.
§Returns
num
Number of terms in weighted sum that forms the element.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbaraidx
sourcepub fn get_bara_idx_i_j(
&self,
idx_: i64,
i_: &mut i32,
j_: &mut i32
) -> Result<(), String>
pub fn get_bara_idx_i_j( &self, idx_: i64, i_: &mut i32, j_: &mut i32 ) -> Result<(), String>
Obtains information about an element in barA.
§Arguments
idx_
Position of the element in the vectorized form.i_
Row index of the element at position idx.j_
Column index of the element at position idx.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbaraidxij
sourcepub fn get_bara_idx_info(&self, idx_: i64) -> Result<i64, String>
pub fn get_bara_idx_info(&self, idx_: i64) -> Result<i64, String>
Obtains the number of terms in the weighted sum that form a particular element in barA.
§Arguments
idx_
The internal position of the element for which information should be obtained.
§Returns
num
Number of terms in the weighted sum that form the specified element in barA.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbaraidxinfo
sourcepub fn get_bara_sparsity(
&self,
numnz_: &mut i64,
idxij_: &mut [i64]
) -> Result<(), String>
pub fn get_bara_sparsity( &self, numnz_: &mut i64, idxij_: &mut [i64] ) -> Result<(), String>
Obtains the sparsity pattern of the barA matrix.
§Arguments
numnz_
Number of nonzero elements in barA.idxij_
Position of each nonzero element in the vector representation of barA.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarasparsity
sourcepub fn get_barc_block_triplet(
&self,
subj_: &mut [i32],
subk_: &mut [i32],
subl_: &mut [i32],
valjkl_: &mut [f64]
) -> Result<i64, String>
pub fn get_barc_block_triplet( &self, subj_: &mut [i32], subk_: &mut [i32], subl_: &mut [i32], valjkl_: &mut [f64] ) -> Result<i64, String>
Obtains barC in block triplet form.
§Arguments
subj_
Symmetric matrix variable index.subk_
Block row index.subl_
Block column index.valjkl_
The numerical value associated with each block triplet.
§Returns
num
Number of elements in the block triplet form.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarcblocktriplet
sourcepub fn get_barc_idx(
&self,
idx_: i64,
j_: &mut i32,
num_: &mut i64,
sub_: &mut [i64],
weights_: &mut [f64]
) -> Result<(), String>
pub fn get_barc_idx( &self, idx_: i64, j_: &mut i32, num_: &mut i64, sub_: &mut [i64], weights_: &mut [f64] ) -> Result<(), String>
Obtains information about an element in barc.
§Arguments
idx_
Index of the element for which information should be obtained.j_
Row index in barc.num_
Number of terms in the weighted sum.sub_
Elements appearing the weighted sum.weights_
Weights of terms in the weighted sum.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarcidx
sourcepub fn get_barc_idx_info(&self, idx_: i64) -> Result<i64, String>
pub fn get_barc_idx_info(&self, idx_: i64) -> Result<i64, String>
Obtains information about an element in barc.
§Arguments
idx_
Index of the element for which information should be obtained. The value is an index of a symmetric sparse variable.
§Returns
num
Number of terms that appear in the weighted sum that forms the requested element.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarcidxinfo
sourcepub fn get_barc_idx_j(&self, idx_: i64, j_: &mut i32) -> Result<(), String>
pub fn get_barc_idx_j(&self, idx_: i64, j_: &mut i32) -> Result<(), String>
Obtains the row index of an element in barc.
§Arguments
idx_
Index of the element for which information should be obtained.j_
Row index in barc.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarcidxj
sourcepub fn get_barc_sparsity(
&self,
numnz_: &mut i64,
idxj_: &mut [i64]
) -> Result<(), String>
pub fn get_barc_sparsity( &self, numnz_: &mut i64, idxj_: &mut [i64] ) -> Result<(), String>
Get the positions of the nonzero elements in barc.
§Arguments
numnz_
Number of nonzero elements in barc.idxj_
Internal positions of the nonzeros elements in barc.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarcsparsity
sourcepub fn get_bars_j(
&self,
whichsol_: i32,
j_: i32,
barsj_: &mut [f64]
) -> Result<(), String>
pub fn get_bars_j( &self, whichsol_: i32, j_: i32, barsj_: &mut [f64] ) -> Result<(), String>
Obtains the dual solution for a semidefinite variable.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
j_
Index of the semidefinite variable. -
barsj_
Value of the j’th dual variable of barx.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarsj
sourcepub fn get_bars_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
slicesize_: i64,
barsslice_: &mut [f64]
) -> Result<(), String>
pub fn get_bars_slice( &self, whichsol_: i32, first_: i32, last_: i32, slicesize_: i64, barsslice_: &mut [f64] ) -> Result<(), String>
Obtains the dual solution for a sequence of semidefinite variables.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
Index of the first semidefinite variable in the slice. -
last_
Index of the last semidefinite variable in the slice plus one. -
slicesize_
Denotes the length of the array barsslice. -
barsslice_
Dual solution values of symmetric matrix variables in the slice, stored sequentially.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarsslice
sourcepub fn get_barvar_name(&self, i_: i32) -> Result<String, String>
pub fn get_barvar_name(&self, i_: i32) -> Result<String, String>
Obtains the name of a semidefinite variable.
§Arguments
i_
Index of the variable.
§Returns
name
The requested name is copied to this buffer.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarvarname
sourcepub fn get_barvar_name_index(
&self,
somename_: &str,
asgn_: &mut i32
) -> Result<i32, String>
pub fn get_barvar_name_index( &self, somename_: &str, asgn_: &mut i32 ) -> Result<i32, String>
Obtains the index of semidefinite variable from its name.
§Arguments
somename_
The name of the variable.asgn_
Non-zero if the name somename is assigned to some semidefinite variable.
§Returns
index
The index of a semidefinite variable with the name somename (if one exists).
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarvarnameindex
sourcepub fn get_barvar_name_len(&self, i_: i32) -> Result<i32, String>
pub fn get_barvar_name_len(&self, i_: i32) -> Result<i32, String>
Obtains the length of the name of a semidefinite variable.
§Arguments
i_
Index of the variable.
§Returns
len
Returns the length of the indicated name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarvarnamelen
sourcepub fn get_barx_j(
&self,
whichsol_: i32,
j_: i32,
barxj_: &mut [f64]
) -> Result<(), String>
pub fn get_barx_j( &self, whichsol_: i32, j_: i32, barxj_: &mut [f64] ) -> Result<(), String>
Obtains the primal solution for a semidefinite variable.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
j_
Index of the semidefinite variable. -
barxj_
Value of the j’th variable of barx.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarxj
Examples found in repository?
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
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(())
}
More examples
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
fn main() -> Result<(),String> {
/* Input data */
let numcon : i32 = 2; /* Number of constraints. */
let dimbarvar : &[i32] = &[3, 4]; /* Dimension of semidefinite variables */
/* Objective coefficients concatenated */
let Cj : &[i32] = &[ 0, 0, 1, 1, 1, 1 ]; /* Which symmetric variable (j) */
let Ck : &[i32] = &[ 0, 2, 0, 1, 1, 2 ]; /* Which entry (k,l)->v */
let Cl : &[i32] = &[ 0, 2, 0, 0, 1, 2 ];
let Cv : &[f64] = &[ 1.0, 6.0, 1.0, -3.0, 2.0, 1.0 ];
/* Equality constraints coefficients concatenated */
let Ai : &[i32] = &[ 0, 0, 0, 0, 0, 0 ]; /* Which constraint (i = 0) */
let Aj : &[i32] = &[ 0, 0, 0, 1, 1, 1 ]; /* Which symmetric variable (j) */
let Ak : &[i32] = &[ 0, 2, 2, 1, 1, 3 ]; /* Which entry (k,l)->v */
let Al : &[i32] = &[ 0, 0, 2, 0, 1, 3 ];
let Av : &[f64] = &[ 1.0, 1.0, 2.0, 1.0, -1.0, -3.0 ];
/* The second constraint - one-term inequality */
let A2i : &[i32] = &[ 1 ]; /* Which constraint (i = 1) */
let A2j : &[i32] = &[ 1 ]; /* Which symmetric variable (j = 1) */
let A2k : &[i32] = &[ 1 ]; /* Which entry A(1,0) = A(0,1) = 0.5 */
let A2l : &[i32] = &[ 0 ];
let A2v : &[f64] = &[ 0.5 ];
let bkc = &[ mosek::Boundkey::FX,
mosek::Boundkey::UP ];
let blc = &[ 23.0, 0.0 ];
let buc = &[ 23.0, -3.0 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append numcon empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append numbarvar semidefinite variables. */
task.append_barvars(dimbarvar)?;
/* Set objective (6 nonzeros).*/
task.put_barc_block_triplet(Cj, Ck, Cl, Cv)?;
/* Set the equality constraint (6 nonzeros).*/
task.put_bara_block_triplet(Ai, Aj, Ak, Al, Av)?;
/* Set the inequality constraint (1 nonzero).*/
task.put_bara_block_triplet(A2i, A2j, A2k, A2l, A2v)?;
/* Set constraint bounds */
task.put_con_bound_slice(0, 2, bkc, blc, buc)?;
/* Run optimizer */
task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
//mosek.solsta[] solsta = new mosek.solsta[1];
let solsta = task.get_sol_sta (Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
/* Retrieve the soution for all symmetric variables */
println!("Solution (lower triangular part vectorized):");
for (i,dimbarvari) in dimbarvar.iter().enumerate() {
//let dim = dimbarvar[i] * (dimbarvar[i] + 1) / 2;
let dim = dimbarvari * (dimbarvari+1)/2;
//double[] barx = new double[dim];
let mut barx : Vec<f64> = vec![0.0; dim as usize];
task.get_barx_j(Soltype::ITR, i as i32, barx.as_mut_slice())?;
println!("X{}: {:?}",i+1,barx);
// for (int j = 0; j < dim; ++j)
// System.out.print(barx[j] + " ");
// System.out.println();
}
},
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(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
fn main() -> Result<(),String>
{
let dimbarvar = vec![3]; /* Dimension of semidefinite cone */
let bkc = &[ mosek::Boundkey::FX, mosek::Boundkey::FX ];
let blc = &[ 1.0, 0.5 ];
let buc = &[ 1.0, 0.5 ];
let barc_i = &[0, 1, 1, 2, 2];
let barc_j = &[0, 0, 1, 1, 2];
let barc_v = &[2.0, 1.0, 2.0, 1.0, 2.0];
let aptrb = &[0, 1];
let aptre = &[1, 3];
let asub = &[0, 1, 2]; /* column subscripts of A */
let aval = &[1.0, 1.0, 1.0];
let bara_i = &[0, 1, 2, 0, 1, 2, 1, 2, 2];
let bara_j = &[0, 1, 2, 0, 0, 0, 1, 1, 2];
let bara_v = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let falpha = 1.0;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'NUMCON' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Append 'NUMBARVAR' semidefinite variables. */
task.append_barvars(&dimbarvar[..])?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
/* Set the linear term c_j in the objective.*/
task.put_c_j(0,1.0)?;
for j in 0..NUMVAR {
task.put_var_bound(j as i32,
mosek::Boundkey::FR,
-INF,
INF)?;
}
/* Set the linear term barc_j in the objective.*/
let c_symmat_idx = task.append_sparse_sym_mat(dimbarvar[0],
barc_i,
barc_j,
barc_v)?;
task.put_barc_j(0, &[c_symmat_idx], &[falpha])?;
for i in 0..NUMCON
{
/* Input A row by row */
task.put_a_row(i as i32,
& asub[aptrb[i]..aptre[i]],
& aval[aptrb[i]..aptre[i]])?;
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
}
{
/* Append the conic quadratic cone */
let afei = task.get_num_afe()?;
task.append_afes(3)?;
task.put_afe_f_entry_list(&[0,1,2],
&[0,1,2],
&[1.0,1.0,1.0])?;
let dom = task.append_quadratic_cone_domain(3)?;
task.append_acc_seq(dom,afei,&[0.0,0.0,0.0])?;
}
/* Add the first row of barA */
let a_symmat_idx1 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[..3],
& bara_j[..3],
& bara_v[..3])?;
task.put_bara_ij(0, 0, &[a_symmat_idx1][..], &[falpha][..])?;
/* Add the second row of barA */
let a_symmat_idx2 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[3..9],
& bara_j[3..9],
& bara_v[3..9])?;
task.put_bara_ij(1, 0, &[a_symmat_idx2][..], &[falpha][..])?;
let _trmcode = task.optimize()?;
task.write_data("sdo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0,0.0,0.0];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
& mut xx[..])?;
let mut barx = vec![0.0,0.0,0.0,0.0,0.0,0.0];
task.get_barx_j(Soltype::ITR, /* Request the interior solution. */
0,
& mut barx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR as usize
{
println!("x[{}]: {}",j,xx[j]);
}
let n = dimbarvar[0] as usize;
for j in 0..n
{
for i in j..n
{
println!("barx[{},{}]: {}",i,j,barx[j*n+i-j*(j+1)/2]);
}
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN =>
{
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",solsta);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn get_barx_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
slicesize_: i64,
barxslice_: &mut [f64]
) -> Result<(), String>
pub fn get_barx_slice( &self, whichsol_: i32, first_: i32, last_: i32, slicesize_: i64, barxslice_: &mut [f64] ) -> Result<(), String>
Obtains the primal solution for a sequence of semidefinite variables.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
Index of the first semidefinite variable in the slice. -
last_
Index of the last semidefinite variable in the slice plus one. -
slicesize_
Denotes the length of the array barxslice. -
barxslice_
Solution values of symmetric matrix variables in the slice, stored sequentially.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getbarxslice
sourcepub fn get_c(&self, c_: &mut [f64]) -> Result<(), String>
pub fn get_c(&self, c_: &mut [f64]) -> Result<(), String>
Obtains all objective coefficients.
§Arguments
c_
Linear terms of the objective as a dense vector. The length is the number of variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getc
sourcepub fn get_cfix(&self) -> Result<f64, String>
pub fn get_cfix(&self) -> Result<f64, String>
Obtains the fixed term in the objective.
§Returns
cfix
Fixed term in the objective.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getcfix
sourcepub fn get_c_j(&self, j_: i32, cj_: &mut f64) -> Result<(), String>
pub fn get_c_j(&self, j_: i32, cj_: &mut f64) -> Result<(), String>
Obtains one objective coefficient.
§Arguments
j_
Index of the variable for which the c coefficient should be obtained.cj_
The c coefficient value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getcj
sourcepub fn get_c_list(&self, subj_: &[i32], c_: &mut [f64]) -> Result<(), String>
pub fn get_c_list(&self, subj_: &[i32], c_: &mut [f64]) -> Result<(), String>
Obtains a sequence of coefficients from the objective.
§Arguments
subj_
A list of variable indexes.c_
Linear terms of the requested list of the objective as a dense vector.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getclist
sourcepub fn get_con_bound(
&self,
i_: i32,
bk_: &mut i32,
bl_: &mut f64,
bu_: &mut f64
) -> Result<(), String>
pub fn get_con_bound( &self, i_: i32, bk_: &mut i32, bl_: &mut f64, bu_: &mut f64 ) -> Result<(), String>
Obtains bound information for one constraint.
§Arguments
-
i_
Index of the constraint for which the bound information should be obtained. -
bk_
Bound keys.See Boundkey
-
bl_
Values for lower bounds. -
bu_
Values for upper bounds.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getconbound
sourcepub fn get_con_bound_slice(
&self,
first_: i32,
last_: i32,
bk_: &mut [i32],
bl_: &mut [f64],
bu_: &mut [f64]
) -> Result<(), String>
pub fn get_con_bound_slice( &self, first_: i32, last_: i32, bk_: &mut [i32], bl_: &mut [f64], bu_: &mut [f64] ) -> Result<(), String>
Obtains bounds information for a slice of the constraints.
§Arguments
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
bk_
Bound keys.See Boundkey
-
bl_
Values for lower bounds. -
bu_
Values for upper bounds.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getconboundslice
sourcepub fn get_cone(
&mut self,
k_: i32,
ct_: &mut i32,
conepar_: &mut f64,
nummem_: &mut i32,
submem_: &mut [i32]
) -> Result<(), String>
pub fn get_cone( &mut self, k_: i32, ct_: &mut i32, conepar_: &mut f64, nummem_: &mut i32, submem_: &mut [i32] ) -> Result<(), String>
Obtains a cone.
§Arguments
-
k_
Index of the cone. -
ct_
Specifies the type of the cone.See Conetype
-
conepar_
For the power cone it denotes the exponent alpha. For other cone types it is unused and can be set to 0. -
nummem_
Number of member variables in the cone. -
submem_
Variable subscripts of the members in the cone.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getcone
sourcepub fn get_cone_info(
&self,
k_: i32,
ct_: &mut i32,
conepar_: &mut f64,
nummem_: &mut i32
) -> Result<(), String>
pub fn get_cone_info( &self, k_: i32, ct_: &mut i32, conepar_: &mut f64, nummem_: &mut i32 ) -> Result<(), String>
Obtains information about a cone.
§Arguments
-
k_
Index of the cone. -
ct_
Specifies the type of the cone.See Conetype
-
conepar_
For the power cone it denotes the exponent alpha. For other cone types it is unused and can be set to 0. -
nummem_
Number of member variables in the cone.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getconeinfo
sourcepub fn get_cone_name(&self, i_: i32) -> Result<String, String>
pub fn get_cone_name(&self, i_: i32) -> Result<String, String>
Obtains the name of a cone.
§Arguments
i_
Index of the cone.
§Returns
name
The required name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getconename
sourcepub fn get_cone_name_index(
&self,
somename_: &str,
asgn_: &mut i32
) -> Result<i32, String>
pub fn get_cone_name_index( &self, somename_: &str, asgn_: &mut i32 ) -> Result<i32, String>
Checks whether the name has been assigned to any cone.
§Arguments
somename_
The name which should be checked.asgn_
Is non-zero if the name somename is assigned to some cone.
§Returns
index
If the name somename is assigned to some cone, this is the index of the cone.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getconenameindex
sourcepub fn get_cone_name_len(&self, i_: i32) -> Result<i32, String>
pub fn get_cone_name_len(&self, i_: i32) -> Result<i32, String>
Obtains the length of the name of a cone.
§Arguments
i_
Index of the cone.
§Returns
len
Returns the length of the indicated name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getconenamelen
sourcepub fn get_con_name(&self, i_: i32) -> Result<String, String>
pub fn get_con_name(&self, i_: i32) -> Result<String, String>
Obtains the name of a constraint.
§Arguments
i_
Index of the constraint.
§Returns
name
The required name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getconname
sourcepub fn get_con_name_index(
&self,
somename_: &str,
asgn_: &mut i32
) -> Result<i32, String>
pub fn get_con_name_index( &self, somename_: &str, asgn_: &mut i32 ) -> Result<i32, String>
Checks whether the name has been assigned to any constraint.
§Arguments
somename_
The name which should be checked.asgn_
Is non-zero if the name somename is assigned to some constraint.
§Returns
index
If the name somename is assigned to a constraint, then return the index of the constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getconnameindex
sourcepub fn get_con_name_len(&self, i_: i32) -> Result<i32, String>
pub fn get_con_name_len(&self, i_: i32) -> Result<i32, String>
Obtains the length of the name of a constraint.
§Arguments
i_
Index of the constraint.
§Returns
len
Returns the length of the indicated name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getconnamelen
sourcepub fn get_c_slice(
&self,
first_: i32,
last_: i32,
c_: &mut [f64]
) -> Result<(), String>
pub fn get_c_slice( &self, first_: i32, last_: i32, c_: &mut [f64] ) -> Result<(), String>
Obtains a sequence of coefficients from the objective.
§Arguments
first_
First index in the sequence.last_
Last index plus 1 in the sequence.c_
Linear terms of the requested slice of the objective as a dense vector.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getcslice
sourcepub fn get_dim_barvar_j(&self, j_: i32) -> Result<i32, String>
pub fn get_dim_barvar_j(&self, j_: i32) -> Result<i32, String>
Obtains the dimension of a symmetric matrix variable.
§Arguments
j_
Index of the semidefinite variable whose dimension is requested.
§Returns
dimbarvarj
The dimension of the j’th semidefinite variable.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdimbarvarj
sourcepub fn get_djc_afe_idx_list(
&self,
djcidx_: i64,
afeidxlist_: &mut [i64]
) -> Result<(), String>
pub fn get_djc_afe_idx_list( &self, djcidx_: i64, afeidxlist_: &mut [i64] ) -> Result<(), String>
Obtains the list of affine expression indexes in a disjunctive constraint.
§Arguments
djcidx_
Index of the disjunctive constraint.afeidxlist_
List of affine expression indexes.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcafeidxlist
sourcepub fn get_djc_b(&self, djcidx_: i64, b_: &mut [f64]) -> Result<(), String>
pub fn get_djc_b(&self, djcidx_: i64, b_: &mut [f64]) -> Result<(), String>
Obtains the optional constant term vector of a disjunctive constraint.
§Arguments
djcidx_
Index of the disjunctive constraint.b_
The vector b.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcb
sourcepub fn get_djc_domain_idx_list(
&self,
djcidx_: i64,
domidxlist_: &mut [i64]
) -> Result<(), String>
pub fn get_djc_domain_idx_list( &self, djcidx_: i64, domidxlist_: &mut [i64] ) -> Result<(), String>
Obtains the list of domain indexes in a disjunctive constraint.
§Arguments
djcidx_
Index of the disjunctive constraint.domidxlist_
List of term sizes.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcdomainidxlist
sourcepub fn get_djc_name(&self, djcidx_: i64) -> Result<String, String>
pub fn get_djc_name(&self, djcidx_: i64) -> Result<String, String>
Obtains the name of a disjunctive constraint.
§Arguments
djcidx_
Index of a disjunctive constraint.
§Returns
name
Returns the required name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcname
sourcepub fn get_djc_name_len(&self, djcidx_: i64) -> Result<i32, String>
pub fn get_djc_name_len(&self, djcidx_: i64) -> Result<i32, String>
Obtains the length of the name of a disjunctive constraint.
§Arguments
djcidx_
Index of a disjunctive constraint.
§Returns
len
Returns the length of the indicated name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcnamelen
sourcepub fn get_djc_num_afe(&mut self, djcidx_: i64) -> Result<i64, String>
pub fn get_djc_num_afe(&mut self, djcidx_: i64) -> Result<i64, String>
Obtains the number of affine expressions in the disjunctive constraint.
§Arguments
djcidx_
Index of the disjunctive constraint.
§Returns
numafe
Number of affine expressions in the disjunctive constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcnumafe
sourcepub fn get_djc_num_afe_tot(&mut self) -> Result<i64, String>
pub fn get_djc_num_afe_tot(&mut self) -> Result<i64, String>
Obtains the number of affine expressions in all disjunctive constraints.
§Returns
numafetot
Number of affine expressions in all disjunctive constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcnumafetot
sourcepub fn get_djc_num_domain(&mut self, djcidx_: i64) -> Result<i64, String>
pub fn get_djc_num_domain(&mut self, djcidx_: i64) -> Result<i64, String>
Obtains the number of domains in the disjunctive constraint.
§Arguments
djcidx_
Index of the disjunctive constraint.
§Returns
numdomain
Number of domains in the disjunctive constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcnumdomain
sourcepub fn get_djc_num_domain_tot(&mut self) -> Result<i64, String>
pub fn get_djc_num_domain_tot(&mut self) -> Result<i64, String>
Obtains the number of domains in all disjunctive constraints.
§Returns
numdomaintot
Number of domains in all disjunctive constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcnumdomaintot
sourcepub fn get_djc_num_term(&mut self, djcidx_: i64) -> Result<i64, String>
pub fn get_djc_num_term(&mut self, djcidx_: i64) -> Result<i64, String>
Obtains the number terms in the disjunctive constraint.
§Arguments
djcidx_
Index of the disjunctive constraint.
§Returns
numterm
Number of terms in the disjunctive constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcnumterm
sourcepub fn get_djc_num_term_tot(&mut self) -> Result<i64, String>
pub fn get_djc_num_term_tot(&mut self) -> Result<i64, String>
Obtains the number of terms in all disjunctive constraints.
§Returns
numtermtot
Total number of terms in all disjunctive constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcnumtermtot
sourcepub fn get_djcs(
&self,
domidxlist_: &mut [i64],
afeidxlist_: &mut [i64],
b_: &mut [f64],
termsizelist_: &mut [i64],
numterms_: &mut [i64]
) -> Result<(), String>
pub fn get_djcs( &self, domidxlist_: &mut [i64], afeidxlist_: &mut [i64], b_: &mut [f64], termsizelist_: &mut [i64], numterms_: &mut [i64] ) -> Result<(), String>
Obtains full data of all disjunctive constraints.
§Arguments
domidxlist_
The concatenation of index lists of domains appearing in all disjunctive constraints.afeidxlist_
The concatenation of index lists of affine expressions appearing in all disjunctive constraints.b_
The concatenation of vectors b appearing in all disjunctive constraints.termsizelist_
The concatenation of lists of term sizes appearing in all disjunctive constraints.numterms_
The number of terms in each of the disjunctive constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjcs
sourcepub fn get_djc_term_size_list(
&self,
djcidx_: i64,
termsizelist_: &mut [i64]
) -> Result<(), String>
pub fn get_djc_term_size_list( &self, djcidx_: i64, termsizelist_: &mut [i64] ) -> Result<(), String>
Obtains the list of term sizes in a disjunctive constraint.
§Arguments
djcidx_
Index of the disjunctive constraint.termsizelist_
List of term sizes.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdjctermsizelist
sourcepub fn get_domain_n(&self, domidx_: i64) -> Result<i64, String>
pub fn get_domain_n(&self, domidx_: i64) -> Result<i64, String>
Obtains the dimension of the domain.
§Arguments
domidx_
Index of the domain.
§Returns
n
Dimension of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdomainn
sourcepub fn get_domain_name(&self, domidx_: i64) -> Result<String, String>
pub fn get_domain_name(&self, domidx_: i64) -> Result<String, String>
Obtains the name of a domain.
§Arguments
domidx_
Index of a domain.
§Returns
name
Returns the required name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdomainname
sourcepub fn get_domain_name_len(&self, domidx_: i64) -> Result<i32, String>
pub fn get_domain_name_len(&self, domidx_: i64) -> Result<i32, String>
Obtains the length of the name of a domain.
§Arguments
domidx_
Index of a domain.
§Returns
len
Returns the length of the indicated name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdomainnamelen
sourcepub fn get_domain_type(&self, domidx_: i64) -> Result<i32, String>
pub fn get_domain_type(&self, domidx_: i64) -> Result<i32, String>
Returns the type of the domain.
§Arguments
domidx_
Index of the domain.
§Returns
domtype
The type of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdomaintype
sourcepub fn get_dou_inf(&self, whichdinf_: i32) -> Result<f64, String>
pub fn get_dou_inf(&self, whichdinf_: i32) -> Result<f64, String>
Obtains a double information item.
§Arguments
-
whichdinf_
Specifies a double information item.See Dinfitem
§Returns
dvalue
The value of the required double information item.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdouinf
Examples found in repository?
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
fn feasrepairex1(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
match filename {
FileOrText::File(fname) => task.read_data(fname.as_str())?,
FileOrText::Text(data) => task.read_lp_string(data.as_str())?
}
task.put_int_param(mosek::Iparam::LOG_FEAS_REPAIR, 3)?;
let wc = vec![1.0; task.get_num_con()? as usize];
let wx = vec![1.0; task.get_num_var()? as usize];
task.primal_repair(wc.as_slice(),wc.as_slice(),wx.as_slice(),wx.as_slice())?;
let sum_viol = task.get_dou_inf(mosek::Dinfitem::PRIMAL_REPAIR_PENALTY_OBJ)?;
println!("Minimized sum of violations = {}", sum_viol);
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::MSG)?;
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
let numvar : i32 = 4;
let numcon : i32 = 1;
let c = &[ 7.0, 10.0, 1.0, 5.0 ];
let bkc = &[Boundkey::UP];
let blc = &[ -INF ];
let buc = &[2.5];
let bkx = &[Boundkey::LO,
Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = &[0.0,
0.0,
0.0,
0.0 ];
let bux = &[INF,
INF,
INF,
INF];
let ptrb = &[0i64, 1, 2, 3];
let ptre = &[1i64, 2, 3, 4];
let aval = &[1.0, 1.0, 1.0, 1.0];
let asub = &[0i32, 0, 0, 0 ];
let intsub = &[0i32, 1, 2];
let inttype = &[Variabletype::TYPE_INT,
Variabletype::TYPE_INT,
Variabletype::TYPE_INT ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon, numvar,
c, 0.0,
ptrb, ptre,
asub, aval,
bkc, blc, buc,
bkx, blx, bux)?;
task.put_var_type_list(intsub, inttype)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MAXIMIZE)?;
// Assign values to integer variables
// We only set that slice of xx
task.put_xx_slice(Soltype::ITG, 0, 3, &[1.0,1.0,0.0])?;
// Request constructing the solution from integer variable values
task.put_int_param(mosek::Iparam::MIO_CONSTRUCT_SOL, mosek::Onoffkey::ON)?;
// solve
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::LOG)?;
// Read and print solution
let mut xx = vec![0.0; numvar as usize];
task.get_xx(mosek::Soltype::ITG, xx.as_mut_slice())?;
println!("Optimal solution:");
for (i,xi) in xx.iter().enumerate() {
println!("x[{}] = {}",i,*xi);
}
// Was the initial solution used?
let constr = task.get_int_inf(mosek::Iinfitem::MIO_CONSTRUCT_SOLUTION)?;
let constr_val = task.get_dou_inf(mosek::Dinfitem::MIO_CONSTRUCT_SOLUTION_OBJ)?;
println!("Construct solution utilization: {}", constr);
println!("Construct solution objective: {}", constr_val);
Ok(())
}
sourcepub fn get_dou_param(&self, param_: i32) -> Result<f64, String>
pub fn get_dou_param(&self, param_: i32) -> Result<f64, String>
Obtains a double parameter.
§Arguments
-
param_
Which parameter.See Dparam
§Returns
parvalue
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdouparam
sourcepub fn get_dual_obj(
&self,
whichsol_: i32,
dualobj_: &mut f64
) -> Result<(), String>
pub fn get_dual_obj( &self, whichsol_: i32, dualobj_: &mut f64 ) -> Result<(), String>
Computes the dual objective value associated with the solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
dualobj_
Objective value corresponding to the dual solution.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdualobj
sourcepub fn get_dual_solution_norms(
&self,
whichsol_: i32,
nrmy_: &mut f64,
nrmslc_: &mut f64,
nrmsuc_: &mut f64,
nrmslx_: &mut f64,
nrmsux_: &mut f64,
nrmsnx_: &mut f64,
nrmbars_: &mut f64
) -> Result<(), String>
pub fn get_dual_solution_norms( &self, whichsol_: i32, nrmy_: &mut f64, nrmslc_: &mut f64, nrmsuc_: &mut f64, nrmslx_: &mut f64, nrmsux_: &mut f64, nrmsnx_: &mut f64, nrmbars_: &mut f64 ) -> Result<(), String>
Compute norms of the dual solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
nrmy_
The norm of the y vector. -
nrmslc_
The norm of the slc vector. -
nrmsuc_
The norm of the suc vector. -
nrmslx_
The norm of the slx vector. -
nrmsux_
The norm of the sux vector. -
nrmsnx_
The norm of the snx vector. -
nrmbars_
The norm of the bars vector.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdualsolutionnorms
sourcepub fn get_dviol_acc(
&self,
whichsol_: i32,
accidxlist_: &[i64],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_dviol_acc( &self, whichsol_: i32, accidxlist_: &[i64], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of the dual solution for set of affine conic constraints.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
accidxlist_
An array of indexes of conic constraints. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdviolacc
sourcepub fn get_dviol_barvar(
&self,
whichsol_: i32,
sub_: &[i32],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_dviol_barvar( &self, whichsol_: i32, sub_: &[i32], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of dual solution for a set of semidefinite variables.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sub_
An array of indexes of barx variables. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdviolbarvar
sourcepub fn get_dviol_con(
&self,
whichsol_: i32,
sub_: &[i32],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_dviol_con( &self, whichsol_: i32, sub_: &[i32], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of a dual solution associated with a set of constraints.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sub_
An array of indexes of constraints. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdviolcon
sourcepub fn get_dviol_cones(
&self,
whichsol_: i32,
sub_: &[i32],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_dviol_cones( &self, whichsol_: i32, sub_: &[i32], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of a solution for set of dual conic constraints.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sub_
An array of indexes of conic constraints. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdviolcones
sourcepub fn get_dviol_var(
&self,
whichsol_: i32,
sub_: &[i32],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_dviol_var( &self, whichsol_: i32, sub_: &[i32], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of a dual solution associated with a set of scalar variables.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sub_
An array of indexes of x variables. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getdviolvar
sourcepub fn get_inf_index(
&self,
inftype_: i32,
infname_: &str,
infindex_: &mut i32
) -> Result<(), String>
pub fn get_inf_index( &self, inftype_: i32, infname_: &str, infindex_: &mut i32 ) -> Result<(), String>
Obtains the index of a named information item.
§Arguments
-
inftype_
Type of the information item.See Inftype
-
infname_
Name of the information item. -
infindex_
The item index.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getinfindex
sourcepub fn get_inf_max(
&self,
inftype_: i32,
infmax_: &mut [i32]
) -> Result<(), String>
pub fn get_inf_max( &self, inftype_: i32, infmax_: &mut [i32] ) -> Result<(), String>
Obtains the maximum index of an information item of a given type.
§Arguments
-
inftype_
Type of the information item.See Inftype
-
infmax_
The maximum index (plus 1) requested.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getinfmax
sourcepub fn get_inf_name(
&self,
inftype_: i32,
whichinf_: i32
) -> Result<String, String>
pub fn get_inf_name( &self, inftype_: i32, whichinf_: i32 ) -> Result<String, String>
Obtains the name of an information item.
§Arguments
-
inftype_
Type of the information item.See Inftype
-
whichinf_
An information item.
§Returns
infname
Name of the information item.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getinfname
sourcepub fn get_int_inf(&self, whichiinf_: i32) -> Result<i32, String>
pub fn get_int_inf(&self, whichiinf_: i32) -> Result<i32, String>
Obtains an integer information item.
§Arguments
-
whichiinf_
Specifies an integer information item.See Iinfitem
§Returns
ivalue
The value of the required integer information item.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getintinf
Examples found in repository?
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
fn main() -> Result<(),String> {
let numvar : i32 = 4;
let numcon : i32 = 1;
let c = &[ 7.0, 10.0, 1.0, 5.0 ];
let bkc = &[Boundkey::UP];
let blc = &[ -INF ];
let buc = &[2.5];
let bkx = &[Boundkey::LO,
Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = &[0.0,
0.0,
0.0,
0.0 ];
let bux = &[INF,
INF,
INF,
INF];
let ptrb = &[0i64, 1, 2, 3];
let ptre = &[1i64, 2, 3, 4];
let aval = &[1.0, 1.0, 1.0, 1.0];
let asub = &[0i32, 0, 0, 0 ];
let intsub = &[0i32, 1, 2];
let inttype = &[Variabletype::TYPE_INT,
Variabletype::TYPE_INT,
Variabletype::TYPE_INT ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon, numvar,
c, 0.0,
ptrb, ptre,
asub, aval,
bkc, blc, buc,
bkx, blx, bux)?;
task.put_var_type_list(intsub, inttype)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MAXIMIZE)?;
// Assign values to integer variables
// We only set that slice of xx
task.put_xx_slice(Soltype::ITG, 0, 3, &[1.0,1.0,0.0])?;
// Request constructing the solution from integer variable values
task.put_int_param(mosek::Iparam::MIO_CONSTRUCT_SOL, mosek::Onoffkey::ON)?;
// solve
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::LOG)?;
// Read and print solution
let mut xx = vec![0.0; numvar as usize];
task.get_xx(mosek::Soltype::ITG, xx.as_mut_slice())?;
println!("Optimal solution:");
for (i,xi) in xx.iter().enumerate() {
println!("x[{}] = {}",i,*xi);
}
// Was the initial solution used?
let constr = task.get_int_inf(mosek::Iinfitem::MIO_CONSTRUCT_SOLUTION)?;
let constr_val = task.get_dou_inf(mosek::Dinfitem::MIO_CONSTRUCT_SOLUTION_OBJ)?;
println!("Construct solution utilization: {}", constr);
println!("Construct solution objective: {}", constr_val);
Ok(())
}
sourcepub fn get_int_param(&self, param_: i32) -> Result<i32, String>
pub fn get_int_param(&self, param_: i32) -> Result<i32, String>
Obtains an integer parameter.
§Arguments
-
param_
Which parameter.See Iparam
§Returns
parvalue
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getintparam
sourcepub fn get_len_barvar_j(&self, j_: i32) -> Result<i64, String>
pub fn get_len_barvar_j(&self, j_: i32) -> Result<i64, String>
Obtains the length of one semidefinite variable.
§Arguments
j_
Index of the semidefinite variable whose length if requested.
§Returns
lenbarvarj
Number of scalar elements in the lower triangular part of the semidefinite variable.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getlenbarvarj
sourcepub fn get_lint_inf(&self, whichliinf_: i32) -> Result<i64, String>
pub fn get_lint_inf(&self, whichliinf_: i32) -> Result<i64, String>
Obtains a long integer information item.
§Arguments
-
whichliinf_
Specifies a long information item.See Liinfitem
§Returns
ivalue
The value of the required long integer information item.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getlintinf
sourcepub fn get_max_name_len(&self, maxlen_: &mut i32) -> Result<(), String>
pub fn get_max_name_len(&self, maxlen_: &mut i32) -> Result<(), String>
Obtains the maximum length (not including terminating zero character) of any objective, constraint, variable, domain or cone name.
§Arguments
maxlen_
The maximum length of any name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getmaxnamelen
sourcepub fn get_max_num_a_nz(&self) -> Result<i64, String>
pub fn get_max_num_a_nz(&self) -> Result<i64, String>
Obtains number of preallocated non-zeros in the linear constraint matrix.
§Returns
maxnumanz
Number of preallocated non-zero linear matrix elements.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getmaxnumanz64
sourcepub fn get_max_num_barvar(&self) -> Result<i32, String>
pub fn get_max_num_barvar(&self) -> Result<i32, String>
Obtains maximum number of symmetric matrix variables for which space is currently preallocated.
§Returns
maxnumbarvar
Maximum number of symmetric matrix variables for which space is currently preallocated.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getmaxnumbarvar
sourcepub fn get_max_num_con(&self, maxnumcon_: &mut i32) -> Result<(), String>
pub fn get_max_num_con(&self, maxnumcon_: &mut i32) -> Result<(), String>
Obtains the number of preallocated constraints in the optimization task.
§Arguments
maxnumcon_
Number of preallocated constraints in the optimization task.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getmaxnumcon
sourcepub fn get_max_num_cone(&self, maxnumcone_: &mut i32) -> Result<(), String>
pub fn get_max_num_cone(&self, maxnumcone_: &mut i32) -> Result<(), String>
Obtains the number of preallocated cones in the optimization task.
§Arguments
maxnumcone_
Number of preallocated conic constraints in the optimization task.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getmaxnumcone
sourcepub fn get_max_num_q_nz(&self, maxnumqnz_: &mut i64) -> Result<(), String>
pub fn get_max_num_q_nz(&self, maxnumqnz_: &mut i64) -> Result<(), String>
Obtains the number of preallocated non-zeros for all quadratic terms in objective and constraints.
§Arguments
maxnumqnz_
Number of non-zero elements preallocated in quadratic coefficient matrices.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getmaxnumqnz64
sourcepub fn get_max_num_var(&self, maxnumvar_: &mut i32) -> Result<(), String>
pub fn get_max_num_var(&self, maxnumvar_: &mut i32) -> Result<(), String>
Obtains the maximum number variables allowed.
§Arguments
maxnumvar_
Number of preallocated variables in the optimization task.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getmaxnumvar
sourcepub fn get_mem_usage(
&self,
meminuse_: &mut i64,
maxmemuse_: &mut i64
) -> Result<(), String>
pub fn get_mem_usage( &self, meminuse_: &mut i64, maxmemuse_: &mut i64 ) -> Result<(), String>
Obtains information about the amount of memory used by a task.
§Arguments
meminuse_
Amount of memory currently used by the task.maxmemuse_
Maximum amount of memory used by the task until now.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getmemusagetask
sourcepub fn get_mio_num_threads(&self) -> Result<i32, String>
pub fn get_mio_num_threads(&self) -> Result<i32, String>
Obtains the number of threads used by the mixed integer optimizer.
§Returns
numthreads
The number of threads.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getmionumthreads
sourcepub fn get_na_dou_inf(
&self,
infitemname_: &str,
dvalue_: &mut f64
) -> Result<(), String>
pub fn get_na_dou_inf( &self, infitemname_: &str, dvalue_: &mut f64 ) -> Result<(), String>
Obtains a named double information item.
§Arguments
infitemname_
The name of a double information item.dvalue_
The value of the required double information item.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnadouinf
sourcepub fn get_na_dou_param(
&self,
paramname_: &str,
parvalue_: &mut f64
) -> Result<(), String>
pub fn get_na_dou_param( &self, paramname_: &str, parvalue_: &mut f64 ) -> Result<(), String>
Obtains a double parameter.
§Arguments
paramname_
Name of a parameter.parvalue_
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnadouparam
sourcepub fn get_na_int_inf(
&self,
infitemname_: &str,
ivalue_: &mut i32
) -> Result<(), String>
pub fn get_na_int_inf( &self, infitemname_: &str, ivalue_: &mut i32 ) -> Result<(), String>
Obtains a named integer information item.
§Arguments
infitemname_
The name of an integer information item.ivalue_
The value of the required integer information item.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnaintinf
sourcepub fn get_na_int_param(
&self,
paramname_: &str,
parvalue_: &mut i32
) -> Result<(), String>
pub fn get_na_int_param( &self, paramname_: &str, parvalue_: &mut i32 ) -> Result<(), String>
Obtains an integer parameter.
§Arguments
paramname_
Name of a parameter.parvalue_
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnaintparam
sourcepub fn get_na_str_param(
&self,
paramname_: &str,
sizeparamname_: i32,
len_: &mut i32
) -> Result<String, String>
pub fn get_na_str_param( &self, paramname_: &str, sizeparamname_: i32, len_: &mut i32 ) -> Result<String, String>
Obtains a string parameter.
§Arguments
paramname_
Name of a parameter.sizeparamname_
Size of the name buffer.len_
Returns the length of the parameter value.
§Returns
parvalue
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnastrparam
sourcepub fn get_num_acc(&mut self) -> Result<i64, String>
pub fn get_num_acc(&mut self) -> Result<i64, String>
Obtains the number of affine conic constraints.
§Returns
num
The number of affine conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumacc
Examples found in repository?
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
More examples
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 129 130
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn get_num_afe(&mut self) -> Result<i64, String>
pub fn get_num_afe(&mut self) -> Result<i64, String>
Obtains the number of affine expressions.
§Returns
numafe
Number of affine expressions.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumafe
Examples found in repository?
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
More examples
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
// Model logistic regression (regularized with full 2-norm of theta)
// X - n x d matrix of data points
// y - length n vector classifying training points
// lamb - regularization parameter
#[allow(non_snake_case)]
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
fn main() -> Result<(),String>
{
let dimbarvar = vec![3]; /* Dimension of semidefinite cone */
let bkc = &[ mosek::Boundkey::FX, mosek::Boundkey::FX ];
let blc = &[ 1.0, 0.5 ];
let buc = &[ 1.0, 0.5 ];
let barc_i = &[0, 1, 1, 2, 2];
let barc_j = &[0, 0, 1, 1, 2];
let barc_v = &[2.0, 1.0, 2.0, 1.0, 2.0];
let aptrb = &[0, 1];
let aptre = &[1, 3];
let asub = &[0, 1, 2]; /* column subscripts of A */
let aval = &[1.0, 1.0, 1.0];
let bara_i = &[0, 1, 2, 0, 1, 2, 1, 2, 2];
let bara_j = &[0, 1, 2, 0, 0, 0, 1, 1, 2];
let bara_v = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let falpha = 1.0;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'NUMCON' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Append 'NUMBARVAR' semidefinite variables. */
task.append_barvars(&dimbarvar[..])?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
/* Set the linear term c_j in the objective.*/
task.put_c_j(0,1.0)?;
for j in 0..NUMVAR {
task.put_var_bound(j as i32,
mosek::Boundkey::FR,
-INF,
INF)?;
}
/* Set the linear term barc_j in the objective.*/
let c_symmat_idx = task.append_sparse_sym_mat(dimbarvar[0],
barc_i,
barc_j,
barc_v)?;
task.put_barc_j(0, &[c_symmat_idx], &[falpha])?;
for i in 0..NUMCON
{
/* Input A row by row */
task.put_a_row(i as i32,
& asub[aptrb[i]..aptre[i]],
& aval[aptrb[i]..aptre[i]])?;
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
}
{
/* Append the conic quadratic cone */
let afei = task.get_num_afe()?;
task.append_afes(3)?;
task.put_afe_f_entry_list(&[0,1,2],
&[0,1,2],
&[1.0,1.0,1.0])?;
let dom = task.append_quadratic_cone_domain(3)?;
task.append_acc_seq(dom,afei,&[0.0,0.0,0.0])?;
}
/* Add the first row of barA */
let a_symmat_idx1 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[..3],
& bara_j[..3],
& bara_v[..3])?;
task.put_bara_ij(0, 0, &[a_symmat_idx1][..], &[falpha][..])?;
/* Add the second row of barA */
let a_symmat_idx2 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[3..9],
& bara_j[3..9],
& bara_v[3..9])?;
task.put_bara_ij(1, 0, &[a_symmat_idx2][..], &[falpha][..])?;
let _trmcode = task.optimize()?;
task.write_data("sdo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0,0.0,0.0];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
& mut xx[..])?;
let mut barx = vec![0.0,0.0,0.0,0.0,0.0,0.0];
task.get_barx_j(Soltype::ITR, /* Request the interior solution. */
0,
& mut barx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR as usize
{
println!("x[{}]: {}",j,xx[j]);
}
let n = dimbarvar[0] as usize;
for j in 0..n
{
for i in j..n
{
println!("barx[{},{}]: {}",i,j,barx[j*n+i-j*(j+1)/2]);
}
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN =>
{
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",solsta);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn get_num_a_nz(&self) -> Result<i32, String>
pub fn get_num_a_nz(&self) -> Result<i32, String>
Obtains the number of non-zeros in the coefficient matrix.
§Returns
numanz
Number of non-zero elements in the linear constraint matrix.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumanz
sourcepub fn get_num_a_nz_64(&self) -> Result<i64, String>
pub fn get_num_a_nz_64(&self) -> Result<i64, String>
Obtains the number of non-zeros in the coefficient matrix.
§Returns
numanz
Number of non-zero elements in the linear constraint matrix.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumanz64
sourcepub fn get_num_bara_block_triplets(&self) -> Result<i64, String>
pub fn get_num_bara_block_triplets(&self) -> Result<i64, String>
Obtains an upper bound on the number of scalar elements in the block triplet form of bara.
§Returns
num
An upper bound on the number of elements in the block triplet form of bara.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumbarablocktriplets
sourcepub fn get_num_bara_nz(&self) -> Result<i64, String>
pub fn get_num_bara_nz(&self) -> Result<i64, String>
Get the number of nonzero elements in barA.
§Returns
nz
The number of nonzero block elements in barA.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumbaranz
sourcepub fn get_num_barc_block_triplets(&self) -> Result<i64, String>
pub fn get_num_barc_block_triplets(&self) -> Result<i64, String>
Obtains an upper bound on the number of elements in the block triplet form of barc.
§Returns
num
An upper bound on the number of elements in the block triplet form of barc.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumbarcblocktriplets
sourcepub fn get_num_barc_nz(&self) -> Result<i64, String>
pub fn get_num_barc_nz(&self) -> Result<i64, String>
Obtains the number of nonzero elements in barc.
§Returns
nz
The number of nonzero elements in barc.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumbarcnz
sourcepub fn get_num_barvar(&self) -> Result<i32, String>
pub fn get_num_barvar(&self) -> Result<i32, String>
Obtains the number of semidefinite variables.
§Returns
numbarvar
Number of semidefinite variables in the problem.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumbarvar
sourcepub fn get_num_con(&self) -> Result<i32, String>
pub fn get_num_con(&self) -> Result<i32, String>
Obtains the number of constraints.
§Returns
numcon
Number of constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumcon
Examples found in repository?
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
fn feasrepairex1(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
match filename {
FileOrText::File(fname) => task.read_data(fname.as_str())?,
FileOrText::Text(data) => task.read_lp_string(data.as_str())?
}
task.put_int_param(mosek::Iparam::LOG_FEAS_REPAIR, 3)?;
let wc = vec![1.0; task.get_num_con()? as usize];
let wx = vec![1.0; task.get_num_var()? as usize];
task.primal_repair(wc.as_slice(),wc.as_slice(),wx.as_slice(),wx.as_slice())?;
let sum_viol = task.get_dou_inf(mosek::Dinfitem::PRIMAL_REPAIR_PENALTY_OBJ)?;
println!("Minimized sum of violations = {}", sum_viol);
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::MSG)?;
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
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 129 130
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn get_num_cone(&self) -> Result<i32, String>
pub fn get_num_cone(&self) -> Result<i32, String>
Obtains the number of cones.
§Returns
numcone
Number of conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumcone
sourcepub fn get_num_cone_mem(&self, k_: i32, nummem_: &mut i32) -> Result<(), String>
pub fn get_num_cone_mem(&self, k_: i32, nummem_: &mut i32) -> Result<(), String>
Obtains the number of members in a cone.
§Arguments
k_
Index of the cone.nummem_
Number of member variables in the cone.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumconemem
sourcepub fn get_num_djc(&mut self) -> Result<i64, String>
pub fn get_num_djc(&mut self) -> Result<i64, String>
Obtains the number of disjunctive constraints.
§Returns
num
The number of disjunctive constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumdjc
sourcepub fn get_num_domain(&mut self) -> Result<i64, String>
pub fn get_num_domain(&mut self) -> Result<i64, String>
Obtain the number of domains defined.
§Returns
numdomain
Number of domains in the task.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumdomain
sourcepub fn get_num_int_var(&self) -> Result<i32, String>
pub fn get_num_int_var(&self) -> Result<i32, String>
Obtains the number of integer-constrained variables.
§Returns
numintvar
Number of integer variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumintvar
sourcepub fn get_num_param(
&self,
partype_: i32,
numparam_: &mut i32
) -> Result<(), String>
pub fn get_num_param( &self, partype_: i32, numparam_: &mut i32 ) -> Result<(), String>
Obtains the number of parameters of a given type.
§Arguments
-
partype_
Parameter type.See Parametertype
-
numparam_
Returns the number of parameters of the requested type.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumparam
sourcepub fn get_num_q_con_k_nz(&self, k_: i32) -> Result<i64, String>
pub fn get_num_q_con_k_nz(&self, k_: i32) -> Result<i64, String>
Obtains the number of non-zero quadratic terms in a constraint.
§Arguments
k_
Index of the constraint for which the number quadratic terms should be obtained.
§Returns
numqcnz
Number of quadratic terms.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumqconknz64
sourcepub fn get_num_q_obj_nz(&self) -> Result<i64, String>
pub fn get_num_q_obj_nz(&self) -> Result<i64, String>
Obtains the number of non-zero quadratic terms in the objective.
§Returns
numqonz
Number of non-zero elements in the quadratic objective terms.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumqobjnz64
sourcepub fn get_num_sym_mat(&self, num_: &mut i64) -> Result<(), String>
pub fn get_num_sym_mat(&self, num_: &mut i64) -> Result<(), String>
Obtains the number of symmetric matrices stored.
§Arguments
num_
The number of symmetric sparse matrices.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumsymmat
sourcepub fn get_num_var(&self) -> Result<i32, String>
pub fn get_num_var(&self) -> Result<i32, String>
Obtains the number of variables.
§Returns
numvar
Number of variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getnumvar
Examples found in repository?
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
fn feasrepairex1(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
match filename {
FileOrText::File(fname) => task.read_data(fname.as_str())?,
FileOrText::Text(data) => task.read_lp_string(data.as_str())?
}
task.put_int_param(mosek::Iparam::LOG_FEAS_REPAIR, 3)?;
let wc = vec![1.0; task.get_num_con()? as usize];
let wx = vec![1.0; task.get_num_var()? as usize];
task.primal_repair(wc.as_slice(),wc.as_slice(),wx.as_slice(),wx.as_slice())?;
let sum_viol = task.get_dou_inf(mosek::Dinfitem::PRIMAL_REPAIR_PENALTY_OBJ)?;
println!("Minimized sum of violations = {}", sum_viol);
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::MSG)?;
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
let args: Vec<String> = env::args().collect();
let mut task = Task::new().unwrap().with_callbacks();
if args.len() < 2 {
task.read_ptf_string(CQO1_PTF)?;
}
else {
task.read_data(args[1].as_str())?;
}
// Perform optimization.
let trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Handle solution status. We expect Optimal
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
// Fetch and print the solution
println!("An optimal interior point solution is located.");
let numvar = task.get_num_var()?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR, xx.as_mut_slice())?;
println!("xx = {:?}",xx)
},
Solsta::DUAL_INFEAS_CER =>
println!("Dual infeasibility certificate found."),
Solsta::PRIM_INFEAS_CER =>
println!("Primal infeasibility certificate found."),
Solsta::UNKNOWN => {
// The solutions status is unknown. The termination code
// indicates why the optimizer terminated prematurely.
println!("The solution status is unknown.");
let (symname,desc) = mosek::get_code_desc(trm)?;
println!(" Termination code: {} {}\n", symname, desc)
},
_ =>
println!("Unexpected solution status {}\n",solsta)
}
Ok(())
}
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
fn solutionquality(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(filename) => task.read_data (filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Solve the problem
let _ = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut pobj : f64 = 0.0;
let mut pviolcon : f64 = 0.0;
let mut pviolvar : f64 = 0.0;
let mut pviolbarvar : f64 = 0.0;
let mut pviolcones : f64 = 0.0;
let mut pviolitg : f64 = 0.0;
let mut dobj : f64 = 0.0;
let mut dviolcon : f64 = 0.0;
let mut dviolvar : f64 = 0.0;
let mut dviolbarvar : f64 = 0.0;
let mut dviolcones : f64 = 0.0;
task.get_solution_info(Soltype::BAS,
& mut pobj, & mut pviolcon, & mut pviolvar, & mut pviolbarvar, & mut pviolcones, & mut pviolitg,
& mut dobj, & mut dviolcon, & mut dviolvar, & mut dviolbarvar, & mut dviolcones)?;
match solsta {
Solsta::OPTIMAL => {
let abs_obj_gap = (dobj-pobj).abs();
let rel_obj_gap = abs_obj_gap / (1.0 + f64::min(pobj.abs(), dobj.abs()));
let max_primal_viol = f64::max(pviolcon, pviolvar);
let max_primal_viol = f64::max(max_primal_viol , pviolbarvar);
let max_primal_viol = f64::max(max_primal_viol , pviolcones);
let max_dual_viol = f64::max(dviolcon, dviolvar);
let max_dual_viol = f64::max(max_dual_viol, dviolbarvar);
let max_dual_viol = f64::max(max_dual_viol, dviolcones);
// Assume the application needs the solution to be within
// 1e-6 ofoptimality in an absolute sense. Another approach
// would be looking at the relative objective gap
println!("Customized solution information.");
println!(" Absolute objective gap: {:.3e}", abs_obj_gap);
println!(" Relative objective gap: {:.3e}", rel_obj_gap);
println!(" Max primal violation : {:.3e}", max_primal_viol);
println!(" Max dual violation : {:.3e}", max_dual_viol);
let mut accepted = true;
if rel_obj_gap > 1e-6 {
println!("Warning: The relative objective gap is LARGE.");
accepted = false;
}
// We will accept a primal infeasibility of 1e-8 and
// dual infeasibility of 1e-6. These number should chosen problem
// dependent.
if max_primal_viol > 1e-8 {
println!("Warning: Primal violation is too LARGE");
accepted = false;
}
if max_dual_viol > 1e-6 {
println!("Warning: Dual violation is too LARGE.");
accepted = false;
}
if accepted {
let numvar = task.get_num_var()?;
println!("Optimal primal solution");
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS,xx.as_mut_slice())?;
for (j,&xj) in (0..numvar).zip(xx.iter()) {
println!("x[{}]: {}",j,xj);
}
} else {
// print etailed information about the solution
task.analyze_solution(Streamtype::LOG, Soltype::BAS)?;
}
},
Solsta::DUAL_INFEAS_CER => println!("Primal or dual infeasibility certificate found."),
Solsta::UNKNOWN => println!("The status of the solution is unknown."),
_ => println!("Other solution status"),
}
Ok(())
}
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 129 130
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
sourcepub fn get_obj_name(&self) -> Result<String, String>
pub fn get_obj_name(&self) -> Result<String, String>
Obtains the name assigned to the objective function.
§Returns
objname
Assigned the objective name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getobjname
sourcepub fn get_obj_name_len(&self) -> Result<i32, String>
pub fn get_obj_name_len(&self) -> Result<i32, String>
Obtains the length of the name assigned to the objective function.
§Returns
len
Assigned the length of the objective name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getobjnamelen
sourcepub fn get_obj_sense(&self) -> Result<i32, String>
pub fn get_obj_sense(&self) -> Result<i32, String>
Gets the objective sense.
§Returns
sense
The returned objective sense.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getobjsense
sourcepub fn get_param_max(
&self,
partype_: i32,
parammax_: &mut i32
) -> Result<(), String>
pub fn get_param_max( &self, partype_: i32, parammax_: &mut i32 ) -> Result<(), String>
Obtains the maximum index of a parameter of a given type.
§Arguments
-
partype_
Parameter type.See Parametertype
-
parammax_
The maximum index (plus 1) of the given parameter type.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getparammax
sourcepub fn get_param_name(
&self,
partype_: i32,
param_: i32
) -> Result<String, String>
pub fn get_param_name( &self, partype_: i32, param_: i32 ) -> Result<String, String>
Obtains the name of a parameter.
§Arguments
-
partype_
Parameter type.See Parametertype
-
param_
Which parameter.
§Returns
parname
Parameter name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getparamname
sourcepub fn get_power_domain_alpha(
&mut self,
domidx_: i64,
alpha_: &mut [f64]
) -> Result<(), String>
pub fn get_power_domain_alpha( &mut self, domidx_: i64, alpha_: &mut [f64] ) -> Result<(), String>
Obtains the exponent vector of a power domain.
§Arguments
domidx_
Index of the domain.alpha_
The exponent vector of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getpowerdomainalpha
sourcepub fn get_power_domain_info(
&mut self,
domidx_: i64,
n_: &mut i64,
nleft_: &mut i64
) -> Result<(), String>
pub fn get_power_domain_info( &mut self, domidx_: i64, n_: &mut i64, nleft_: &mut i64 ) -> Result<(), String>
Obtains structural information about a power domain.
§Arguments
domidx_
Index of the domain.n_
Dimension of the domain.nleft_
Number of variables on the left hand side.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getpowerdomaininfo
sourcepub fn get_primal_obj(&self, whichsol_: i32) -> Result<f64, String>
pub fn get_primal_obj(&self, whichsol_: i32) -> Result<f64, String>
Computes the primal objective value for the desired solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
§Returns
primalobj
Objective value corresponding to the primal solution.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getprimalobj
Examples found in repository?
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
More examples
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn get_primal_solution_norms(
&self,
whichsol_: i32,
nrmxc_: &mut f64,
nrmxx_: &mut f64,
nrmbarx_: &mut f64
) -> Result<(), String>
pub fn get_primal_solution_norms( &self, whichsol_: i32, nrmxc_: &mut f64, nrmxx_: &mut f64, nrmbarx_: &mut f64 ) -> Result<(), String>
Compute norms of the primal solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
nrmxc_
The norm of the xc vector. -
nrmxx_
The norm of the xx vector. -
nrmbarx_
The norm of the barX vector.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getprimalsolutionnorms
sourcepub fn get_prob_type(&self) -> Result<i32, String>
pub fn get_prob_type(&self) -> Result<i32, String>
Obtains the problem type.
§Returns
probtype
The problem type.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getprobtype
sourcepub fn get_pro_sta(&self, whichsol_: i32) -> Result<i32, String>
pub fn get_pro_sta(&self, whichsol_: i32) -> Result<i32, String>
Obtains the problem status.
§Arguments
-
whichsol_
Selects a solution.See Soltype
§Returns
problemsta
Problem status.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getprosta
Examples found in repository?
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
sourcepub fn get_pviol_acc(
&self,
whichsol_: i32,
accidxlist_: &[i64],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_pviol_acc( &self, whichsol_: i32, accidxlist_: &[i64], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of a solution for set of affine conic constraints.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
accidxlist_
An array of indexes of conic constraints. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getpviolacc
sourcepub fn get_pviol_barvar(
&self,
whichsol_: i32,
sub_: &[i32],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_pviol_barvar( &self, whichsol_: i32, sub_: &[i32], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of a primal solution for a list of semidefinite variables.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sub_
An array of indexes of barX variables. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getpviolbarvar
sourcepub fn get_pviol_con(
&self,
whichsol_: i32,
sub_: &[i32],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_pviol_con( &self, whichsol_: i32, sub_: &[i32], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of a primal solution associated to a constraint.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sub_
An array of indexes of constraints. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getpviolcon
sourcepub fn get_pviol_cones(
&self,
whichsol_: i32,
sub_: &[i32],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_pviol_cones( &self, whichsol_: i32, sub_: &[i32], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of a solution for set of conic constraints.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sub_
An array of indexes of conic constraints. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getpviolcones
sourcepub fn get_pviol_djc(
&self,
whichsol_: i32,
djcidxlist_: &[i64],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_pviol_djc( &self, whichsol_: i32, djcidxlist_: &[i64], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of a solution for set of disjunctive constraints.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
djcidxlist_
An array of indexes of disjunctive constraints. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getpvioldjc
sourcepub fn get_pviol_var(
&self,
whichsol_: i32,
sub_: &[i32],
viol_: &mut [f64]
) -> Result<(), String>
pub fn get_pviol_var( &self, whichsol_: i32, sub_: &[i32], viol_: &mut [f64] ) -> Result<(), String>
Computes the violation of a primal solution for a list of scalar variables.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sub_
An array of indexes of x variables. -
viol_
List of violations corresponding to sub.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getpviolvar
sourcepub fn get_q_con_k(
&self,
k_: i32,
qcsubi_: &mut [i32],
qcsubj_: &mut [i32],
qcval_: &mut [f64]
) -> Result<i64, String>
pub fn get_q_con_k( &self, k_: i32, qcsubi_: &mut [i32], qcsubj_: &mut [i32], qcval_: &mut [f64] ) -> Result<i64, String>
Obtains all the quadratic terms in a constraint.
§Arguments
k_
Which constraint.qcsubi_
Row subscripts for quadratic constraint matrix.qcsubj_
Column subscripts for quadratic constraint matrix.qcval_
Quadratic constraint coefficient values.
§Returns
numqcnz
Number of quadratic terms.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getqconk64
sourcepub fn get_q_obj(
&self,
numqonz_: &mut i64,
qosubi_: &mut [i32],
qosubj_: &mut [i32],
qoval_: &mut [f64]
) -> Result<(), String>
pub fn get_q_obj( &self, numqonz_: &mut i64, qosubi_: &mut [i32], qosubj_: &mut [i32], qoval_: &mut [f64] ) -> Result<(), String>
Obtains all the quadratic terms in the objective.
§Arguments
numqonz_
Number of non-zero elements in the quadratic objective terms.qosubi_
Row subscripts for quadratic objective coefficients.qosubj_
Column subscripts for quadratic objective coefficients.qoval_
Quadratic objective coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getqobj64
sourcepub fn get_q_obj_i_j(
&self,
i_: i32,
j_: i32,
qoij_: &mut f64
) -> Result<(), String>
pub fn get_q_obj_i_j( &self, i_: i32, j_: i32, qoij_: &mut f64 ) -> Result<(), String>
Obtains one coefficient from the quadratic term of the objective
§Arguments
i_
Row index of the coefficient.j_
Column index of coefficient.qoij_
The required coefficient.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getqobjij
sourcepub fn get_reduced_costs(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
redcosts_: &mut [f64]
) -> Result<(), String>
pub fn get_reduced_costs( &self, whichsol_: i32, first_: i32, last_: i32, redcosts_: &mut [f64] ) -> Result<(), String>
Obtains the reduced costs for a sequence of variables.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
The index of the first variable in the sequence. -
last_
The index of the last variable in the sequence plus 1. -
redcosts_
Returns the requested reduced costs.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getreducedcosts
sourcepub fn get_skc(&self, whichsol_: i32, skc_: &mut [i32]) -> Result<(), String>
pub fn get_skc(&self, whichsol_: i32, skc_: &mut [i32]) -> Result<(), String>
Obtains the status keys for the constraints.
§Arguments
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getskc
sourcepub fn get_skc_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
skc_: &mut [i32]
) -> Result<(), String>
pub fn get_skc_slice( &self, whichsol_: i32, first_: i32, last_: i32, skc_: &mut [i32] ) -> Result<(), String>
Obtains the status keys for a slice of the constraints.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
skc_
Status keys for the constraints.See Stakey
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getskcslice
sourcepub fn get_skn(&self, whichsol_: i32, skn_: &mut [i32]) -> Result<(), String>
pub fn get_skn(&self, whichsol_: i32, skn_: &mut [i32]) -> Result<(), String>
Obtains the status keys for the conic constraints.
§Arguments
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getskn
sourcepub fn get_skx(&self, whichsol_: i32, skx_: &mut [i32]) -> Result<(), String>
pub fn get_skx(&self, whichsol_: i32, skx_: &mut [i32]) -> Result<(), String>
Obtains the status keys for the scalar variables.
§Arguments
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getskx
sourcepub fn get_skx_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
skx_: &mut [i32]
) -> Result<(), String>
pub fn get_skx_slice( &self, whichsol_: i32, first_: i32, last_: i32, skx_: &mut [i32] ) -> Result<(), String>
Obtains the status keys for a slice of the scalar variables.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
skx_
Status keys for the variables.See Stakey
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getskxslice
sourcepub fn get_slc(&self, whichsol_: i32, slc_: &mut [f64]) -> Result<(), String>
pub fn get_slc(&self, whichsol_: i32, slc_: &mut [f64]) -> Result<(), String>
Obtains the slc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
slc_
Dual variables corresponding to the lower bounds on the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getslc
Examples found in repository?
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
sourcepub fn get_slc_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
slc_: &mut [f64]
) -> Result<(), String>
pub fn get_slc_slice( &self, whichsol_: i32, first_: i32, last_: i32, slc_: &mut [f64] ) -> Result<(), String>
Obtains a slice of the slc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
slc_
Dual variables corresponding to the lower bounds on the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getslcslice
sourcepub fn get_slx(&self, whichsol_: i32, slx_: &mut [f64]) -> Result<(), String>
pub fn get_slx(&self, whichsol_: i32, slx_: &mut [f64]) -> Result<(), String>
Obtains the slx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
slx_
Dual variables corresponding to the lower bounds on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getslx
Examples found in repository?
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
sourcepub fn get_slx_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
slx_: &mut [f64]
) -> Result<(), String>
pub fn get_slx_slice( &self, whichsol_: i32, first_: i32, last_: i32, slx_: &mut [f64] ) -> Result<(), String>
Obtains a slice of the slx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
slx_
Dual variables corresponding to the lower bounds on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getslxslice
sourcepub fn get_snx(&self, whichsol_: i32, snx_: &mut [f64]) -> Result<(), String>
pub fn get_snx(&self, whichsol_: i32, snx_: &mut [f64]) -> Result<(), String>
Obtains the snx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
snx_
Dual variables corresponding to the conic constraints on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsnx
sourcepub fn get_snx_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
snx_: &mut [f64]
) -> Result<(), String>
pub fn get_snx_slice( &self, whichsol_: i32, first_: i32, last_: i32, snx_: &mut [f64] ) -> Result<(), String>
Obtains a slice of the snx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
snx_
Dual variables corresponding to the conic constraints on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsnxslice
sourcepub fn get_sol_sta(&self, whichsol_: i32) -> Result<i32, String>
pub fn get_sol_sta(&self, whichsol_: i32) -> Result<i32, String>
Obtains the solution status.
§Arguments
-
whichsol_
Selects a solution.See Soltype
§Returns
solutionsta
Solution status.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsolsta
Examples found in repository?
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
fn main() -> Result<(),String> {
let args: Vec<String> = env::args().collect();
let mut task = Task::new().unwrap().with_callbacks();
if args.len() < 2 {
task.read_ptf_string(CQO1_PTF)?;
}
else {
task.read_data(args[1].as_str())?;
}
// Perform optimization.
let trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Handle solution status. We expect Optimal
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
// Fetch and print the solution
println!("An optimal interior point solution is located.");
let numvar = task.get_num_var()?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR, xx.as_mut_slice())?;
println!("xx = {:?}",xx)
},
Solsta::DUAL_INFEAS_CER =>
println!("Dual infeasibility certificate found."),
Solsta::PRIM_INFEAS_CER =>
println!("Primal infeasibility certificate found."),
Solsta::UNKNOWN => {
// The solutions status is unknown. The termination code
// indicates why the optimizer terminated prematurely.
println!("The solution status is unknown.");
let (symname,desc) = mosek::get_code_desc(trm)?;
println!(" Termination code: {} {}\n", symname, desc)
},
_ =>
println!("Unexpected solution status {}\n",solsta)
}
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
sourcepub fn get_solution(
&self,
whichsol_: i32,
problemsta_: &mut i32,
solutionsta_: &mut i32,
skc_: &mut [i32],
skx_: &mut [i32],
skn_: &mut [i32],
xc_: &mut [f64],
xx_: &mut [f64],
y_: &mut [f64],
slc_: &mut [f64],
suc_: &mut [f64],
slx_: &mut [f64],
sux_: &mut [f64],
snx_: &mut [f64]
) -> Result<(), String>
pub fn get_solution( &self, whichsol_: i32, problemsta_: &mut i32, solutionsta_: &mut i32, skc_: &mut [i32], skx_: &mut [i32], skn_: &mut [i32], xc_: &mut [f64], xx_: &mut [f64], y_: &mut [f64], slc_: &mut [f64], suc_: &mut [f64], slx_: &mut [f64], sux_: &mut [f64], snx_: &mut [f64] ) -> Result<(), String>
Obtains the complete solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
problemsta_
Problem status.See Prosta
-
solutionsta_
Solution status.See Solsta
-
skc_
Status keys for the constraints.See Stakey
-
skx_
Status keys for the variables.See Stakey
-
skn_
Status keys for the conic constraints.See Stakey
-
xc_
Primal constraint solution. -
xx_
Primal variable solution. -
y_
Vector of dual variables corresponding to the constraints. -
slc_
Dual variables corresponding to the lower bounds on the constraints. -
suc_
Dual variables corresponding to the upper bounds on the constraints. -
slx_
Dual variables corresponding to the lower bounds on the variables. -
sux_
Dual variables corresponding to the upper bounds on the variables. -
snx_
Dual variables corresponding to the conic constraints on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsolution
sourcepub fn get_solution_info(
&self,
whichsol_: i32,
pobj_: &mut f64,
pviolcon_: &mut f64,
pviolvar_: &mut f64,
pviolbarvar_: &mut f64,
pviolcone_: &mut f64,
pviolitg_: &mut f64,
dobj_: &mut f64,
dviolcon_: &mut f64,
dviolvar_: &mut f64,
dviolbarvar_: &mut f64,
dviolcone_: &mut f64
) -> Result<(), String>
pub fn get_solution_info( &self, whichsol_: i32, pobj_: &mut f64, pviolcon_: &mut f64, pviolvar_: &mut f64, pviolbarvar_: &mut f64, pviolcone_: &mut f64, pviolitg_: &mut f64, dobj_: &mut f64, dviolcon_: &mut f64, dviolvar_: &mut f64, dviolbarvar_: &mut f64, dviolcone_: &mut f64 ) -> Result<(), String>
Obtains information about of a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
pobj_
The primal objective value. -
pviolcon_
Maximal primal bound violation for a xc variable. -
pviolvar_
Maximal primal bound violation for a xx variable. -
pviolbarvar_
Maximal primal bound violation for a barx variable. -
pviolcone_
Maximal primal violation of the solution with respect to the conic constraints. -
pviolitg_
Maximal violation in the integer constraints. -
dobj_
Dual objective value. -
dviolcon_
Maximal dual bound violation for a xc variable. -
dviolvar_
Maximal dual bound violation for a xx variable. -
dviolbarvar_
Maximal dual bound violation for a bars variable. -
dviolcone_
Maximum violation of the dual solution in the dual conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsolutioninfo
Examples found in repository?
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
fn solutionquality(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(filename) => task.read_data (filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Solve the problem
let _ = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut pobj : f64 = 0.0;
let mut pviolcon : f64 = 0.0;
let mut pviolvar : f64 = 0.0;
let mut pviolbarvar : f64 = 0.0;
let mut pviolcones : f64 = 0.0;
let mut pviolitg : f64 = 0.0;
let mut dobj : f64 = 0.0;
let mut dviolcon : f64 = 0.0;
let mut dviolvar : f64 = 0.0;
let mut dviolbarvar : f64 = 0.0;
let mut dviolcones : f64 = 0.0;
task.get_solution_info(Soltype::BAS,
& mut pobj, & mut pviolcon, & mut pviolvar, & mut pviolbarvar, & mut pviolcones, & mut pviolitg,
& mut dobj, & mut dviolcon, & mut dviolvar, & mut dviolbarvar, & mut dviolcones)?;
match solsta {
Solsta::OPTIMAL => {
let abs_obj_gap = (dobj-pobj).abs();
let rel_obj_gap = abs_obj_gap / (1.0 + f64::min(pobj.abs(), dobj.abs()));
let max_primal_viol = f64::max(pviolcon, pviolvar);
let max_primal_viol = f64::max(max_primal_viol , pviolbarvar);
let max_primal_viol = f64::max(max_primal_viol , pviolcones);
let max_dual_viol = f64::max(dviolcon, dviolvar);
let max_dual_viol = f64::max(max_dual_viol, dviolbarvar);
let max_dual_viol = f64::max(max_dual_viol, dviolcones);
// Assume the application needs the solution to be within
// 1e-6 ofoptimality in an absolute sense. Another approach
// would be looking at the relative objective gap
println!("Customized solution information.");
println!(" Absolute objective gap: {:.3e}", abs_obj_gap);
println!(" Relative objective gap: {:.3e}", rel_obj_gap);
println!(" Max primal violation : {:.3e}", max_primal_viol);
println!(" Max dual violation : {:.3e}", max_dual_viol);
let mut accepted = true;
if rel_obj_gap > 1e-6 {
println!("Warning: The relative objective gap is LARGE.");
accepted = false;
}
// We will accept a primal infeasibility of 1e-8 and
// dual infeasibility of 1e-6. These number should chosen problem
// dependent.
if max_primal_viol > 1e-8 {
println!("Warning: Primal violation is too LARGE");
accepted = false;
}
if max_dual_viol > 1e-6 {
println!("Warning: Dual violation is too LARGE.");
accepted = false;
}
if accepted {
let numvar = task.get_num_var()?;
println!("Optimal primal solution");
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS,xx.as_mut_slice())?;
for (j,&xj) in (0..numvar).zip(xx.iter()) {
println!("x[{}]: {}",j,xj);
}
} else {
// print etailed information about the solution
task.analyze_solution(Streamtype::LOG, Soltype::BAS)?;
}
},
Solsta::DUAL_INFEAS_CER => println!("Primal or dual infeasibility certificate found."),
Solsta::UNKNOWN => println!("The status of the solution is unknown."),
_ => println!("Other solution status"),
}
Ok(())
}
sourcepub fn get_solution_info_new(
&self,
whichsol_: i32,
pobj_: &mut f64,
pviolcon_: &mut f64,
pviolvar_: &mut f64,
pviolbarvar_: &mut f64,
pviolcone_: &mut f64,
pviolacc_: &mut f64,
pvioldjc_: &mut f64,
pviolitg_: &mut f64,
dobj_: &mut f64,
dviolcon_: &mut f64,
dviolvar_: &mut f64,
dviolbarvar_: &mut f64,
dviolcone_: &mut f64,
dviolacc_: &mut f64
) -> Result<(), String>
pub fn get_solution_info_new( &self, whichsol_: i32, pobj_: &mut f64, pviolcon_: &mut f64, pviolvar_: &mut f64, pviolbarvar_: &mut f64, pviolcone_: &mut f64, pviolacc_: &mut f64, pvioldjc_: &mut f64, pviolitg_: &mut f64, dobj_: &mut f64, dviolcon_: &mut f64, dviolvar_: &mut f64, dviolbarvar_: &mut f64, dviolcone_: &mut f64, dviolacc_: &mut f64 ) -> Result<(), String>
Obtains information about of a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
pobj_
The primal objective value. -
pviolcon_
Maximal primal bound violation for a xc variable. -
pviolvar_
Maximal primal bound violation for a xx variable. -
pviolbarvar_
Maximal primal bound violation for a barx variable. -
pviolcone_
Maximal primal violation of the solution with respect to the conic constraints. -
pviolacc_
Maximal primal violation of the solution with respect to the affine conic constraints. -
pvioldjc_
Maximal primal violation of the solution with respect to the disjunctive constraints. -
pviolitg_
Maximal violation in the integer constraints. -
dobj_
Dual objective value. -
dviolcon_
Maximal dual bound violation for a xc variable. -
dviolvar_
Maximal dual bound violation for a xx variable. -
dviolbarvar_
Maximal dual bound violation for a bars variable. -
dviolcone_
Maximum violation of the dual solution in the dual conic constraints. -
dviolacc_
Maximum violation of the dual solution in the dual affine conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsolutioninfonew
sourcepub fn get_solution_new(
&self,
whichsol_: i32,
problemsta_: &mut i32,
solutionsta_: &mut i32,
skc_: &mut [i32],
skx_: &mut [i32],
skn_: &mut [i32],
xc_: &mut [f64],
xx_: &mut [f64],
y_: &mut [f64],
slc_: &mut [f64],
suc_: &mut [f64],
slx_: &mut [f64],
sux_: &mut [f64],
snx_: &mut [f64],
doty_: &mut [f64]
) -> Result<(), String>
pub fn get_solution_new( &self, whichsol_: i32, problemsta_: &mut i32, solutionsta_: &mut i32, skc_: &mut [i32], skx_: &mut [i32], skn_: &mut [i32], xc_: &mut [f64], xx_: &mut [f64], y_: &mut [f64], slc_: &mut [f64], suc_: &mut [f64], slx_: &mut [f64], sux_: &mut [f64], snx_: &mut [f64], doty_: &mut [f64] ) -> Result<(), String>
Obtains the complete solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
problemsta_
Problem status.See Prosta
-
solutionsta_
Solution status.See Solsta
-
skc_
Status keys for the constraints.See Stakey
-
skx_
Status keys for the variables.See Stakey
-
skn_
Status keys for the conic constraints.See Stakey
-
xc_
Primal constraint solution. -
xx_
Primal variable solution. -
y_
Vector of dual variables corresponding to the constraints. -
slc_
Dual variables corresponding to the lower bounds on the constraints. -
suc_
Dual variables corresponding to the upper bounds on the constraints. -
slx_
Dual variables corresponding to the lower bounds on the variables. -
sux_
Dual variables corresponding to the upper bounds on the variables. -
snx_
Dual variables corresponding to the conic constraints on the variables. -
doty_
Dual variables corresponding to affine conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsolutionnew
sourcepub fn get_solution_slice(
&self,
whichsol_: i32,
solitem_: i32,
first_: i32,
last_: i32,
values_: &mut [f64]
) -> Result<(), String>
pub fn get_solution_slice( &self, whichsol_: i32, solitem_: i32, first_: i32, last_: i32, values_: &mut [f64] ) -> Result<(), String>
Obtains a slice of the solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
solitem_
Which part of the solution is required.See Solitem
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
values_
The values of the requested solution elements.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsolutionslice
sourcepub fn get_sparse_sym_mat(
&self,
idx_: i64,
subi_: &mut [i32],
subj_: &mut [i32],
valij_: &mut [f64]
) -> Result<(), String>
pub fn get_sparse_sym_mat( &self, idx_: i64, subi_: &mut [i32], subj_: &mut [i32], valij_: &mut [f64] ) -> Result<(), String>
Gets a single symmetric matrix from the matrix store.
§Arguments
idx_
Index of the matrix to retrieve.subi_
Row subscripts of the matrix non-zero elements.subj_
Column subscripts of the matrix non-zero elements.valij_
Coefficients of the matrix non-zero elements.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsparsesymmat
sourcepub fn get_str_param(
&self,
param_: i32,
len_: &mut i32
) -> Result<String, String>
pub fn get_str_param( &self, param_: i32, len_: &mut i32 ) -> Result<String, String>
Obtains the value of a string parameter.
§Arguments
-
param_
Which parameter.See Sparam
-
len_
The length of the parameter value.
§Returns
parvalue
If this is not a null pointer, the parameter value is stored here.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getstrparam
sourcepub fn get_str_param_len(&self, param_: i32) -> Result<i32, String>
pub fn get_str_param_len(&self, param_: i32) -> Result<i32, String>
Obtains the length of a string parameter.
§Arguments
-
param_
Which parameter.See Sparam
§Returns
len
The length of the parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getstrparamlen
sourcepub fn get_suc(&self, whichsol_: i32, suc_: &mut [f64]) -> Result<(), String>
pub fn get_suc(&self, whichsol_: i32, suc_: &mut [f64]) -> Result<(), String>
Obtains the suc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
suc_
Dual variables corresponding to the upper bounds on the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsuc
Examples found in repository?
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
sourcepub fn get_suc_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
suc_: &mut [f64]
) -> Result<(), String>
pub fn get_suc_slice( &self, whichsol_: i32, first_: i32, last_: i32, suc_: &mut [f64] ) -> Result<(), String>
Obtains a slice of the suc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
suc_
Dual variables corresponding to the upper bounds on the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsucslice
sourcepub fn get_sux(&self, whichsol_: i32, sux_: &mut [f64]) -> Result<(), String>
pub fn get_sux(&self, whichsol_: i32, sux_: &mut [f64]) -> Result<(), String>
Obtains the sux vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sux_
Dual variables corresponding to the upper bounds on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsux
Examples found in repository?
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
sourcepub fn get_sux_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
sux_: &mut [f64]
) -> Result<(), String>
pub fn get_sux_slice( &self, whichsol_: i32, first_: i32, last_: i32, sux_: &mut [f64] ) -> Result<(), String>
Obtains a slice of the sux vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
sux_
Dual variables corresponding to the upper bounds on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsuxslice
sourcepub fn get_symb_con(&self, i_: i32, value_: &mut i32) -> Result<String, String>
pub fn get_symb_con(&self, i_: i32, value_: &mut i32) -> Result<String, String>
Obtains a cone type string identifier.
§Arguments
i_
Index.value_
The corresponding value.
§Returns
name
Name of the i’th symbolic constant.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsymbcon
sourcepub fn get_sym_mat_info(
&self,
idx_: i64,
dim_: &mut i32,
nz_: &mut i64,
mattype_: &mut i32
) -> Result<(), String>
pub fn get_sym_mat_info( &self, idx_: i64, dim_: &mut i32, nz_: &mut i64, mattype_: &mut i32 ) -> Result<(), String>
Obtains information about a matrix from the symmetric matrix storage.
§Arguments
-
idx_
Index of the matrix for which information is requested. -
dim_
Returns the dimension of the requested matrix. -
nz_
Returns the number of non-zeros in the requested matrix. -
mattype_
Returns the type of the requested matrix.See Symmattype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getsymmatinfo
sourcepub fn get_task_name(&self) -> Result<String, String>
pub fn get_task_name(&self) -> Result<String, String>
Obtains the task name.
§Returns
taskname
Returns the task name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.gettaskname
sourcepub fn get_task_name_len(&self) -> Result<i32, String>
pub fn get_task_name_len(&self) -> Result<i32, String>
Obtains the length the task name.
§Returns
len
Returns the length of the task name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.gettasknamelen
sourcepub fn get_var_bound(
&self,
i_: i32,
bk_: &mut i32,
bl_: &mut f64,
bu_: &mut f64
) -> Result<(), String>
pub fn get_var_bound( &self, i_: i32, bk_: &mut i32, bl_: &mut f64, bu_: &mut f64 ) -> Result<(), String>
Obtains bound information for one variable.
§Arguments
-
i_
Index of the variable for which the bound information should be obtained. -
bk_
Bound keys.See Boundkey
-
bl_
Values for lower bounds. -
bu_
Values for upper bounds.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getvarbound
sourcepub fn get_var_bound_slice(
&self,
first_: i32,
last_: i32,
bk_: &mut [i32],
bl_: &mut [f64],
bu_: &mut [f64]
) -> Result<(), String>
pub fn get_var_bound_slice( &self, first_: i32, last_: i32, bk_: &mut [i32], bl_: &mut [f64], bu_: &mut [f64] ) -> Result<(), String>
Obtains bounds information for a slice of the variables.
§Arguments
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
bk_
Bound keys.See Boundkey
-
bl_
Values for lower bounds. -
bu_
Values for upper bounds.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getvarboundslice
sourcepub fn get_var_name(&self, j_: i32) -> Result<String, String>
pub fn get_var_name(&self, j_: i32) -> Result<String, String>
Obtains the name of a variable.
§Arguments
j_
Index of a variable.
§Returns
name
Returns the required name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getvarname
sourcepub fn get_var_name_index(
&self,
somename_: &str,
asgn_: &mut i32
) -> Result<i32, String>
pub fn get_var_name_index( &self, somename_: &str, asgn_: &mut i32 ) -> Result<i32, String>
Checks whether the name has been assigned to any variable.
§Arguments
somename_
The name which should be checked.asgn_
Is non-zero if the name somename is assigned to a variable.
§Returns
index
If the name somename is assigned to a variable, then return the index of the variable.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getvarnameindex
sourcepub fn get_var_name_len(&self, i_: i32) -> Result<i32, String>
pub fn get_var_name_len(&self, i_: i32) -> Result<i32, String>
Obtains the length of the name of a variable.
§Arguments
i_
Index of a variable.
§Returns
len
Returns the length of the indicated name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getvarnamelen
sourcepub fn get_var_type(&self, j_: i32) -> Result<i32, String>
pub fn get_var_type(&self, j_: i32) -> Result<i32, String>
Gets the variable type of one variable.
§Arguments
j_
Index of the variable.
§Returns
vartype
Variable type of variable index j.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getvartype
sourcepub fn get_var_type_list(
&self,
subj_: &[i32],
vartype_: &mut [i32]
) -> Result<(), String>
pub fn get_var_type_list( &self, subj_: &[i32], vartype_: &mut [i32] ) -> Result<(), String>
Obtains the variable type for one or more variables.
§Arguments
-
subj_
A list of variable indexes. -
vartype_
Returns the variables types corresponding the variable indexes requested.See Variabletype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getvartypelist
sourcepub fn get_xc(&self, whichsol_: i32, xc_: &mut [f64]) -> Result<(), String>
pub fn get_xc(&self, whichsol_: i32, xc_: &mut [f64]) -> Result<(), String>
Obtains the xc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
xc_
Primal constraint solution.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getxc
sourcepub fn get_xc_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
xc_: &mut [f64]
) -> Result<(), String>
pub fn get_xc_slice( &self, whichsol_: i32, first_: i32, last_: i32, xc_: &mut [f64] ) -> Result<(), String>
Obtains a slice of the xc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
xc_
Primal constraint solution.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getxcslice
sourcepub fn get_xx(&self, whichsol_: i32, xx_: &mut [f64]) -> Result<(), String>
pub fn get_xx(&self, whichsol_: i32, xx_: &mut [f64]) -> Result<(), String>
Obtains the xx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
xx_
Primal variable solution.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getxx
Examples found in repository?
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
fn main() -> Result<(),String> {
let args: Vec<String> = env::args().collect();
let mut task = Task::new().unwrap().with_callbacks();
if args.len() < 2 {
task.read_ptf_string(CQO1_PTF)?;
}
else {
task.read_data(args[1].as_str())?;
}
// Perform optimization.
let trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Handle solution status. We expect Optimal
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
// Fetch and print the solution
println!("An optimal interior point solution is located.");
let numvar = task.get_num_var()?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR, xx.as_mut_slice())?;
println!("xx = {:?}",xx)
},
Solsta::DUAL_INFEAS_CER =>
println!("Dual infeasibility certificate found."),
Solsta::PRIM_INFEAS_CER =>
println!("Primal infeasibility certificate found."),
Solsta::UNKNOWN => {
// The solutions status is unknown. The termination code
// indicates why the optimizer terminated prematurely.
println!("The solution status is unknown.");
let (symname,desc) = mosek::get_code_desc(trm)?;
println!(" Termination code: {} {}\n", symname, desc)
},
_ =>
println!("Unexpected solution status {}\n",solsta)
}
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
let numvar : i32 = 4;
let numcon : i32 = 1;
let c = &[ 7.0, 10.0, 1.0, 5.0 ];
let bkc = &[Boundkey::UP];
let blc = &[ -INF ];
let buc = &[2.5];
let bkx = &[Boundkey::LO,
Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = &[0.0,
0.0,
0.0,
0.0 ];
let bux = &[INF,
INF,
INF,
INF];
let ptrb = &[0i64, 1, 2, 3];
let ptre = &[1i64, 2, 3, 4];
let aval = &[1.0, 1.0, 1.0, 1.0];
let asub = &[0i32, 0, 0, 0 ];
let intsub = &[0i32, 1, 2];
let inttype = &[Variabletype::TYPE_INT,
Variabletype::TYPE_INT,
Variabletype::TYPE_INT ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon, numvar,
c, 0.0,
ptrb, ptre,
asub, aval,
bkc, blc, buc,
bkx, blx, bux)?;
task.put_var_type_list(intsub, inttype)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MAXIMIZE)?;
// Assign values to integer variables
// We only set that slice of xx
task.put_xx_slice(Soltype::ITG, 0, 3, &[1.0,1.0,0.0])?;
// Request constructing the solution from integer variable values
task.put_int_param(mosek::Iparam::MIO_CONSTRUCT_SOL, mosek::Onoffkey::ON)?;
// solve
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::LOG)?;
// Read and print solution
let mut xx = vec![0.0; numvar as usize];
task.get_xx(mosek::Soltype::ITG, xx.as_mut_slice())?;
println!("Optimal solution:");
for (i,xi) in xx.iter().enumerate() {
println!("x[{}] = {}",i,*xi);
}
// Was the initial solution used?
let constr = task.get_int_inf(mosek::Iinfitem::MIO_CONSTRUCT_SOLUTION)?;
let constr_val = task.get_dou_inf(mosek::Dinfitem::MIO_CONSTRUCT_SOLUTION_OBJ)?;
println!("Construct solution utilization: {}", constr);
println!("Construct solution objective: {}", constr_val);
Ok(())
}
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
sourcepub fn get_xx_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
xx_: &mut [f64]
) -> Result<(), String>
pub fn get_xx_slice( &self, whichsol_: i32, first_: i32, last_: i32, xx_: &mut [f64] ) -> Result<(), String>
Obtains a slice of the xx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
xx_
Primal variable solution.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getxxslice
Examples found in repository?
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
More examples
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
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
fn portfolio(w : f64,
mu : &[f64],
x0 : &[f64],
gammas : &[f64],
theta : &[f64],
GT : &Matrix) -> Result<Vec<(f64,f64)>,String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
let (kx,nx) = GT.size();
if mu.len() != nx { panic!("Mismatching data"); }
let k : i32 = kx.try_into().unwrap();
let n : i32 = nx.try_into().unwrap();
let total_budget : f64 = w + x0.iter().sum::<f64>();
//Offset of variables into the API variable.
let numvar = n;
let voff_x : i32 = 0;
// Constraint offset
let coff_bud : i32 = 0;
// Holding variable x of length n
// No other auxiliary variables are needed in this formulation
task.append_vars(numvar)?;
// Setting up variable x
for j in 0..n {
task.put_var_name(voff_x+j,format!("x[{}]",j+1).as_str())?;
}
task.put_var_bound_slice_const(voff_x,voff_x+n, Boundkey::LO,0.0, INF)?;
// One linear constraint: total budget
task.append_cons(1)?;
task.put_con_name(coff_bud, "budget")?;
/* Coefficients in the first row of A */
for j in 0..n {
task.put_aij(coff_bud,voff_x + j, 1.0)?;
}
task.put_con_bound(coff_bud, Boundkey::FX, total_budget, total_budget)?;
// Input (gamma, G_factor_T x, diag(sqrt(theta))*x) in the AFE (affine expression) storage
// We need k+n+1 rows and we fill them in in three parts
task.append_afes((k+n) as i64 + 1)?;
// 1. The first affine expression = gamma, will be specified later
// 2. The next k expressions comprise G_factor_T*x, we add them row by row
// transposing the matrix G_factor on the fly
task.put_afe_f_row_list((1..1+k as i64).collect::<Vec<i64>>().as_slice(), // f row idxs
vec![n; k as usize].as_slice(), // row lengths
(0..GT.len() as i64).step_by(n as usize).collect::<Vec<i64>>().as_slice(), // row ptr
iproduct!(0..k,0..n).map(|(_,b)| b).collect::<Vec<i32>>().as_slice(), // varidx, 0..n repeated k times
GT.data_by_row().as_slice())?;
// 3. The remaining n rows contain sqrt(theta) on the diagonal
for (i,thetai) in (0..n).zip(theta.iter()) {
task.put_afe_f_entry(i as i64 + 1 + k as i64, voff_x + i, thetai.sqrt())?;
}
// Input the affine conic constraint (gamma, GT*x) \in QCone
// Add the quadratic domain of dimension k+1
let qdom = task.append_quadratic_cone_domain(k as i64+ 1)?;
// Add the constraint
task.append_acc_seq(qdom, 0, vec![0.0; k as usize+1].as_slice())?;
task.put_acc_name(0, "risk")?;
// Objective: maximize expected return mu^T x
for (j,&muj) in (0..n).zip(mu.iter()) {
task.put_c_j(voff_x + j, muj)?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
Ok(gammas.iter().filter_map(|&gamma| {
// Specify gamma in ACC
task.put_afe_g(0, gamma).ok()?;
task.optimize().ok()?;
/* Display solution summary for quick inspection of results */
let _ = task.solution_summary(Streamtype::LOG);
let _ = task.write_data(format!("portfolio_6_factor-{}.ptf",gamma).as_str());
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR).ok()? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Read the results */
let mut xx = vec![0.0; n as usize];
task.get_xx_slice(Soltype::ITR, voff_x, voff_x + n, xx.as_mut_slice()).ok()?;
Some((gamma,xx.iter().zip(mu.iter()).map(|(&xj,&muj)| xj*muj).sum::<f64>()))
}).collect::<Vec<(f64,f64)>>())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
sourcepub fn get_y(&self, whichsol_: i32, y_: &mut [f64]) -> Result<(), String>
pub fn get_y(&self, whichsol_: i32, y_: &mut [f64]) -> Result<(), String>
Obtains the y vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
y_
Vector of dual variables corresponding to the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.gety
sourcepub fn get_y_slice(
&self,
whichsol_: i32,
first_: i32,
last_: i32,
y_: &mut [f64]
) -> Result<(), String>
pub fn get_y_slice( &self, whichsol_: i32, first_: i32, last_: i32, y_: &mut [f64] ) -> Result<(), String>
Obtains a slice of the y vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
y_
Vector of dual variables corresponding to the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.getyslice
sourcepub fn infeasibility_report(
&mut self,
whichstream_: i32,
whichsol_: i32
) -> Result<(), String>
pub fn infeasibility_report( &mut self, whichstream_: i32, whichsol_: i32 ) -> Result<(), String>
Prints the infeasibility report to an output stream.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
-
whichsol_
Selects a solution.See Soltype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.infeasibilityreport
sourcepub fn init_basis_solve(&mut self, basis_: &mut [i32]) -> Result<(), String>
pub fn init_basis_solve(&mut self, basis_: &mut [i32]) -> Result<(), String>
Prepare a task for basis solver.
§Arguments
basis_
The array of basis indexes to use.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.initbasissolve
Examples found in repository?
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
fn solve() -> Result<(),String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.put_obj_name("solvebasis")?;
let numcon : i32 = 2;
let numvar : i32 = 2;
let mut w1 = vec![2.0, 6.0];
let mut w2 = vec![1.0, 0.0];
task.input_data(numcon, numvar,
&[1.0, 1.0], // c
0.0, // cfix
&[0,2], // ptrb
&[2,3], // ptre
&[0,1,
0,1], // sub
&[1.0, 1.0,
2.0, 1.0], // val
&[Boundkey::UP,
Boundkey::UP], // bkc
&[0.0,0.0], // blc
&[2.0,6.0], // buc
&[Boundkey::LO,
Boundkey::LO], // bkx
&[0.0, 0.0], // blx
&[0.0,0.0])?; // bux;
task.put_obj_sense(Objsense::MAXIMIZE)?;
let _ = task.optimize()?;
let mut basis = vec![0i32; numcon as usize];
task.init_basis_solve(basis.as_mut_slice())?;
// List basis variables corresponding to columns of B
let mut varsub = vec![0i32, 1];
for i in 0..numcon {
if basis[varsub[i as usize] as usize] < numcon {
println!("Basis variable no {} is xc{}",i,basis[varsub[i as usize] as usize]);
}
else {
println!("Basis variable no {} is x{}",i,basis[i as usize]-numcon);
// solve Bx = w1
// varsub contains index of non-zeros in b.
// On return b contains the solution x and
// varsub the index of the non-zeros in x.
{
let nz = task.solve_with_basis(false, 2, varsub.as_mut_slice(), w1.as_mut_slice())?;
println!("nz = {}",nz);
println!("Solution to Bx = {:?}",w1);
for vsubi in &varsub[0..nz as usize] {
if basis[*vsubi as usize] < numcon {
println!("xc {} = {}",basis[*vsubi as usize],w1[*vsubi as usize]);
}
else {
println!("x{} = {}",basis[*vsubi as usize] - numcon,w1[*vsubi as usize])
}
}
}
// Solve B^Tx = w2
{
varsub[0] = 1;
let nz = task.solve_with_basis(true,1,varsub.as_mut_slice(),w2.as_mut_slice())?;
println!("nz = {}",nz);
println!("Solution to B^Tx = {:?}",w2);
for vsubi in &varsub[0..nz as usize] {
if basis[*vsubi as usize] < numcon {
print!("xc{} = {}",basis[*vsubi as usize],w2[*vsubi as usize]);
}
else {
print!("x{} = {}",basis[*vsubi as usize] - numcon,w2[*vsubi as usize]);
}
}
}
}
}
Ok(())
}
sourcepub fn input_data(
&mut self,
maxnumcon_: i32,
maxnumvar_: i32,
c_: &[f64],
cfix_: f64,
aptrb_: &[i64],
aptre_: &[i64],
asub_: &[i32],
aval_: &[f64],
bkc_: &[i32],
blc_: &[f64],
buc_: &[f64],
bkx_: &[i32],
blx_: &[f64],
bux_: &[f64]
) -> Result<(), String>
pub fn input_data( &mut self, maxnumcon_: i32, maxnumvar_: i32, c_: &[f64], cfix_: f64, aptrb_: &[i64], aptre_: &[i64], asub_: &[i32], aval_: &[f64], bkc_: &[i32], blc_: &[f64], buc_: &[f64], bkx_: &[i32], blx_: &[f64], bux_: &[f64] ) -> Result<(), String>
Input the linear part of an optimization task in one function call.
§Arguments
-
maxnumcon_
Number of preallocated constraints in the optimization task. -
maxnumvar_
Number of preallocated variables in the optimization task. -
c_
Linear terms of the objective as a dense vector. The length is the number of variables. -
cfix_
Fixed term in the objective. -
aptrb_
Row or column start pointers. -
aptre_
Row or column end pointers. -
asub_
Coefficient subscripts. -
aval_
Coefficient values. -
bkc_
Bound keys for the constraints.See Boundkey
-
blc_
Lower bounds for the constraints. -
buc_
Upper bounds for the constraints. -
bkx_
Bound keys for the variables.See Boundkey
-
blx_
Lower bounds for the variables. -
bux_
Upper bounds for the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.inputdata64
Examples found in repository?
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
fn main() -> Result<(),String> {
let numvar : i32 = 4;
let numcon : i32 = 1;
let c = &[ 7.0, 10.0, 1.0, 5.0 ];
let bkc = &[Boundkey::UP];
let blc = &[ -INF ];
let buc = &[2.5];
let bkx = &[Boundkey::LO,
Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = &[0.0,
0.0,
0.0,
0.0 ];
let bux = &[INF,
INF,
INF,
INF];
let ptrb = &[0i64, 1, 2, 3];
let ptre = &[1i64, 2, 3, 4];
let aval = &[1.0, 1.0, 1.0, 1.0];
let asub = &[0i32, 0, 0, 0 ];
let intsub = &[0i32, 1, 2];
let inttype = &[Variabletype::TYPE_INT,
Variabletype::TYPE_INT,
Variabletype::TYPE_INT ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon, numvar,
c, 0.0,
ptrb, ptre,
asub, aval,
bkc, blc, buc,
bkx, blx, bux)?;
task.put_var_type_list(intsub, inttype)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MAXIMIZE)?;
// Assign values to integer variables
// We only set that slice of xx
task.put_xx_slice(Soltype::ITG, 0, 3, &[1.0,1.0,0.0])?;
// Request constructing the solution from integer variable values
task.put_int_param(mosek::Iparam::MIO_CONSTRUCT_SOL, mosek::Onoffkey::ON)?;
// solve
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::LOG)?;
// Read and print solution
let mut xx = vec![0.0; numvar as usize];
task.get_xx(mosek::Soltype::ITG, xx.as_mut_slice())?;
println!("Optimal solution:");
for (i,xi) in xx.iter().enumerate() {
println!("x[{}] = {}",i,*xi);
}
// Was the initial solution used?
let constr = task.get_int_inf(mosek::Iinfitem::MIO_CONSTRUCT_SOLUTION)?;
let constr_val = task.get_dou_inf(mosek::Dinfitem::MIO_CONSTRUCT_SOLUTION_OBJ)?;
println!("Construct solution utilization: {}", constr);
println!("Construct solution objective: {}", constr_val);
Ok(())
}
More examples
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
fn solve() -> Result<(),String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.put_obj_name("solvebasis")?;
let numcon : i32 = 2;
let numvar : i32 = 2;
let mut w1 = vec![2.0, 6.0];
let mut w2 = vec![1.0, 0.0];
task.input_data(numcon, numvar,
&[1.0, 1.0], // c
0.0, // cfix
&[0,2], // ptrb
&[2,3], // ptre
&[0,1,
0,1], // sub
&[1.0, 1.0,
2.0, 1.0], // val
&[Boundkey::UP,
Boundkey::UP], // bkc
&[0.0,0.0], // blc
&[2.0,6.0], // buc
&[Boundkey::LO,
Boundkey::LO], // bkx
&[0.0, 0.0], // blx
&[0.0,0.0])?; // bux;
task.put_obj_sense(Objsense::MAXIMIZE)?;
let _ = task.optimize()?;
let mut basis = vec![0i32; numcon as usize];
task.init_basis_solve(basis.as_mut_slice())?;
// List basis variables corresponding to columns of B
let mut varsub = vec![0i32, 1];
for i in 0..numcon {
if basis[varsub[i as usize] as usize] < numcon {
println!("Basis variable no {} is xc{}",i,basis[varsub[i as usize] as usize]);
}
else {
println!("Basis variable no {} is x{}",i,basis[i as usize]-numcon);
// solve Bx = w1
// varsub contains index of non-zeros in b.
// On return b contains the solution x and
// varsub the index of the non-zeros in x.
{
let nz = task.solve_with_basis(false, 2, varsub.as_mut_slice(), w1.as_mut_slice())?;
println!("nz = {}",nz);
println!("Solution to Bx = {:?}",w1);
for vsubi in &varsub[0..nz as usize] {
if basis[*vsubi as usize] < numcon {
println!("xc {} = {}",basis[*vsubi as usize],w1[*vsubi as usize]);
}
else {
println!("x{} = {}",basis[*vsubi as usize] - numcon,w1[*vsubi as usize])
}
}
}
// Solve B^Tx = w2
{
varsub[0] = 1;
let nz = task.solve_with_basis(true,1,varsub.as_mut_slice(),w2.as_mut_slice())?;
println!("nz = {}",nz);
println!("Solution to B^Tx = {:?}",w2);
for vsubi in &varsub[0..nz as usize] {
if basis[*vsubi as usize] < numcon {
print!("xc{} = {}",basis[*vsubi as usize],w2[*vsubi as usize]);
}
else {
print!("x{} = {}",basis[*vsubi as usize] - numcon,w2[*vsubi as usize]);
}
}
}
}
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
fn main() -> Result<(),String> {
let bkc = vec![
Boundkey::UP, Boundkey::UP,
Boundkey::UP, Boundkey::FX,
Boundkey::FX, Boundkey::FX,
Boundkey::FX ];
let bkx = vec![
Boundkey::LO, Boundkey::LO,
Boundkey::LO, Boundkey::LO,
Boundkey::LO, Boundkey::LO,
Boundkey::LO ];
let ptr = [0i64, 2, 4, 6, 8, 10, 12, 14];
let sub = [0i32, 3, 0, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6];
let blc = [ -INFINITY, -INFINITY, -INFINITY, 800.0, 100.0, 500.0, 500.0 ];
let buc = [400.0, 1200.0, 1000.0, 800.0, 100.0, 500.0, 500.0];
let c = [1.0, 2.0, 5.0, 2.0, 1.0, 2.0, 1.0];
let blx = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
let bux = [INFINITY, INFINITY,
INFINITY, INFINITY,
INFINITY, INFINITY,
INFINITY];
let val = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let numcon = 7; /* Number of constraints. */
let numvar = 7; /* Number of variables. */
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
/* Directs the log task stream to the 'printstr' function. */
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon as i32, numvar as i32,
&c,
0.0,
&ptr[0..numvar as usize],
&ptr[1..numvar as usize+1],
&sub,
&val,
&bkc,
&blc,
&buc,
&bkx,
&blx,
&bux)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MINIMIZE)?;
task.optimize()?;
/* Analyze upper bound on c1 and the equality constraint on c4 */
let mut subi = vec![0i32, 3i32];
let mut marki = vec![Mark::UP, Mark::UP];
/* Analyze lower bound on the variables x12 and x31 */
let mut subj = vec![1i32, 4];
let mut markj = vec![Mark::LO, Mark::LO];
let mut leftpricei = vec![0.0; 2];
let mut rightpricei = vec![0.0; 2];
let mut leftrangei = vec![0.0; 2];
let mut rightrangei = vec![0.0; 2];
let mut leftpricej = vec![0.0; 2];
let mut rightpricej = vec![0.0; 2];
let mut leftrangej = vec![0.0; 2];
let mut rightrangej = vec![0.0; 2];
task.primal_sensitivity(subi.as_mut_slice(),
marki.as_mut_slice(),
subj.as_mut_slice(),
markj.as_mut_slice(),
leftpricei.as_mut_slice(),
rightpricei.as_mut_slice(),
leftrangei.as_mut_slice(),
rightrangei.as_mut_slice(),
leftpricej.as_mut_slice(),
rightpricej.as_mut_slice(),
leftrangej.as_mut_slice(),
rightrangej.as_mut_slice())?;
println!("Results from sensitivity analysis on bounds:");
println!("For constraints:");
for i in 0..2 {
println!("leftprice = {:.5e}, rightprice = {:.5e}, leftrange = {:.5e}, rightrange = {:.5e}",
leftpricei[i], rightpricei[i], leftrangei[i], rightrangei[i]);
}
println!("For variables:\n");
for i in 0..2 {
println!("leftprice = {:.5e}, rightprice = {:.5e}, leftrange = {:.5e}, rightrange = {:.5e}",
leftpricej[i], rightpricej[i], leftrangej[i], rightrangej[i]);
}
let mut leftprice = vec![0.0; 2];
let mut rightprice = vec![0.0; 2];
let mut leftrange = vec![0.0; 2];
let mut rightrange = vec![0.0; 2];
let subc = [2i32, 5i32];
task.dual_sensitivity(&subc,
leftprice.as_mut_slice(),
rightprice.as_mut_slice(),
leftrange.as_mut_slice(),
rightrange.as_mut_slice())?;
println!("Results from sensitivity analysis on objective coefficients:");
for i in 0..2 {
println!("leftprice = {:.5e}, rightprice = {:.5e}, leftrange = {:.5e}, rightrange = {:.5e}",
leftprice[i], rightprice[i], leftrange[i], rightrange[i]);
}
return Result::Ok(());
}
sourcepub fn is_dou_par_name(
&self,
parname_: &str,
param_: &mut i32
) -> Result<(), String>
pub fn is_dou_par_name( &self, parname_: &str, param_: &mut i32 ) -> Result<(), String>
Checks a double parameter name.
§Arguments
-
parname_
Parameter name. -
param_
Returns the parameter corresponding to the name, if one exists.See Dparam
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.isdouparname
sourcepub fn is_int_par_name(
&self,
parname_: &str,
param_: &mut i32
) -> Result<(), String>
pub fn is_int_par_name( &self, parname_: &str, param_: &mut i32 ) -> Result<(), String>
Checks an integer parameter name.
§Arguments
-
parname_
Parameter name. -
param_
Returns the parameter corresponding to the name, if one exists.See Iparam
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.isintparname
sourcepub fn is_str_par_name(
&self,
parname_: &str,
param_: &mut i32
) -> Result<(), String>
pub fn is_str_par_name( &self, parname_: &str, param_: &mut i32 ) -> Result<(), String>
Checks a string parameter name.
§Arguments
-
parname_
Parameter name. -
param_
Returns the parameter corresponding to the name, if one exists.See Sparam
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.isstrparname
sourcepub fn link_file_to_stream(
&mut self,
whichstream_: i32,
filename_: &str,
append_: i32
) -> Result<(), String>
pub fn link_file_to_stream( &mut self, whichstream_: i32, filename_: &str, append_: i32 ) -> Result<(), String>
Directs all output from a task stream to a file.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
-
filename_
A valid file name. -
append_
If this argument is 0 the output file will be overwritten, otherwise it will be appended to.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.linkfiletotaskstream
sourcepub fn one_solution_summary(
&self,
whichstream_: i32,
whichsol_: i32
) -> Result<(), String>
pub fn one_solution_summary( &self, whichstream_: i32, whichsol_: i32 ) -> Result<(), String>
Prints a short summary of a specified solution.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
-
whichsol_
Selects a solution.See Soltype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.onesolutionsummary
sourcepub fn optimize_rmt(
&mut self,
address_: &str,
accesstoken_: &str,
trmcode_: &mut i32
) -> Result<(), String>
pub fn optimize_rmt( &mut self, address_: &str, accesstoken_: &str, trmcode_: &mut i32 ) -> Result<(), String>
Offload the optimization task to a solver server and wait for the solution.
§Arguments
-
address_
Address of the OptServer. -
accesstoken_
Access token. -
trmcode_
Is either OK or a termination response code.See Rescode
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.optimizermt
sourcepub fn optimizer_summary(&self, whichstream_: i32) -> Result<(), String>
pub fn optimizer_summary(&self, whichstream_: i32) -> Result<(), String>
Prints a short summary with optimizer statistics from last optimization.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.optimizersummary
sourcepub fn optimize(&mut self) -> Result<i32, String>
pub fn optimize(&mut self) -> Result<i32, String>
Optimizes the problem.
§Returns
trmcode
Is either OK or a termination response code.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.optimizetrm
Examples found in repository?
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
fn opt_server_sync(inputfile : FileOrText, addr : String, cert : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Load some data into the task
match inputfile {
FileOrText::File(filename) => task.read_data(filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Set OptServer URL
task.put_optserver_host(addr.as_str())?;
// Path to certificate, if any
if let Some(cert) = cert {
task.put_str_param(Sparam::REMOTE_TLS_CERT_PATH, cert.as_str())?;
}
// Optimize remotely, no access token
let _trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
Ok(())
}
More examples
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
fn feasrepairex1(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
match filename {
FileOrText::File(fname) => task.read_data(fname.as_str())?,
FileOrText::Text(data) => task.read_lp_string(data.as_str())?
}
task.put_int_param(mosek::Iparam::LOG_FEAS_REPAIR, 3)?;
let wc = vec![1.0; task.get_num_con()? as usize];
let wx = vec![1.0; task.get_num_var()? as usize];
task.primal_repair(wc.as_slice(),wc.as_slice(),wx.as_slice(),wx.as_slice())?;
let sum_viol = task.get_dou_inf(mosek::Dinfitem::PRIMAL_REPAIR_PENALTY_OBJ)?;
println!("Minimized sum of violations = {}", sum_viol);
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::MSG)?;
Ok(())
}
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
fn simple(filename : FileOrText, outfile : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(fname) => {
task.read_data(fname.as_str())?
},
FileOrText::Text(data) => {
task.read_ptf_string(data.as_str())?
}
}
// Solve the problem
let _ = task.optimize()?;
// Print a summary of the solution
task.solution_summary(Streamtype::LOG)?;
// If an output file was specified, save problem to file
if let Some(outfile) = outfile {
// If using OPF format, these parameters will specify what to include in output
task.put_int_param(Iparam::OPF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_PROBLEM, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_HINTS, Onoffkey::OFF)?;
task.put_int_param(Iparam::OPF_WRITE_PARAMETERS, Onoffkey::OFF)?;
task.put_int_param(Iparam::PTF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.write_data(outfile.as_str())?;
}
Ok(())
}
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
fn main() -> Result<(),String> {
let args: Vec<String> = env::args().collect();
let mut task = Task::new().unwrap().with_callbacks();
if args.len() < 2 {
task.read_ptf_string(CQO1_PTF)?;
}
else {
task.read_data(args[1].as_str())?;
}
// Perform optimization.
let trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Handle solution status. We expect Optimal
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
// Fetch and print the solution
println!("An optimal interior point solution is located.");
let numvar = task.get_num_var()?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR, xx.as_mut_slice())?;
println!("xx = {:?}",xx)
},
Solsta::DUAL_INFEAS_CER =>
println!("Dual infeasibility certificate found."),
Solsta::PRIM_INFEAS_CER =>
println!("Primal infeasibility certificate found."),
Solsta::UNKNOWN => {
// The solutions status is unknown. The termination code
// indicates why the optimizer terminated prematurely.
println!("The solution status is unknown.");
let (symname,desc) = mosek::get_code_desc(trm)?;
println!(" Termination code: {} {}\n", symname, desc)
},
_ =>
println!("Unexpected solution status {}\n",solsta)
}
Ok(())
}
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
- examples/mico1.rs
- examples/mioinitsol.rs
- examples/acc1.rs
- examples/acc2.rs
- examples/pow1.rs
- examples/gp1.rs
- examples/portfolio_1_basic.rs
- examples/solvebasis.rs
- examples/djc1.rs
- examples/sdo_lmi.rs
- examples/lo2.rs
- examples/sdo2.rs
- examples/qo1.rs
- examples/qcqo1.rs
- examples/solutionquality.rs
- examples/portfolio_6_factor.rs
- examples/lo1.rs
- examples/cqo1.rs
- examples/sensitivity.rs
- examples/portfolio_4_transcost.rs
- examples/portfolio_3_impact.rs
- examples/sdo1.rs
sourcepub fn primal_repair(
&mut self,
wlc_: &[f64],
wuc_: &[f64],
wlx_: &[f64],
wux_: &[f64]
) -> Result<(), String>
pub fn primal_repair( &mut self, wlc_: &[f64], wuc_: &[f64], wlx_: &[f64], wux_: &[f64] ) -> Result<(), String>
Repairs a primal infeasible optimization problem by adjusting the bounds on the constraints and variables.
§Arguments
wlc_
Weights associated with relaxing lower bounds on the constraints.wuc_
Weights associated with relaxing the upper bound on the constraints.wlx_
Weights associated with relaxing the lower bounds of the variables.wux_
Weights associated with relaxing the upper bounds of variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.primalrepair
Examples found in repository?
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
fn feasrepairex1(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
match filename {
FileOrText::File(fname) => task.read_data(fname.as_str())?,
FileOrText::Text(data) => task.read_lp_string(data.as_str())?
}
task.put_int_param(mosek::Iparam::LOG_FEAS_REPAIR, 3)?;
let wc = vec![1.0; task.get_num_con()? as usize];
let wx = vec![1.0; task.get_num_var()? as usize];
task.primal_repair(wc.as_slice(),wc.as_slice(),wx.as_slice(),wx.as_slice())?;
let sum_viol = task.get_dou_inf(mosek::Dinfitem::PRIMAL_REPAIR_PENALTY_OBJ)?;
println!("Minimized sum of violations = {}", sum_viol);
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::MSG)?;
Ok(())
}
sourcepub fn primal_sensitivity(
&mut self,
subi_: &[i32],
marki_: &[i32],
subj_: &[i32],
markj_: &[i32],
leftpricei_: &mut [f64],
rightpricei_: &mut [f64],
leftrangei_: &mut [f64],
rightrangei_: &mut [f64],
leftpricej_: &mut [f64],
rightpricej_: &mut [f64],
leftrangej_: &mut [f64],
rightrangej_: &mut [f64]
) -> Result<(), String>
pub fn primal_sensitivity( &mut self, subi_: &[i32], marki_: &[i32], subj_: &[i32], markj_: &[i32], leftpricei_: &mut [f64], rightpricei_: &mut [f64], leftrangei_: &mut [f64], rightrangei_: &mut [f64], leftpricej_: &mut [f64], rightpricej_: &mut [f64], leftrangej_: &mut [f64], rightrangej_: &mut [f64] ) -> Result<(), String>
Perform sensitivity analysis on bounds.
§Arguments
-
subi_
Indexes of constraints to analyze. -
marki_
Mark which constraint bounds to analyze.See Mark
-
subj_
Indexes of variables to analyze. -
markj_
Mark which variable bounds to analyze.See Mark
-
leftpricei_
Left shadow price for constraints. -
rightpricei_
Right shadow price for constraints. -
leftrangei_
Left range for constraints. -
rightrangei_
Right range for constraints. -
leftpricej_
Left shadow price for variables. -
rightpricej_
Right shadow price for variables. -
leftrangej_
Left range for variables. -
rightrangej_
Right range for variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.primalsensitivity
Examples found in repository?
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
fn main() -> Result<(),String> {
let bkc = vec![
Boundkey::UP, Boundkey::UP,
Boundkey::UP, Boundkey::FX,
Boundkey::FX, Boundkey::FX,
Boundkey::FX ];
let bkx = vec![
Boundkey::LO, Boundkey::LO,
Boundkey::LO, Boundkey::LO,
Boundkey::LO, Boundkey::LO,
Boundkey::LO ];
let ptr = [0i64, 2, 4, 6, 8, 10, 12, 14];
let sub = [0i32, 3, 0, 4, 1, 5, 1, 6, 2, 3, 2, 5, 2, 6];
let blc = [ -INFINITY, -INFINITY, -INFINITY, 800.0, 100.0, 500.0, 500.0 ];
let buc = [400.0, 1200.0, 1000.0, 800.0, 100.0, 500.0, 500.0];
let c = [1.0, 2.0, 5.0, 2.0, 1.0, 2.0, 1.0];
let blx = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
let bux = [INFINITY, INFINITY,
INFINITY, INFINITY,
INFINITY, INFINITY,
INFINITY];
let val = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let numcon = 7; /* Number of constraints. */
let numvar = 7; /* Number of variables. */
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
/* Directs the log task stream to the 'printstr' function. */
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon as i32, numvar as i32,
&c,
0.0,
&ptr[0..numvar as usize],
&ptr[1..numvar as usize+1],
&sub,
&val,
&bkc,
&blc,
&buc,
&bkx,
&blx,
&bux)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MINIMIZE)?;
task.optimize()?;
/* Analyze upper bound on c1 and the equality constraint on c4 */
let mut subi = vec![0i32, 3i32];
let mut marki = vec![Mark::UP, Mark::UP];
/* Analyze lower bound on the variables x12 and x31 */
let mut subj = vec![1i32, 4];
let mut markj = vec![Mark::LO, Mark::LO];
let mut leftpricei = vec![0.0; 2];
let mut rightpricei = vec![0.0; 2];
let mut leftrangei = vec![0.0; 2];
let mut rightrangei = vec![0.0; 2];
let mut leftpricej = vec![0.0; 2];
let mut rightpricej = vec![0.0; 2];
let mut leftrangej = vec![0.0; 2];
let mut rightrangej = vec![0.0; 2];
task.primal_sensitivity(subi.as_mut_slice(),
marki.as_mut_slice(),
subj.as_mut_slice(),
markj.as_mut_slice(),
leftpricei.as_mut_slice(),
rightpricei.as_mut_slice(),
leftrangei.as_mut_slice(),
rightrangei.as_mut_slice(),
leftpricej.as_mut_slice(),
rightpricej.as_mut_slice(),
leftrangej.as_mut_slice(),
rightrangej.as_mut_slice())?;
println!("Results from sensitivity analysis on bounds:");
println!("For constraints:");
for i in 0..2 {
println!("leftprice = {:.5e}, rightprice = {:.5e}, leftrange = {:.5e}, rightrange = {:.5e}",
leftpricei[i], rightpricei[i], leftrangei[i], rightrangei[i]);
}
println!("For variables:\n");
for i in 0..2 {
println!("leftprice = {:.5e}, rightprice = {:.5e}, leftrange = {:.5e}, rightrange = {:.5e}",
leftpricej[i], rightpricej[i], leftrangej[i], rightrangej[i]);
}
let mut leftprice = vec![0.0; 2];
let mut rightprice = vec![0.0; 2];
let mut leftrange = vec![0.0; 2];
let mut rightrange = vec![0.0; 2];
let subc = [2i32, 5i32];
task.dual_sensitivity(&subc,
leftprice.as_mut_slice(),
rightprice.as_mut_slice(),
leftrange.as_mut_slice(),
rightrange.as_mut_slice())?;
println!("Results from sensitivity analysis on objective coefficients:");
for i in 0..2 {
println!("leftprice = {:.5e}, rightprice = {:.5e}, leftrange = {:.5e}, rightrange = {:.5e}",
leftprice[i], rightprice[i], leftrange[i], rightrange[i]);
}
return Result::Ok(());
}
sourcepub fn print_param(&self) -> Result<(), String>
pub fn print_param(&self) -> Result<(), String>
Prints the current parameter settings.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.printparam
sourcepub fn put_acc(
&mut self,
accidx_: i64,
domidx_: i64,
afeidxlist_: &[i64],
b_: &[f64]
) -> Result<(), String>
pub fn put_acc( &mut self, accidx_: i64, domidx_: i64, afeidxlist_: &[i64], b_: &[f64] ) -> Result<(), String>
Puts an affine conic constraint.
§Arguments
accidx_
Affine conic constraint index.domidx_
Domain index.afeidxlist_
List of affine expression indexes.b_
The vector of constant terms modifying affine expressions. Optional.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putacc
sourcepub fn put_acc_b(&mut self, accidx_: i64, b_: &[f64]) -> Result<(), String>
pub fn put_acc_b(&mut self, accidx_: i64, b_: &[f64]) -> Result<(), String>
Puts the constant vector b in an affine conic constraint.
§Arguments
accidx_
Affine conic constraint index.b_
The vector of constant terms modifying affine expressions. Optional.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putaccb
sourcepub fn put_acc_b_j(
&mut self,
accidx_: i64,
j_: i64,
bj_: f64
) -> Result<(), String>
pub fn put_acc_b_j( &mut self, accidx_: i64, j_: i64, bj_: f64 ) -> Result<(), String>
Sets one element in the b vector of an affine conic constraint.
§Arguments
accidx_
Affine conic constraint index.j_
The index of an element in b to change.bj_
The new value of b[j].
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putaccbj
sourcepub fn put_acc_dot_y(
&self,
whichsol_: i32,
accidx_: i64,
doty_: &mut [f64]
) -> Result<(), String>
pub fn put_acc_dot_y( &self, whichsol_: i32, accidx_: i64, doty_: &mut [f64] ) -> Result<(), String>
Puts the doty vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
accidx_
The index of the affine conic constraint. -
doty_
The dual values for this affine conic constraint. The array should have length equal to the dimension of the constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putaccdoty
sourcepub fn put_acc_list(
&mut self,
accidxs_: &[i64],
domidxs_: &[i64],
afeidxlist_: &[i64],
b_: &[f64]
) -> Result<(), String>
pub fn put_acc_list( &mut self, accidxs_: &[i64], domidxs_: &[i64], afeidxlist_: &[i64], b_: &[f64] ) -> Result<(), String>
Puts a number of affine conic constraints.
§Arguments
accidxs_
Affine conic constraint indices.domidxs_
Domain indices.afeidxlist_
List of affine expression indexes.b_
The vector of constant terms modifying affine expressions. Optional.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putacclist
sourcepub fn put_acc_name(&mut self, accidx_: i64, name_: &str) -> Result<(), String>
pub fn put_acc_name(&mut self, accidx_: i64, name_: &str) -> Result<(), String>
Sets the name of an affine conic constraint.
§Arguments
accidx_
Index of the affine conic constraint.name_
The name of the affine conic constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putaccname
Examples found in repository?
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
More examples
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
fn portfolio(w : f64,
mu : &[f64],
x0 : &[f64],
gammas : &[f64],
theta : &[f64],
GT : &Matrix) -> Result<Vec<(f64,f64)>,String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
let (kx,nx) = GT.size();
if mu.len() != nx { panic!("Mismatching data"); }
let k : i32 = kx.try_into().unwrap();
let n : i32 = nx.try_into().unwrap();
let total_budget : f64 = w + x0.iter().sum::<f64>();
//Offset of variables into the API variable.
let numvar = n;
let voff_x : i32 = 0;
// Constraint offset
let coff_bud : i32 = 0;
// Holding variable x of length n
// No other auxiliary variables are needed in this formulation
task.append_vars(numvar)?;
// Setting up variable x
for j in 0..n {
task.put_var_name(voff_x+j,format!("x[{}]",j+1).as_str())?;
}
task.put_var_bound_slice_const(voff_x,voff_x+n, Boundkey::LO,0.0, INF)?;
// One linear constraint: total budget
task.append_cons(1)?;
task.put_con_name(coff_bud, "budget")?;
/* Coefficients in the first row of A */
for j in 0..n {
task.put_aij(coff_bud,voff_x + j, 1.0)?;
}
task.put_con_bound(coff_bud, Boundkey::FX, total_budget, total_budget)?;
// Input (gamma, G_factor_T x, diag(sqrt(theta))*x) in the AFE (affine expression) storage
// We need k+n+1 rows and we fill them in in three parts
task.append_afes((k+n) as i64 + 1)?;
// 1. The first affine expression = gamma, will be specified later
// 2. The next k expressions comprise G_factor_T*x, we add them row by row
// transposing the matrix G_factor on the fly
task.put_afe_f_row_list((1..1+k as i64).collect::<Vec<i64>>().as_slice(), // f row idxs
vec![n; k as usize].as_slice(), // row lengths
(0..GT.len() as i64).step_by(n as usize).collect::<Vec<i64>>().as_slice(), // row ptr
iproduct!(0..k,0..n).map(|(_,b)| b).collect::<Vec<i32>>().as_slice(), // varidx, 0..n repeated k times
GT.data_by_row().as_slice())?;
// 3. The remaining n rows contain sqrt(theta) on the diagonal
for (i,thetai) in (0..n).zip(theta.iter()) {
task.put_afe_f_entry(i as i64 + 1 + k as i64, voff_x + i, thetai.sqrt())?;
}
// Input the affine conic constraint (gamma, GT*x) \in QCone
// Add the quadratic domain of dimension k+1
let qdom = task.append_quadratic_cone_domain(k as i64+ 1)?;
// Add the constraint
task.append_acc_seq(qdom, 0, vec![0.0; k as usize+1].as_slice())?;
task.put_acc_name(0, "risk")?;
// Objective: maximize expected return mu^T x
for (j,&muj) in (0..n).zip(mu.iter()) {
task.put_c_j(voff_x + j, muj)?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
Ok(gammas.iter().filter_map(|&gamma| {
// Specify gamma in ACC
task.put_afe_g(0, gamma).ok()?;
task.optimize().ok()?;
/* Display solution summary for quick inspection of results */
let _ = task.solution_summary(Streamtype::LOG);
let _ = task.write_data(format!("portfolio_6_factor-{}.ptf",gamma).as_str());
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR).ok()? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Read the results */
let mut xx = vec![0.0; n as usize];
task.get_xx_slice(Soltype::ITR, voff_x, voff_x + n, xx.as_mut_slice()).ok()?;
Some((gamma,xx.iter().zip(mu.iter()).map(|(&xj,&muj)| xj*muj).sum::<f64>()))
}).collect::<Vec<(f64,f64)>>())
}
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 129 130
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn put_a_col(
&mut self,
j_: i32,
subj_: &[i32],
valj_: &[f64]
) -> Result<(), String>
pub fn put_a_col( &mut self, j_: i32, subj_: &[i32], valj_: &[f64] ) -> Result<(), String>
Replaces all elements in one column of the linear constraint matrix.
§Arguments
j_
Column index.subj_
Row indexes of non-zero values in column.valj_
New non-zero values of column.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putacol
Examples found in repository?
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 129 130 131 132 133 134 135 136 137
fn main() -> Result<(),String> {
let c = vec![ 0.0,-1.0,0.0 ];
let bkc = vec![ mosek::Boundkey::LO ];
let blc = vec![ 1.0 ];
let buc = vec![ INF ];
let bkx = vec![ Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = vec![ 0.0,
0.0,
0.0 ];
let bux = vec![ INF,
INF,
INF ];
let aptrb = vec![ 0, 1, 2 ];
let aptre = vec![ 1, 2, 3 ];
let asub = vec![ 0, 0, 0 ];
let aval = vec![ 1.0, 1.0, 1.0 ];
let qsubi = vec![ 0, 1, 2, 2 ];
let qsubj = vec![ 0, 1, 0, 2 ];
let qval = vec![ 2.0,0.2,-1.0,2.0 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
//r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for j in 0..NUMVAR
{
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32,c[j])?;
/* Set the bounds on variable j.
* blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, /* Index of variable.*/
bkx[j], /* Bound key.*/
blx[j], /* Numerical value of lower bound.*/
bux[j])?; /* Numerical value of upper bound.*/
/* Input column j of A */
task.put_a_col(j as i32, /* Variable (column) index.*/
&asub[aptrb[j]..aptre[j]], /* Pointer to row indexes of column j.*/
&aval[aptrb[j]..aptre[j]])?; /* Pointer to Values of column j.*/
}
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
for i in 0..NUMCON
{
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
/*
* The lower triangular part of the Q
* matrix in the objective is specified.
*/
/* Input the Q for the objective. */
task.put_q_obj(&qsubi,&qsubj,&qval)?;
}
let _trmcode = task.optimize()?;
/* Run optimizer */
/* Print a summary containing information
about the solution for debugging purposes*/
task.solution_summary(Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0, 0.0, 0.0];
task.get_xx(Soltype::ITR, /* Request the interior solution. */
& mut xx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR
{
println!("x[{}]: {}",j,xx[j]);
}
}
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.");
}
}
return Ok(());
}
More examples
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 129 130 131 132 133 134 135 136 137 138 139 140
fn main() -> Result<(),String> {
const NUMCON : i32 = 1; /* Number of constraints. */
const NUMVAR : i32 = 3; /* Number of variables. */
let c = [0.0, -1.0, 0.0];
let bkc = [Boundkey::LO];
let blc = [1.0];
let buc = [INF];
let bkx = [Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = [0.0,
0.0,
0.0 ];
let bux = [INF,
INF,
INF ];
let asub = [ &[0i32], &[0i32], &[0i32] ];
let aval = [ &[1.0], &[1.0], &[1.0] ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Give MOSEK an estimate of the size of the input data.
// This is done to increase the speed of inputting data.
// However, it is optional.
// Append 'numcon' empty constraints.
// The constraints will initially have no bounds.
task.append_cons(NUMCON)?;
// Append 'numvar' variables.
// The variables will initially be fixed at zero (x=0).
task.append_vars(NUMVAR)?;
for (j,cj,bkj,blj,buj) in izip!(0..NUMVAR,c,bkx,blx,bux) {
// Set the linear term c_j in the objective.
task.put_c_j(j, cj)?;
// Set the bounds on variable j.
// blx[j] <= x_j <= bux[j]
task.put_var_bound(j, bkj, blj, buj)?;
}
for (j,asubj,avalj) in izip!(0..NUMVAR, asub, aval) {
/* Input column j of A */
task.put_a_col(j, /* Variable (column) index.*/
asubj, /* Row index of non-zeros in column j.*/
avalj)?; /* Non-zero Values of column j. */
}
// Set the bounds on constraints.
// for i=1, ...,numcon : blc[i] <= constraint i <= buc[i]
for (i,bki,bli,bui) in izip!(0..NUMCON,bkc,blc,buc) {
task.put_con_bound(i, bki, bli, bui)?;
}
{
// The lower triangular part of the Q
// matrix in the objective is specified.
let qosubi = &[ 0, 1, 2, 2 ];
let qosubj = &[ 0, 1, 0, 2 ];
let qoval = &[ 2.0, 0.2, -1.0, 2.0 ];
// Input the Q for the objective.
task.put_q_obj(qosubi, qosubj, qoval)?;
}
// The lower triangular part of the Q^0
// matrix in the first constraint is specified.
// This corresponds to adding the term
// x0^2 - x1^2 - 0.1 x2^2 + 0.2 x0 x2
{
let qsubi = &[0, 1, 2, 2 ];
let qsubj = &[0, 1, 2, 0 ];
let qval = &[-2.0, -2.0, -0.2, 0.2];
/* put Q^0 in constraint with index 0. */
task.put_q_con_k(0,
qsubi,
qsubj,
qval)?;
}
task.put_obj_sense(Objsense::MINIMIZE)?;
/* Solve the problem */
let _trm = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
let mut xx = vec![0.0; NUMVAR as usize];
task.get_xx(Soltype::ITR, // Interior solution.
xx.as_mut_slice())?;
match solsta {
Solsta::OPTIMAL => {
println!("Optimal primal solution");
for (j,xj) in izip!(0..NUMVAR,xx) {
println!("x[{}]: {}",j,xj);
}
},
Solsta::DUAL_INFEAS_CER|
Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility.\n"),
Solsta::UNKNOWN =>
println!("Unknown solution status.\n"),
_ =>
println!("Other solution status")
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
fn main() -> Result<(),String> {
let numvar = 4;
let numcon = 3;
let c = vec![3.0, 1.0, 5.0, 1.0];
/* Below is the sparse representation of the A
* matrix stored by column. */
let aptrb = vec![ 0, 2, 5, 7 ];
let aptre = vec![ 2, 5, 7, 9 ];
let asub = vec![ 0, 1,
0, 1, 2,
0, 1,
1, 2 ];
let aval = vec![ 3.0, 2.0,
1.0, 1.0, 2.0,
2.0, 3.0,
1.0, 3.0 ];
/* Bounds on constraints. */
let bkc = vec![ Boundkey::FX, Boundkey::LO, Boundkey::UP ];
let blc = vec![ 30.0, 15.0, -INF ];
let buc = vec![ 30.0, INF, 25.0 ];
/* Bounds on variables. */
let bkx = vec![ Boundkey::LO, Boundkey::RA, Boundkey::LO, Boundkey::LO ];
let blx = vec![ 0.0, 0.0, 0.0, 0.0 ];
let bux = vec![ INF, 10.0, INF, INF ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
/* Directs the log task stream to the 'printstr' function. */
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(numcon as i32)?;
/* Append 'numvar' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar as i32)?;
for j in 0..numvar
{
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32,c[j])?;
/* Set the bounds on variable j.
* blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, /* Index of variable.*/
bkx[j], /* Bound key.*/
blx[j], /* Numerical value of lower bound.*/
bux[j])?; /* Numerical value of upper bound.*/
/* Input column j of A */
task.put_a_col(j as i32, /* Variable (column) index.*/
& asub[aptrb[j]..aptre[j]], /* Pointer to row indexes of column j.*/
& aval[aptrb[j]..aptre[j]])?; /* Pointer to Values of column j.*/
}
/* Set the bounds on constraints.
* for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for i in 0..numcon {
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
}
/* Maximize objective function. */
task.put_obj_sense(Objsense::MAXIMIZE)?;
/* Run optimizer */
let _trmcode = task.optimize()?;
/* Print a summary containing information
* about the solution for debugging purposes. */
task.solution_summary(Streamtype::LOG)?;
let solsta = task.get_sol_sta(Soltype::BAS)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0,0.0,0.0,0.0];
task.get_xx(Soltype::BAS, /* Request the basic solution. */
& mut xx[..])?;
println!("Optimal primal solution");
for j in 0..numvar as usize
{
println!("x[{}]: {}",j,xx[j]);
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN =>
{
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",solsta);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn put_a_col_list(
&mut self,
sub_: &[i32],
ptrb_: &[i64],
ptre_: &[i64],
asub_: &[i32],
aval_: &[f64]
) -> Result<(), String>
pub fn put_a_col_list( &mut self, sub_: &[i32], ptrb_: &[i64], ptre_: &[i64], asub_: &[i32], aval_: &[f64] ) -> Result<(), String>
Replaces all elements in several columns the linear constraint matrix.
§Arguments
sub_
Indexes of columns that should be replaced.ptrb_
Array of pointers to the first element in the columns.ptre_
Array of pointers to the last element plus one in the columns.asub_
Row indexesaval_
Coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putacollist64
sourcepub fn put_a_col_slice(
&mut self,
first_: i32,
last_: i32,
ptrb_: &[i64],
ptre_: &[i64],
asub_: &[i32],
aval_: &[f64]
) -> Result<(), String>
pub fn put_a_col_slice( &mut self, first_: i32, last_: i32, ptrb_: &[i64], ptre_: &[i64], asub_: &[i32], aval_: &[f64] ) -> Result<(), String>
Replaces all elements in a sequence of columns the linear constraint matrix.
§Arguments
first_
First column in the slice.last_
Last column plus one in the slice.ptrb_
Array of pointers to the first element in the columns.ptre_
Array of pointers to the last element plus one in the columns.asub_
Row indexesaval_
Coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putacolslice64
sourcepub fn put_afe_barf_block_triplet(
&mut self,
afeidx_: &[i64],
barvaridx_: &[i32],
subk_: &[i32],
subl_: &[i32],
valkl_: &[f64]
) -> Result<(), String>
pub fn put_afe_barf_block_triplet( &mut self, afeidx_: &[i64], barvaridx_: &[i32], subk_: &[i32], subl_: &[i32], valkl_: &[f64] ) -> Result<(), String>
Inputs barF in block triplet form.
§Arguments
afeidx_
Constraint index.barvaridx_
Symmetric matrix variable index.subk_
Block row index.subl_
Block column index.valkl_
The numerical value associated with each block triplet.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafebarfblocktriplet
Examples found in repository?
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
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(())
}
sourcepub fn put_afe_barf_entry(
&mut self,
afeidx_: i64,
barvaridx_: i32,
termidx_: &[i64],
termweight_: &[f64]
) -> Result<(), String>
pub fn put_afe_barf_entry( &mut self, afeidx_: i64, barvaridx_: i32, termidx_: &[i64], termweight_: &[f64] ) -> Result<(), String>
Inputs one entry in barF.
§Arguments
afeidx_
Row index of barF.barvaridx_
Semidefinite variable index.termidx_
Element indices in matrix storage.termweight_
Weights in the weighted sum.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafebarfentry
sourcepub fn put_afe_barf_entry_list(
&mut self,
afeidx_: &[i64],
barvaridx_: &[i32],
numterm_: &[i64],
ptrterm_: &[i64],
termidx_: &[i64],
termweight_: &[f64]
) -> Result<(), String>
pub fn put_afe_barf_entry_list( &mut self, afeidx_: &[i64], barvaridx_: &[i32], numterm_: &[i64], ptrterm_: &[i64], termidx_: &[i64], termweight_: &[f64] ) -> Result<(), String>
Inputs a list of entries in barF.
§Arguments
afeidx_
Row indexes of barF.barvaridx_
Semidefinite variable indexes.numterm_
Number of terms in the weighted sums.ptrterm_
Pointer to the terms forming each entry.termidx_
Concatenated element indexes in matrix storage.termweight_
Concatenated weights in the weighted sum.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafebarfentrylist
sourcepub fn put_afe_barf_row(
&mut self,
afeidx_: i64,
barvaridx_: &[i32],
numterm_: &[i64],
ptrterm_: &[i64],
termidx_: &[i64],
termweight_: &[f64]
) -> Result<(), String>
pub fn put_afe_barf_row( &mut self, afeidx_: i64, barvaridx_: &[i32], numterm_: &[i64], ptrterm_: &[i64], termidx_: &[i64], termweight_: &[f64] ) -> Result<(), String>
Inputs a row of barF.
§Arguments
afeidx_
Row index of barF.barvaridx_
Semidefinite variable indexes.numterm_
Number of terms in the weighted sums.ptrterm_
Pointer to the terms forming each entry.termidx_
Concatenated element indexes in matrix storage.termweight_
Concatenated weights in the weighted sum.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafebarfrow
sourcepub fn put_afe_f_col(
&mut self,
varidx_: i32,
afeidx_: &[i64],
val_: &[f64]
) -> Result<(), String>
pub fn put_afe_f_col( &mut self, varidx_: i32, afeidx_: &[i64], val_: &[f64] ) -> Result<(), String>
Replaces all elements in one column of the F matrix in the affine expressions.
§Arguments
varidx_
Column index.afeidx_
Row indexes of non-zero values in the column.val_
New non-zero values in the column.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafefcol
sourcepub fn put_afe_f_entry(
&mut self,
afeidx_: i64,
varidx_: i32,
value_: f64
) -> Result<(), String>
pub fn put_afe_f_entry( &mut self, afeidx_: i64, varidx_: i32, value_: f64 ) -> Result<(), String>
Replaces one entry in F.
§Arguments
afeidx_
Row index in F.varidx_
Column index in F.value_
Value of the entry.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafefentry
Examples found in repository?
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
More examples
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
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
fn portfolio(w : f64,
mu : &[f64],
x0 : &[f64],
gammas : &[f64],
theta : &[f64],
GT : &Matrix) -> Result<Vec<(f64,f64)>,String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
let (kx,nx) = GT.size();
if mu.len() != nx { panic!("Mismatching data"); }
let k : i32 = kx.try_into().unwrap();
let n : i32 = nx.try_into().unwrap();
let total_budget : f64 = w + x0.iter().sum::<f64>();
//Offset of variables into the API variable.
let numvar = n;
let voff_x : i32 = 0;
// Constraint offset
let coff_bud : i32 = 0;
// Holding variable x of length n
// No other auxiliary variables are needed in this formulation
task.append_vars(numvar)?;
// Setting up variable x
for j in 0..n {
task.put_var_name(voff_x+j,format!("x[{}]",j+1).as_str())?;
}
task.put_var_bound_slice_const(voff_x,voff_x+n, Boundkey::LO,0.0, INF)?;
// One linear constraint: total budget
task.append_cons(1)?;
task.put_con_name(coff_bud, "budget")?;
/* Coefficients in the first row of A */
for j in 0..n {
task.put_aij(coff_bud,voff_x + j, 1.0)?;
}
task.put_con_bound(coff_bud, Boundkey::FX, total_budget, total_budget)?;
// Input (gamma, G_factor_T x, diag(sqrt(theta))*x) in the AFE (affine expression) storage
// We need k+n+1 rows and we fill them in in three parts
task.append_afes((k+n) as i64 + 1)?;
// 1. The first affine expression = gamma, will be specified later
// 2. The next k expressions comprise G_factor_T*x, we add them row by row
// transposing the matrix G_factor on the fly
task.put_afe_f_row_list((1..1+k as i64).collect::<Vec<i64>>().as_slice(), // f row idxs
vec![n; k as usize].as_slice(), // row lengths
(0..GT.len() as i64).step_by(n as usize).collect::<Vec<i64>>().as_slice(), // row ptr
iproduct!(0..k,0..n).map(|(_,b)| b).collect::<Vec<i32>>().as_slice(), // varidx, 0..n repeated k times
GT.data_by_row().as_slice())?;
// 3. The remaining n rows contain sqrt(theta) on the diagonal
for (i,thetai) in (0..n).zip(theta.iter()) {
task.put_afe_f_entry(i as i64 + 1 + k as i64, voff_x + i, thetai.sqrt())?;
}
// Input the affine conic constraint (gamma, GT*x) \in QCone
// Add the quadratic domain of dimension k+1
let qdom = task.append_quadratic_cone_domain(k as i64+ 1)?;
// Add the constraint
task.append_acc_seq(qdom, 0, vec![0.0; k as usize+1].as_slice())?;
task.put_acc_name(0, "risk")?;
// Objective: maximize expected return mu^T x
for (j,&muj) in (0..n).zip(mu.iter()) {
task.put_c_j(voff_x + j, muj)?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
Ok(gammas.iter().filter_map(|&gamma| {
// Specify gamma in ACC
task.put_afe_g(0, gamma).ok()?;
task.optimize().ok()?;
/* Display solution summary for quick inspection of results */
let _ = task.solution_summary(Streamtype::LOG);
let _ = task.write_data(format!("portfolio_6_factor-{}.ptf",gamma).as_str());
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR).ok()? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Read the results */
let mut xx = vec![0.0; n as usize];
task.get_xx_slice(Soltype::ITR, voff_x, voff_x + n, xx.as_mut_slice()).ok()?;
Some((gamma,xx.iter().zip(mu.iter()).map(|(&xj,&muj)| xj*muj).sum::<f64>()))
}).collect::<Vec<(f64,f64)>>())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn put_afe_f_entry_list(
&mut self,
afeidx_: &[i64],
varidx_: &[i32],
val_: &[f64]
) -> Result<(), String>
pub fn put_afe_f_entry_list( &mut self, afeidx_: &[i64], varidx_: &[i32], val_: &[f64] ) -> Result<(), String>
Replaces a list of entries in F.
§Arguments
afeidx_
Row indices in F.varidx_
Column indices in F.val_
Values of the entries in F.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafefentrylist
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
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
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(())
}
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 129 130
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
sourcepub fn put_afe_f_row(
&mut self,
afeidx_: i64,
varidx_: &[i32],
val_: &[f64]
) -> Result<(), String>
pub fn put_afe_f_row( &mut self, afeidx_: i64, varidx_: &[i32], val_: &[f64] ) -> Result<(), String>
Replaces all elements in one row of the F matrix in the affine expressions.
§Arguments
afeidx_
Row index.varidx_
Column indexes of non-zero values in the row.val_
New non-zero values in the row.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafefrow
Examples found in repository?
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
sourcepub fn put_afe_f_row_list(
&mut self,
afeidx_: &[i64],
numnzrow_: &[i32],
ptrrow_: &[i64],
varidx_: &[i32],
val_: &[f64]
) -> Result<(), String>
pub fn put_afe_f_row_list( &mut self, afeidx_: &[i64], numnzrow_: &[i32], ptrrow_: &[i64], varidx_: &[i32], val_: &[f64] ) -> Result<(), String>
Replaces all elements in a number of rows of the F matrix in the affine expressions.
§Arguments
afeidx_
Row indices.numnzrow_
Number of non-zeros in each row.ptrrow_
Pointer to the first nonzero in each row.varidx_
Column indexes of non-zero values.val_
New non-zero values in the rows.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafefrowlist
Examples found in repository?
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
fn portfolio(w : f64,
mu : &[f64],
x0 : &[f64],
gammas : &[f64],
theta : &[f64],
GT : &Matrix) -> Result<Vec<(f64,f64)>,String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
let (kx,nx) = GT.size();
if mu.len() != nx { panic!("Mismatching data"); }
let k : i32 = kx.try_into().unwrap();
let n : i32 = nx.try_into().unwrap();
let total_budget : f64 = w + x0.iter().sum::<f64>();
//Offset of variables into the API variable.
let numvar = n;
let voff_x : i32 = 0;
// Constraint offset
let coff_bud : i32 = 0;
// Holding variable x of length n
// No other auxiliary variables are needed in this formulation
task.append_vars(numvar)?;
// Setting up variable x
for j in 0..n {
task.put_var_name(voff_x+j,format!("x[{}]",j+1).as_str())?;
}
task.put_var_bound_slice_const(voff_x,voff_x+n, Boundkey::LO,0.0, INF)?;
// One linear constraint: total budget
task.append_cons(1)?;
task.put_con_name(coff_bud, "budget")?;
/* Coefficients in the first row of A */
for j in 0..n {
task.put_aij(coff_bud,voff_x + j, 1.0)?;
}
task.put_con_bound(coff_bud, Boundkey::FX, total_budget, total_budget)?;
// Input (gamma, G_factor_T x, diag(sqrt(theta))*x) in the AFE (affine expression) storage
// We need k+n+1 rows and we fill them in in three parts
task.append_afes((k+n) as i64 + 1)?;
// 1. The first affine expression = gamma, will be specified later
// 2. The next k expressions comprise G_factor_T*x, we add them row by row
// transposing the matrix G_factor on the fly
task.put_afe_f_row_list((1..1+k as i64).collect::<Vec<i64>>().as_slice(), // f row idxs
vec![n; k as usize].as_slice(), // row lengths
(0..GT.len() as i64).step_by(n as usize).collect::<Vec<i64>>().as_slice(), // row ptr
iproduct!(0..k,0..n).map(|(_,b)| b).collect::<Vec<i32>>().as_slice(), // varidx, 0..n repeated k times
GT.data_by_row().as_slice())?;
// 3. The remaining n rows contain sqrt(theta) on the diagonal
for (i,thetai) in (0..n).zip(theta.iter()) {
task.put_afe_f_entry(i as i64 + 1 + k as i64, voff_x + i, thetai.sqrt())?;
}
// Input the affine conic constraint (gamma, GT*x) \in QCone
// Add the quadratic domain of dimension k+1
let qdom = task.append_quadratic_cone_domain(k as i64+ 1)?;
// Add the constraint
task.append_acc_seq(qdom, 0, vec![0.0; k as usize+1].as_slice())?;
task.put_acc_name(0, "risk")?;
// Objective: maximize expected return mu^T x
for (j,&muj) in (0..n).zip(mu.iter()) {
task.put_c_j(voff_x + j, muj)?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
Ok(gammas.iter().filter_map(|&gamma| {
// Specify gamma in ACC
task.put_afe_g(0, gamma).ok()?;
task.optimize().ok()?;
/* Display solution summary for quick inspection of results */
let _ = task.solution_summary(Streamtype::LOG);
let _ = task.write_data(format!("portfolio_6_factor-{}.ptf",gamma).as_str());
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR).ok()? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Read the results */
let mut xx = vec![0.0; n as usize];
task.get_xx_slice(Soltype::ITR, voff_x, voff_x + n, xx.as_mut_slice()).ok()?;
Some((gamma,xx.iter().zip(mu.iter()).map(|(&xj,&muj)| xj*muj).sum::<f64>()))
}).collect::<Vec<(f64,f64)>>())
}
sourcepub fn put_afe_g(&mut self, afeidx_: i64, g_: f64) -> Result<(), String>
pub fn put_afe_g(&mut self, afeidx_: i64, g_: f64) -> Result<(), String>
Replaces one element in the g vector in the affine expressions.
§Arguments
afeidx_
Row index.g_
New value for the element of g.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafeg
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
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
fn portfolio(w : f64,
mu : &[f64],
x0 : &[f64],
gammas : &[f64],
theta : &[f64],
GT : &Matrix) -> Result<Vec<(f64,f64)>,String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
let (kx,nx) = GT.size();
if mu.len() != nx { panic!("Mismatching data"); }
let k : i32 = kx.try_into().unwrap();
let n : i32 = nx.try_into().unwrap();
let total_budget : f64 = w + x0.iter().sum::<f64>();
//Offset of variables into the API variable.
let numvar = n;
let voff_x : i32 = 0;
// Constraint offset
let coff_bud : i32 = 0;
// Holding variable x of length n
// No other auxiliary variables are needed in this formulation
task.append_vars(numvar)?;
// Setting up variable x
for j in 0..n {
task.put_var_name(voff_x+j,format!("x[{}]",j+1).as_str())?;
}
task.put_var_bound_slice_const(voff_x,voff_x+n, Boundkey::LO,0.0, INF)?;
// One linear constraint: total budget
task.append_cons(1)?;
task.put_con_name(coff_bud, "budget")?;
/* Coefficients in the first row of A */
for j in 0..n {
task.put_aij(coff_bud,voff_x + j, 1.0)?;
}
task.put_con_bound(coff_bud, Boundkey::FX, total_budget, total_budget)?;
// Input (gamma, G_factor_T x, diag(sqrt(theta))*x) in the AFE (affine expression) storage
// We need k+n+1 rows and we fill them in in three parts
task.append_afes((k+n) as i64 + 1)?;
// 1. The first affine expression = gamma, will be specified later
// 2. The next k expressions comprise G_factor_T*x, we add them row by row
// transposing the matrix G_factor on the fly
task.put_afe_f_row_list((1..1+k as i64).collect::<Vec<i64>>().as_slice(), // f row idxs
vec![n; k as usize].as_slice(), // row lengths
(0..GT.len() as i64).step_by(n as usize).collect::<Vec<i64>>().as_slice(), // row ptr
iproduct!(0..k,0..n).map(|(_,b)| b).collect::<Vec<i32>>().as_slice(), // varidx, 0..n repeated k times
GT.data_by_row().as_slice())?;
// 3. The remaining n rows contain sqrt(theta) on the diagonal
for (i,thetai) in (0..n).zip(theta.iter()) {
task.put_afe_f_entry(i as i64 + 1 + k as i64, voff_x + i, thetai.sqrt())?;
}
// Input the affine conic constraint (gamma, GT*x) \in QCone
// Add the quadratic domain of dimension k+1
let qdom = task.append_quadratic_cone_domain(k as i64+ 1)?;
// Add the constraint
task.append_acc_seq(qdom, 0, vec![0.0; k as usize+1].as_slice())?;
task.put_acc_name(0, "risk")?;
// Objective: maximize expected return mu^T x
for (j,&muj) in (0..n).zip(mu.iter()) {
task.put_c_j(voff_x + j, muj)?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
Ok(gammas.iter().filter_map(|&gamma| {
// Specify gamma in ACC
task.put_afe_g(0, gamma).ok()?;
task.optimize().ok()?;
/* Display solution summary for quick inspection of results */
let _ = task.solution_summary(Streamtype::LOG);
let _ = task.write_data(format!("portfolio_6_factor-{}.ptf",gamma).as_str());
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR).ok()? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Read the results */
let mut xx = vec![0.0; n as usize];
task.get_xx_slice(Soltype::ITR, voff_x, voff_x + n, xx.as_mut_slice()).ok()?;
Some((gamma,xx.iter().zip(mu.iter()).map(|(&xj,&muj)| xj*muj).sum::<f64>()))
}).collect::<Vec<(f64,f64)>>())
}
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 129 130
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
sourcepub fn put_afe_g_list(
&mut self,
afeidx_: &[i64],
g_: &[f64]
) -> Result<(), String>
pub fn put_afe_g_list( &mut self, afeidx_: &[i64], g_: &[f64] ) -> Result<(), String>
Replaces a list of elements in the g vector in the affine expressions.
§Arguments
afeidx_
Indices of entries in g.g_
New values for the elements of g.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafeglist
sourcepub fn put_afe_g_slice(
&mut self,
first_: i64,
last_: i64,
slice_: &[f64]
) -> Result<(), String>
pub fn put_afe_g_slice( &mut self, first_: i64, last_: i64, slice_: &[f64] ) -> Result<(), String>
Modifies a slice of the vector g.
§Arguments
first_
First index in the sequence.last_
Last index plus 1 in the sequence.slice_
The slice of g as a dense vector.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putafegslice
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
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
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(())
}
sourcepub fn put_aij(&mut self, i_: i32, j_: i32, aij_: f64) -> Result<(), String>
pub fn put_aij(&mut self, i_: i32, j_: i32, aij_: f64) -> Result<(), String>
Changes a single value in the linear coefficient matrix.
§Arguments
i_
Constraint (row) index.j_
Variable (column) index.aij_
New coefficient.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putaij
Examples found in repository?
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
More examples
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
fn portfolio(w : f64,
mu : &[f64],
x0 : &[f64],
gammas : &[f64],
theta : &[f64],
GT : &Matrix) -> Result<Vec<(f64,f64)>,String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
let (kx,nx) = GT.size();
if mu.len() != nx { panic!("Mismatching data"); }
let k : i32 = kx.try_into().unwrap();
let n : i32 = nx.try_into().unwrap();
let total_budget : f64 = w + x0.iter().sum::<f64>();
//Offset of variables into the API variable.
let numvar = n;
let voff_x : i32 = 0;
// Constraint offset
let coff_bud : i32 = 0;
// Holding variable x of length n
// No other auxiliary variables are needed in this formulation
task.append_vars(numvar)?;
// Setting up variable x
for j in 0..n {
task.put_var_name(voff_x+j,format!("x[{}]",j+1).as_str())?;
}
task.put_var_bound_slice_const(voff_x,voff_x+n, Boundkey::LO,0.0, INF)?;
// One linear constraint: total budget
task.append_cons(1)?;
task.put_con_name(coff_bud, "budget")?;
/* Coefficients in the first row of A */
for j in 0..n {
task.put_aij(coff_bud,voff_x + j, 1.0)?;
}
task.put_con_bound(coff_bud, Boundkey::FX, total_budget, total_budget)?;
// Input (gamma, G_factor_T x, diag(sqrt(theta))*x) in the AFE (affine expression) storage
// We need k+n+1 rows and we fill them in in three parts
task.append_afes((k+n) as i64 + 1)?;
// 1. The first affine expression = gamma, will be specified later
// 2. The next k expressions comprise G_factor_T*x, we add them row by row
// transposing the matrix G_factor on the fly
task.put_afe_f_row_list((1..1+k as i64).collect::<Vec<i64>>().as_slice(), // f row idxs
vec![n; k as usize].as_slice(), // row lengths
(0..GT.len() as i64).step_by(n as usize).collect::<Vec<i64>>().as_slice(), // row ptr
iproduct!(0..k,0..n).map(|(_,b)| b).collect::<Vec<i32>>().as_slice(), // varidx, 0..n repeated k times
GT.data_by_row().as_slice())?;
// 3. The remaining n rows contain sqrt(theta) on the diagonal
for (i,thetai) in (0..n).zip(theta.iter()) {
task.put_afe_f_entry(i as i64 + 1 + k as i64, voff_x + i, thetai.sqrt())?;
}
// Input the affine conic constraint (gamma, GT*x) \in QCone
// Add the quadratic domain of dimension k+1
let qdom = task.append_quadratic_cone_domain(k as i64+ 1)?;
// Add the constraint
task.append_acc_seq(qdom, 0, vec![0.0; k as usize+1].as_slice())?;
task.put_acc_name(0, "risk")?;
// Objective: maximize expected return mu^T x
for (j,&muj) in (0..n).zip(mu.iter()) {
task.put_c_j(voff_x + j, muj)?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
Ok(gammas.iter().filter_map(|&gamma| {
// Specify gamma in ACC
task.put_afe_g(0, gamma).ok()?;
task.optimize().ok()?;
/* Display solution summary for quick inspection of results */
let _ = task.solution_summary(Streamtype::LOG);
let _ = task.write_data(format!("portfolio_6_factor-{}.ptf",gamma).as_str());
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR).ok()? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Read the results */
let mut xx = vec![0.0; n as usize];
task.get_xx_slice(Soltype::ITR, voff_x, voff_x + n, xx.as_mut_slice()).ok()?;
Some((gamma,xx.iter().zip(mu.iter()).map(|(&xj,&muj)| xj*muj).sum::<f64>()))
}).collect::<Vec<(f64,f64)>>())
}
sourcepub fn put_aij_list(
&mut self,
subi_: &[i32],
subj_: &[i32],
valij_: &[f64]
) -> Result<(), String>
pub fn put_aij_list( &mut self, subi_: &[i32], subj_: &[i32], valij_: &[f64] ) -> Result<(), String>
Changes one or more coefficients in the linear constraint matrix.
§Arguments
subi_
Constraint (row) indices.subj_
Variable (column) indices.valij_
New coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putaijlist64
Examples found in repository?
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
More examples
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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 129 130
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn put_a_row(
&mut self,
i_: i32,
subi_: &[i32],
vali_: &[f64]
) -> Result<(), String>
pub fn put_a_row( &mut self, i_: i32, subi_: &[i32], vali_: &[f64] ) -> Result<(), String>
Replaces all elements in one row of the linear constraint matrix.
§Arguments
i_
Row index.subi_
Column indexes of non-zero values in row.vali_
New non-zero values of row.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putarow
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 3;
let numvar : i32 = 4;
let c = [3.0, 1.0, 5.0, 1.0];
let asub = [0, 1, 2,
0, 1, 2, 3,
1, 3];
let aval = [3.0, 1.0, 2.0,
2.0, 1.0, 3.0, 1.0,
2.0, 3.0];
let aptr = [0,3,7,9];
let bkc = [Boundkey::FX,
Boundkey::LO,
Boundkey::UP];
let blc = [30.0,
15.0,
-INF];
let buc = [30.0,
INF,
25.0];
let bkx = [Boundkey::LO,
Boundkey::RA,
Boundkey::LO,
Boundkey::LO];
let blx = [0.0,
0.0,
0.0,
0.0];
let bux = [INF,
10.0,
INF,
INF];
// Create a task object linked with the environment env.
let mut task = Task::new().unwrap().with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Give MOSEK an estimate of the size of the input data.
This is done to increase the speed of inputting data.
However, it is optional. */
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for (j,(&cj,&bkj,&blj,&buj)) in izip!(c.iter(),bkx.iter(),blx.iter(),bux.iter()).enumerate() {
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32, cj)?;
/* Set the bounds on variable j.
blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, bkj, blj, buj)?;
};
/* Set the bounds on constraints.
for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for (i,(&bki,&bli,&bui,&ptrb,&ptre)) in izip!(bkc.iter(),blc.iter(),buc.iter(),aptr[..aptr.len()-1].iter(),aptr[1..].iter()).enumerate() {
task.put_con_bound(i as i32, bki, bli, bui)?;
/* Input row i of A */
task.put_a_row(i as i32, /* Row index.*/
&asub[ptrb..ptre], /* Column indexes of non-zeros in row i.*/
&aval[ptrb..ptre])?; /* Non-zero Values of row i. */
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS, // Basic solution.
xx.as_mut_slice());
match solsta {
Solsta::OPTIMAL =>
println!("Optimal primal solution = {:?}",xx),
Solsta::DUAL_INFEAS_CER|Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility."),
Solsta::UNKNOWN =>
println!("Unknown solution status."),
_ =>
println!("Other solution status")
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
fn main() -> Result<(),String>
{
let numvar : i32 = 6;
let numcon : i32 = 1;
let bkc = &[ mosek::Boundkey::FX ];
let blc = &[ 1.0 ];
let buc = &[ 1.0 ];
let bkx = &[ mosek::Boundkey::LO,
mosek::Boundkey::LO,
mosek::Boundkey::LO,
mosek::Boundkey::FR,
mosek::Boundkey::FR,
mosek::Boundkey::FR];
let blx = &[ 0.0, 0.0, 0.0, -INF, -INF, -INF ];
let bux = &[ INF, INF, INF, INF, INF, INF ];
let c = &[ 0.0, 0.0, 0.0, 1.0, 1.0, 1.0 ];
let asub = &[0, 1, 2];
let aval = &[1.0, 1.0, 1.0];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
for (j,&cj,&bkj,&blj,&buj) in izip!(0..numvar,c,bkx,blx,bux) {
/* Set the linear term c_j in the objective.*/
task.put_c_j(j,cj)?;
/* Set the bounds on variable j.
* blx[j] <= x_j <= bux[j] */
task.put_var_bound( j, /* Index of variable.*/
bkj, /* Bound key.*/
blj, /* Numerical value of lower bound.*/
buj)?; /* Numerical value of upper bound.*/
}
/* Input columns of A */
task.put_a_row(0, asub, aval)?;
/* Set the bounds on constraints.
* for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for (i,&bki,&bli,&bui) in izip!(0..numcon,bkc,blc,buc) {
task.put_con_bound( i, /* Index of constraint.*/
bki, /* Bound key.*/
bli, /* Numerical value of lower bound.*/
bui)?; /* Numerical value of upper bound.*/
}
/* Append the first cone. */
// Create a matrix F such that F * x = [x(3),x(0),x(1),x(4),x(5),x(2)]
{
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0,1,2,3,4,5], // Rows
&[3, 0, 1, 4, 5, 2], // Columns
&[1.0,1.0,1.0,1.0,1.0,1.0])?;
// Quadratic cone (x(3),x(0),x(1)) \in QUAD_3
let qconedom = task.append_quadratic_cone_domain(3)?;
task.append_acc(qconedom, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
// Rotated quadratic cone (x(4),x(5),x(2)) \in RQUAD_3
let rqconedom = task.append_r_quadratic_cone_domain(3)?;
task.append_acc(rqconedom, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
}
/* Run optimizer */
let trm = task.optimize()?;
task.write_data("cqo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,xj) in izip!(0..numvar,xx) {
println!("x[{}]: {}",j,xj);
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN => {
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",trm);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn put_a_row_list(
&mut self,
sub_: &[i32],
ptrb_: &[i64],
ptre_: &[i64],
asub_: &[i32],
aval_: &[f64]
) -> Result<(), String>
pub fn put_a_row_list( &mut self, sub_: &[i32], ptrb_: &[i64], ptre_: &[i64], asub_: &[i32], aval_: &[f64] ) -> Result<(), String>
Replaces all elements in several rows of the linear constraint matrix.
§Arguments
sub_
Indexes of rows or columns that should be replaced.ptrb_
Array of pointers to the first element in the rows.ptre_
Array of pointers to the last element plus one in the rows.asub_
Variable indexes.aval_
Coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putarowlist64
sourcepub fn put_a_row_slice(
&mut self,
first_: i32,
last_: i32,
ptrb_: &[i64],
ptre_: &[i64],
asub_: &[i32],
aval_: &[f64]
) -> Result<(), String>
pub fn put_a_row_slice( &mut self, first_: i32, last_: i32, ptrb_: &[i64], ptre_: &[i64], asub_: &[i32], aval_: &[f64] ) -> Result<(), String>
Replaces all elements in several rows the linear constraint matrix.
§Arguments
first_
First row in the slice.last_
Last row plus one in the slice.ptrb_
Array of pointers to the first element in the rows.ptre_
Array of pointers to the last element plus one in the rows.asub_
Column indexes of new elements.aval_
Coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putarowslice64
sourcepub fn put_a_truncate_tol(&mut self, tolzero_: f64) -> Result<(), String>
pub fn put_a_truncate_tol(&mut self, tolzero_: f64) -> Result<(), String>
Truncates all elements in A below a certain tolerance to zero.
§Arguments
tolzero_
Truncation tolerance.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putatruncatetol
sourcepub fn put_bara_block_triplet(
&mut self,
subi_: &[i32],
subj_: &[i32],
subk_: &[i32],
subl_: &[i32],
valijkl_: &[f64]
) -> Result<(), String>
pub fn put_bara_block_triplet( &mut self, subi_: &[i32], subj_: &[i32], subk_: &[i32], subl_: &[i32], valijkl_: &[f64] ) -> Result<(), String>
Inputs barA in block triplet form.
§Arguments
subi_
Constraint index.subj_
Symmetric matrix variable index.subk_
Block row index.subl_
Block column index.valijkl_
The numerical value associated with each block triplet.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putbarablocktriplet
Examples found in repository?
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
fn main() -> Result<(),String> {
/* Input data */
let numcon : i32 = 2; /* Number of constraints. */
let dimbarvar : &[i32] = &[3, 4]; /* Dimension of semidefinite variables */
/* Objective coefficients concatenated */
let Cj : &[i32] = &[ 0, 0, 1, 1, 1, 1 ]; /* Which symmetric variable (j) */
let Ck : &[i32] = &[ 0, 2, 0, 1, 1, 2 ]; /* Which entry (k,l)->v */
let Cl : &[i32] = &[ 0, 2, 0, 0, 1, 2 ];
let Cv : &[f64] = &[ 1.0, 6.0, 1.0, -3.0, 2.0, 1.0 ];
/* Equality constraints coefficients concatenated */
let Ai : &[i32] = &[ 0, 0, 0, 0, 0, 0 ]; /* Which constraint (i = 0) */
let Aj : &[i32] = &[ 0, 0, 0, 1, 1, 1 ]; /* Which symmetric variable (j) */
let Ak : &[i32] = &[ 0, 2, 2, 1, 1, 3 ]; /* Which entry (k,l)->v */
let Al : &[i32] = &[ 0, 0, 2, 0, 1, 3 ];
let Av : &[f64] = &[ 1.0, 1.0, 2.0, 1.0, -1.0, -3.0 ];
/* The second constraint - one-term inequality */
let A2i : &[i32] = &[ 1 ]; /* Which constraint (i = 1) */
let A2j : &[i32] = &[ 1 ]; /* Which symmetric variable (j = 1) */
let A2k : &[i32] = &[ 1 ]; /* Which entry A(1,0) = A(0,1) = 0.5 */
let A2l : &[i32] = &[ 0 ];
let A2v : &[f64] = &[ 0.5 ];
let bkc = &[ mosek::Boundkey::FX,
mosek::Boundkey::UP ];
let blc = &[ 23.0, 0.0 ];
let buc = &[ 23.0, -3.0 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append numcon empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append numbarvar semidefinite variables. */
task.append_barvars(dimbarvar)?;
/* Set objective (6 nonzeros).*/
task.put_barc_block_triplet(Cj, Ck, Cl, Cv)?;
/* Set the equality constraint (6 nonzeros).*/
task.put_bara_block_triplet(Ai, Aj, Ak, Al, Av)?;
/* Set the inequality constraint (1 nonzero).*/
task.put_bara_block_triplet(A2i, A2j, A2k, A2l, A2v)?;
/* Set constraint bounds */
task.put_con_bound_slice(0, 2, bkc, blc, buc)?;
/* Run optimizer */
task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
//mosek.solsta[] solsta = new mosek.solsta[1];
let solsta = task.get_sol_sta (Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
/* Retrieve the soution for all symmetric variables */
println!("Solution (lower triangular part vectorized):");
for (i,dimbarvari) in dimbarvar.iter().enumerate() {
//let dim = dimbarvar[i] * (dimbarvar[i] + 1) / 2;
let dim = dimbarvari * (dimbarvari+1)/2;
//double[] barx = new double[dim];
let mut barx : Vec<f64> = vec![0.0; dim as usize];
task.get_barx_j(Soltype::ITR, i as i32, barx.as_mut_slice())?;
println!("X{}: {:?}",i+1,barx);
// for (int j = 0; j < dim; ++j)
// System.out.print(barx[j] + " ");
// System.out.println();
}
},
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(())
}
sourcepub fn put_bara_ij(
&mut self,
i_: i32,
j_: i32,
sub_: &[i64],
weights_: &[f64]
) -> Result<(), String>
pub fn put_bara_ij( &mut self, i_: i32, j_: i32, sub_: &[i64], weights_: &[f64] ) -> Result<(), String>
Inputs an element of barA.
§Arguments
i_
Row index of barA.j_
Column index of barA.sub_
Element indexes in matrix storage.weights_
Weights in the weighted sum.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putbaraij
Examples found in repository?
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
fn main() -> Result<(),String>
{
let dimbarvar = vec![3]; /* Dimension of semidefinite cone */
let bkc = &[ mosek::Boundkey::FX, mosek::Boundkey::FX ];
let blc = &[ 1.0, 0.5 ];
let buc = &[ 1.0, 0.5 ];
let barc_i = &[0, 1, 1, 2, 2];
let barc_j = &[0, 0, 1, 1, 2];
let barc_v = &[2.0, 1.0, 2.0, 1.0, 2.0];
let aptrb = &[0, 1];
let aptre = &[1, 3];
let asub = &[0, 1, 2]; /* column subscripts of A */
let aval = &[1.0, 1.0, 1.0];
let bara_i = &[0, 1, 2, 0, 1, 2, 1, 2, 2];
let bara_j = &[0, 1, 2, 0, 0, 0, 1, 1, 2];
let bara_v = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let falpha = 1.0;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'NUMCON' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Append 'NUMBARVAR' semidefinite variables. */
task.append_barvars(&dimbarvar[..])?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
/* Set the linear term c_j in the objective.*/
task.put_c_j(0,1.0)?;
for j in 0..NUMVAR {
task.put_var_bound(j as i32,
mosek::Boundkey::FR,
-INF,
INF)?;
}
/* Set the linear term barc_j in the objective.*/
let c_symmat_idx = task.append_sparse_sym_mat(dimbarvar[0],
barc_i,
barc_j,
barc_v)?;
task.put_barc_j(0, &[c_symmat_idx], &[falpha])?;
for i in 0..NUMCON
{
/* Input A row by row */
task.put_a_row(i as i32,
& asub[aptrb[i]..aptre[i]],
& aval[aptrb[i]..aptre[i]])?;
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
}
{
/* Append the conic quadratic cone */
let afei = task.get_num_afe()?;
task.append_afes(3)?;
task.put_afe_f_entry_list(&[0,1,2],
&[0,1,2],
&[1.0,1.0,1.0])?;
let dom = task.append_quadratic_cone_domain(3)?;
task.append_acc_seq(dom,afei,&[0.0,0.0,0.0])?;
}
/* Add the first row of barA */
let a_symmat_idx1 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[..3],
& bara_j[..3],
& bara_v[..3])?;
task.put_bara_ij(0, 0, &[a_symmat_idx1][..], &[falpha][..])?;
/* Add the second row of barA */
let a_symmat_idx2 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[3..9],
& bara_j[3..9],
& bara_v[3..9])?;
task.put_bara_ij(1, 0, &[a_symmat_idx2][..], &[falpha][..])?;
let _trmcode = task.optimize()?;
task.write_data("sdo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0,0.0,0.0];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
& mut xx[..])?;
let mut barx = vec![0.0,0.0,0.0,0.0,0.0,0.0];
task.get_barx_j(Soltype::ITR, /* Request the interior solution. */
0,
& mut barx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR as usize
{
println!("x[{}]: {}",j,xx[j]);
}
let n = dimbarvar[0] as usize;
for j in 0..n
{
for i in j..n
{
println!("barx[{},{}]: {}",i,j,barx[j*n+i-j*(j+1)/2]);
}
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN =>
{
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",solsta);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn put_bara_ij_list(
&mut self,
subi_: &[i32],
subj_: &[i32],
alphaptrb_: &[i64],
alphaptre_: &[i64],
matidx_: &[i64],
weights_: &[f64]
) -> Result<(), String>
pub fn put_bara_ij_list( &mut self, subi_: &[i32], subj_: &[i32], alphaptrb_: &[i64], alphaptre_: &[i64], matidx_: &[i64], weights_: &[f64] ) -> Result<(), String>
Inputs list of elements of barA.
§Arguments
subi_
Row index of barA.subj_
Column index of barA.alphaptrb_
Start entries for terms in the weighted sum.alphaptre_
End entries for terms in the weighted sum.matidx_
Element indexes in matrix storage.weights_
Weights in the weighted sum.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putbaraijlist
sourcepub fn put_bara_row_list(
&mut self,
subi_: &[i32],
ptrb_: &[i64],
ptre_: &[i64],
subj_: &[i32],
nummat_: &[i64],
matidx_: &[i64],
weights_: &[f64]
) -> Result<(), String>
pub fn put_bara_row_list( &mut self, subi_: &[i32], ptrb_: &[i64], ptre_: &[i64], subj_: &[i32], nummat_: &[i64], matidx_: &[i64], weights_: &[f64] ) -> Result<(), String>
Replace a set of rows of barA
§Arguments
subi_
Row indexes of barA.ptrb_
Start of rows in barA.ptre_
End of rows in barA.subj_
Column index of barA.nummat_
Number of entries in weighted sum of matrixes.matidx_
Matrix indexes for weighted sum of matrixes.weights_
Weights for weighted sum of matrixes.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putbararowlist
sourcepub fn put_barc_block_triplet(
&mut self,
subj_: &[i32],
subk_: &[i32],
subl_: &[i32],
valjkl_: &[f64]
) -> Result<(), String>
pub fn put_barc_block_triplet( &mut self, subj_: &[i32], subk_: &[i32], subl_: &[i32], valjkl_: &[f64] ) -> Result<(), String>
Inputs barC in block triplet form.
§Arguments
subj_
Symmetric matrix variable index.subk_
Block row index.subl_
Block column index.valjkl_
The numerical value associated with each block triplet.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putbarcblocktriplet
Examples found in repository?
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
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(())
}
More examples
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
fn main() -> Result<(),String> {
/* Input data */
let numcon : i32 = 2; /* Number of constraints. */
let dimbarvar : &[i32] = &[3, 4]; /* Dimension of semidefinite variables */
/* Objective coefficients concatenated */
let Cj : &[i32] = &[ 0, 0, 1, 1, 1, 1 ]; /* Which symmetric variable (j) */
let Ck : &[i32] = &[ 0, 2, 0, 1, 1, 2 ]; /* Which entry (k,l)->v */
let Cl : &[i32] = &[ 0, 2, 0, 0, 1, 2 ];
let Cv : &[f64] = &[ 1.0, 6.0, 1.0, -3.0, 2.0, 1.0 ];
/* Equality constraints coefficients concatenated */
let Ai : &[i32] = &[ 0, 0, 0, 0, 0, 0 ]; /* Which constraint (i = 0) */
let Aj : &[i32] = &[ 0, 0, 0, 1, 1, 1 ]; /* Which symmetric variable (j) */
let Ak : &[i32] = &[ 0, 2, 2, 1, 1, 3 ]; /* Which entry (k,l)->v */
let Al : &[i32] = &[ 0, 0, 2, 0, 1, 3 ];
let Av : &[f64] = &[ 1.0, 1.0, 2.0, 1.0, -1.0, -3.0 ];
/* The second constraint - one-term inequality */
let A2i : &[i32] = &[ 1 ]; /* Which constraint (i = 1) */
let A2j : &[i32] = &[ 1 ]; /* Which symmetric variable (j = 1) */
let A2k : &[i32] = &[ 1 ]; /* Which entry A(1,0) = A(0,1) = 0.5 */
let A2l : &[i32] = &[ 0 ];
let A2v : &[f64] = &[ 0.5 ];
let bkc = &[ mosek::Boundkey::FX,
mosek::Boundkey::UP ];
let blc = &[ 23.0, 0.0 ];
let buc = &[ 23.0, -3.0 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append numcon empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append numbarvar semidefinite variables. */
task.append_barvars(dimbarvar)?;
/* Set objective (6 nonzeros).*/
task.put_barc_block_triplet(Cj, Ck, Cl, Cv)?;
/* Set the equality constraint (6 nonzeros).*/
task.put_bara_block_triplet(Ai, Aj, Ak, Al, Av)?;
/* Set the inequality constraint (1 nonzero).*/
task.put_bara_block_triplet(A2i, A2j, A2k, A2l, A2v)?;
/* Set constraint bounds */
task.put_con_bound_slice(0, 2, bkc, blc, buc)?;
/* Run optimizer */
task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
//mosek.solsta[] solsta = new mosek.solsta[1];
let solsta = task.get_sol_sta (Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
/* Retrieve the soution for all symmetric variables */
println!("Solution (lower triangular part vectorized):");
for (i,dimbarvari) in dimbarvar.iter().enumerate() {
//let dim = dimbarvar[i] * (dimbarvar[i] + 1) / 2;
let dim = dimbarvari * (dimbarvari+1)/2;
//double[] barx = new double[dim];
let mut barx : Vec<f64> = vec![0.0; dim as usize];
task.get_barx_j(Soltype::ITR, i as i32, barx.as_mut_slice())?;
println!("X{}: {:?}",i+1,barx);
// for (int j = 0; j < dim; ++j)
// System.out.print(barx[j] + " ");
// System.out.println();
}
},
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(())
}
sourcepub fn put_barc_j(
&mut self,
j_: i32,
sub_: &[i64],
weights_: &[f64]
) -> Result<(), String>
pub fn put_barc_j( &mut self, j_: i32, sub_: &[i64], weights_: &[f64] ) -> Result<(), String>
Changes one element in barc.
§Arguments
j_
Index of the element in barc` that should be changed.sub_
sub is list of indexes of those symmetric matrices appearing in sum.weights_
The weights of the terms in the weighted sum.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putbarcj
Examples found in repository?
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
fn main() -> Result<(),String>
{
let dimbarvar = vec![3]; /* Dimension of semidefinite cone */
let bkc = &[ mosek::Boundkey::FX, mosek::Boundkey::FX ];
let blc = &[ 1.0, 0.5 ];
let buc = &[ 1.0, 0.5 ];
let barc_i = &[0, 1, 1, 2, 2];
let barc_j = &[0, 0, 1, 1, 2];
let barc_v = &[2.0, 1.0, 2.0, 1.0, 2.0];
let aptrb = &[0, 1];
let aptre = &[1, 3];
let asub = &[0, 1, 2]; /* column subscripts of A */
let aval = &[1.0, 1.0, 1.0];
let bara_i = &[0, 1, 2, 0, 1, 2, 1, 2, 2];
let bara_j = &[0, 1, 2, 0, 0, 0, 1, 1, 2];
let bara_v = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let falpha = 1.0;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'NUMCON' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Append 'NUMBARVAR' semidefinite variables. */
task.append_barvars(&dimbarvar[..])?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
/* Set the linear term c_j in the objective.*/
task.put_c_j(0,1.0)?;
for j in 0..NUMVAR {
task.put_var_bound(j as i32,
mosek::Boundkey::FR,
-INF,
INF)?;
}
/* Set the linear term barc_j in the objective.*/
let c_symmat_idx = task.append_sparse_sym_mat(dimbarvar[0],
barc_i,
barc_j,
barc_v)?;
task.put_barc_j(0, &[c_symmat_idx], &[falpha])?;
for i in 0..NUMCON
{
/* Input A row by row */
task.put_a_row(i as i32,
& asub[aptrb[i]..aptre[i]],
& aval[aptrb[i]..aptre[i]])?;
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
}
{
/* Append the conic quadratic cone */
let afei = task.get_num_afe()?;
task.append_afes(3)?;
task.put_afe_f_entry_list(&[0,1,2],
&[0,1,2],
&[1.0,1.0,1.0])?;
let dom = task.append_quadratic_cone_domain(3)?;
task.append_acc_seq(dom,afei,&[0.0,0.0,0.0])?;
}
/* Add the first row of barA */
let a_symmat_idx1 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[..3],
& bara_j[..3],
& bara_v[..3])?;
task.put_bara_ij(0, 0, &[a_symmat_idx1][..], &[falpha][..])?;
/* Add the second row of barA */
let a_symmat_idx2 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[3..9],
& bara_j[3..9],
& bara_v[3..9])?;
task.put_bara_ij(1, 0, &[a_symmat_idx2][..], &[falpha][..])?;
let _trmcode = task.optimize()?;
task.write_data("sdo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0,0.0,0.0];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
& mut xx[..])?;
let mut barx = vec![0.0,0.0,0.0,0.0,0.0,0.0];
task.get_barx_j(Soltype::ITR, /* Request the interior solution. */
0,
& mut barx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR as usize
{
println!("x[{}]: {}",j,xx[j]);
}
let n = dimbarvar[0] as usize;
for j in 0..n
{
for i in j..n
{
println!("barx[{},{}]: {}",i,j,barx[j*n+i-j*(j+1)/2]);
}
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN =>
{
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",solsta);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn put_bars_j(
&mut self,
whichsol_: i32,
j_: i32,
barsj_: &[f64]
) -> Result<(), String>
pub fn put_bars_j( &mut self, whichsol_: i32, j_: i32, barsj_: &[f64] ) -> Result<(), String>
Sets the dual solution for a semidefinite variable.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
j_
Index of the semidefinite variable. -
barsj_
Value of the j’th variable of barx.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putbarsj
sourcepub fn put_barvar_name(&mut self, j_: i32, name_: &str) -> Result<(), String>
pub fn put_barvar_name(&mut self, j_: i32, name_: &str) -> Result<(), String>
Sets the name of a semidefinite variable.
§Arguments
j_
Index of the variable.name_
The variable name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putbarvarname
sourcepub fn put_barx_j(
&mut self,
whichsol_: i32,
j_: i32,
barxj_: &[f64]
) -> Result<(), String>
pub fn put_barx_j( &mut self, whichsol_: i32, j_: i32, barxj_: &[f64] ) -> Result<(), String>
Sets the primal solution for a semidefinite variable.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
j_
Index of the semidefinite variable. -
barxj_
Value of the j’th variable of barx.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putbarxj
sourcepub fn put_cfix(&mut self, cfix_: f64) -> Result<(), String>
pub fn put_cfix(&mut self, cfix_: f64) -> Result<(), String>
Replaces the fixed term in the objective.
§Arguments
cfix_
Fixed term in the objective.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putcfix
Examples found in repository?
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
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(())
}
More examples
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
fn main() -> Result<(),String> {
let numcon : i32 = 3;
let numvar : i32 = 4;
let c = [3.0, 1.0, 5.0, 1.0];
let asub = [0, 1, 2,
0, 1, 2, 3,
1, 3];
let aval = [3.0, 1.0, 2.0,
2.0, 1.0, 3.0, 1.0,
2.0, 3.0];
let aptr = [0,3,7,9];
let bkc = [Boundkey::FX,
Boundkey::LO,
Boundkey::UP];
let blc = [30.0,
15.0,
-INF];
let buc = [30.0,
INF,
25.0];
let bkx = [Boundkey::LO,
Boundkey::RA,
Boundkey::LO,
Boundkey::LO];
let blx = [0.0,
0.0,
0.0,
0.0];
let bux = [INF,
10.0,
INF,
INF];
// Create a task object linked with the environment env.
let mut task = Task::new().unwrap().with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Give MOSEK an estimate of the size of the input data.
This is done to increase the speed of inputting data.
However, it is optional. */
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for (j,(&cj,&bkj,&blj,&buj)) in izip!(c.iter(),bkx.iter(),blx.iter(),bux.iter()).enumerate() {
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32, cj)?;
/* Set the bounds on variable j.
blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, bkj, blj, buj)?;
};
/* Set the bounds on constraints.
for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for (i,(&bki,&bli,&bui,&ptrb,&ptre)) in izip!(bkc.iter(),blc.iter(),buc.iter(),aptr[..aptr.len()-1].iter(),aptr[1..].iter()).enumerate() {
task.put_con_bound(i as i32, bki, bli, bui)?;
/* Input row i of A */
task.put_a_row(i as i32, /* Row index.*/
&asub[ptrb..ptre], /* Column indexes of non-zeros in row i.*/
&aval[ptrb..ptre])?; /* Non-zero Values of row i. */
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS, // Basic solution.
xx.as_mut_slice());
match solsta {
Solsta::OPTIMAL =>
println!("Optimal primal solution = {:?}",xx),
Solsta::DUAL_INFEAS_CER|Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility."),
Solsta::UNKNOWN =>
println!("Unknown solution status."),
_ =>
println!("Other solution status")
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137
fn main() -> Result<(),String> {
let c = vec![ 0.0,-1.0,0.0 ];
let bkc = vec![ mosek::Boundkey::LO ];
let blc = vec![ 1.0 ];
let buc = vec![ INF ];
let bkx = vec![ Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = vec![ 0.0,
0.0,
0.0 ];
let bux = vec![ INF,
INF,
INF ];
let aptrb = vec![ 0, 1, 2 ];
let aptre = vec![ 1, 2, 3 ];
let asub = vec![ 0, 0, 0 ];
let aval = vec![ 1.0, 1.0, 1.0 ];
let qsubi = vec![ 0, 1, 2, 2 ];
let qsubj = vec![ 0, 1, 0, 2 ];
let qval = vec![ 2.0,0.2,-1.0,2.0 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
//r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for j in 0..NUMVAR
{
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32,c[j])?;
/* Set the bounds on variable j.
* blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, /* Index of variable.*/
bkx[j], /* Bound key.*/
blx[j], /* Numerical value of lower bound.*/
bux[j])?; /* Numerical value of upper bound.*/
/* Input column j of A */
task.put_a_col(j as i32, /* Variable (column) index.*/
&asub[aptrb[j]..aptre[j]], /* Pointer to row indexes of column j.*/
&aval[aptrb[j]..aptre[j]])?; /* Pointer to Values of column j.*/
}
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
for i in 0..NUMCON
{
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
/*
* The lower triangular part of the Q
* matrix in the objective is specified.
*/
/* Input the Q for the objective. */
task.put_q_obj(&qsubi,&qsubj,&qval)?;
}
let _trmcode = task.optimize()?;
/* Run optimizer */
/* Print a summary containing information
about the solution for debugging purposes*/
task.solution_summary(Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0, 0.0, 0.0];
task.get_xx(Soltype::ITR, /* Request the interior solution. */
& mut xx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR
{
println!("x[{}]: {}",j,xx[j]);
}
}
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.");
}
}
return Ok(());
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
fn main() -> Result<(),String>
{
let dimbarvar = vec![3]; /* Dimension of semidefinite cone */
let bkc = &[ mosek::Boundkey::FX, mosek::Boundkey::FX ];
let blc = &[ 1.0, 0.5 ];
let buc = &[ 1.0, 0.5 ];
let barc_i = &[0, 1, 1, 2, 2];
let barc_j = &[0, 0, 1, 1, 2];
let barc_v = &[2.0, 1.0, 2.0, 1.0, 2.0];
let aptrb = &[0, 1];
let aptre = &[1, 3];
let asub = &[0, 1, 2]; /* column subscripts of A */
let aval = &[1.0, 1.0, 1.0];
let bara_i = &[0, 1, 2, 0, 1, 2, 1, 2, 2];
let bara_j = &[0, 1, 2, 0, 0, 0, 1, 1, 2];
let bara_v = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let falpha = 1.0;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'NUMCON' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Append 'NUMBARVAR' semidefinite variables. */
task.append_barvars(&dimbarvar[..])?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
/* Set the linear term c_j in the objective.*/
task.put_c_j(0,1.0)?;
for j in 0..NUMVAR {
task.put_var_bound(j as i32,
mosek::Boundkey::FR,
-INF,
INF)?;
}
/* Set the linear term barc_j in the objective.*/
let c_symmat_idx = task.append_sparse_sym_mat(dimbarvar[0],
barc_i,
barc_j,
barc_v)?;
task.put_barc_j(0, &[c_symmat_idx], &[falpha])?;
for i in 0..NUMCON
{
/* Input A row by row */
task.put_a_row(i as i32,
& asub[aptrb[i]..aptre[i]],
& aval[aptrb[i]..aptre[i]])?;
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
}
{
/* Append the conic quadratic cone */
let afei = task.get_num_afe()?;
task.append_afes(3)?;
task.put_afe_f_entry_list(&[0,1,2],
&[0,1,2],
&[1.0,1.0,1.0])?;
let dom = task.append_quadratic_cone_domain(3)?;
task.append_acc_seq(dom,afei,&[0.0,0.0,0.0])?;
}
/* Add the first row of barA */
let a_symmat_idx1 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[..3],
& bara_j[..3],
& bara_v[..3])?;
task.put_bara_ij(0, 0, &[a_symmat_idx1][..], &[falpha][..])?;
/* Add the second row of barA */
let a_symmat_idx2 =
task.append_sparse_sym_mat(dimbarvar[0],
& bara_i[3..9],
& bara_j[3..9],
& bara_v[3..9])?;
task.put_bara_ij(1, 0, &[a_symmat_idx2][..], &[falpha][..])?;
let _trmcode = task.optimize()?;
task.write_data("sdo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0,0.0,0.0];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
& mut xx[..])?;
let mut barx = vec![0.0,0.0,0.0,0.0,0.0,0.0];
task.get_barx_j(Soltype::ITR, /* Request the interior solution. */
0,
& mut barx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR as usize
{
println!("x[{}]: {}",j,xx[j]);
}
let n = dimbarvar[0] as usize;
for j in 0..n
{
for i in j..n
{
println!("barx[{},{}]: {}",i,j,barx[j*n+i-j*(j+1)/2]);
}
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN =>
{
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",solsta);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn put_c_j(&mut self, j_: i32, cj_: f64) -> Result<(), String>
pub fn put_c_j(&mut self, j_: i32, cj_: f64) -> Result<(), String>
Modifies one linear coefficient in the objective.
§Arguments
j_
Index of the variable whose objective coefficient should be changed.cj_
New coefficient value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putcj
Examples found in repository?
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
More examples
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
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
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(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 3;
let numvar : i32 = 4;
let c = [3.0, 1.0, 5.0, 1.0];
let asub = [0, 1, 2,
0, 1, 2, 3,
1, 3];
let aval = [3.0, 1.0, 2.0,
2.0, 1.0, 3.0, 1.0,
2.0, 3.0];
let aptr = [0,3,7,9];
let bkc = [Boundkey::FX,
Boundkey::LO,
Boundkey::UP];
let blc = [30.0,
15.0,
-INF];
let buc = [30.0,
INF,
25.0];
let bkx = [Boundkey::LO,
Boundkey::RA,
Boundkey::LO,
Boundkey::LO];
let blx = [0.0,
0.0,
0.0,
0.0];
let bux = [INF,
10.0,
INF,
INF];
// Create a task object linked with the environment env.
let mut task = Task::new().unwrap().with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Give MOSEK an estimate of the size of the input data.
This is done to increase the speed of inputting data.
However, it is optional. */
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for (j,(&cj,&bkj,&blj,&buj)) in izip!(c.iter(),bkx.iter(),blx.iter(),bux.iter()).enumerate() {
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32, cj)?;
/* Set the bounds on variable j.
blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, bkj, blj, buj)?;
};
/* Set the bounds on constraints.
for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for (i,(&bki,&bli,&bui,&ptrb,&ptre)) in izip!(bkc.iter(),blc.iter(),buc.iter(),aptr[..aptr.len()-1].iter(),aptr[1..].iter()).enumerate() {
task.put_con_bound(i as i32, bki, bli, bui)?;
/* Input row i of A */
task.put_a_row(i as i32, /* Row index.*/
&asub[ptrb..ptre], /* Column indexes of non-zeros in row i.*/
&aval[ptrb..ptre])?; /* Non-zero Values of row i. */
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS, // Basic solution.
xx.as_mut_slice());
match solsta {
Solsta::OPTIMAL =>
println!("Optimal primal solution = {:?}",xx),
Solsta::DUAL_INFEAS_CER|Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility."),
Solsta::UNKNOWN =>
println!("Unknown solution status."),
_ =>
println!("Other solution status")
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137
fn main() -> Result<(),String> {
let c = vec![ 0.0,-1.0,0.0 ];
let bkc = vec![ mosek::Boundkey::LO ];
let blc = vec![ 1.0 ];
let buc = vec![ INF ];
let bkx = vec![ Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = vec![ 0.0,
0.0,
0.0 ];
let bux = vec![ INF,
INF,
INF ];
let aptrb = vec![ 0, 1, 2 ];
let aptre = vec![ 1, 2, 3 ];
let asub = vec![ 0, 0, 0 ];
let aval = vec![ 1.0, 1.0, 1.0 ];
let qsubi = vec![ 0, 1, 2, 2 ];
let qsubj = vec![ 0, 1, 0, 2 ];
let qval = vec![ 2.0,0.2,-1.0,2.0 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
//r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for j in 0..NUMVAR
{
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32,c[j])?;
/* Set the bounds on variable j.
* blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, /* Index of variable.*/
bkx[j], /* Bound key.*/
blx[j], /* Numerical value of lower bound.*/
bux[j])?; /* Numerical value of upper bound.*/
/* Input column j of A */
task.put_a_col(j as i32, /* Variable (column) index.*/
&asub[aptrb[j]..aptre[j]], /* Pointer to row indexes of column j.*/
&aval[aptrb[j]..aptre[j]])?; /* Pointer to Values of column j.*/
}
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
for i in 0..NUMCON
{
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
/*
* The lower triangular part of the Q
* matrix in the objective is specified.
*/
/* Input the Q for the objective. */
task.put_q_obj(&qsubi,&qsubj,&qval)?;
}
let _trmcode = task.optimize()?;
/* Run optimizer */
/* Print a summary containing information
about the solution for debugging purposes*/
task.solution_summary(Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0, 0.0, 0.0];
task.get_xx(Soltype::ITR, /* Request the interior solution. */
& mut xx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR
{
println!("x[{}]: {}",j,xx[j]);
}
}
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.");
}
}
return Ok(());
}
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 129 130 131 132 133 134 135 136 137 138 139 140
fn main() -> Result<(),String> {
const NUMCON : i32 = 1; /* Number of constraints. */
const NUMVAR : i32 = 3; /* Number of variables. */
let c = [0.0, -1.0, 0.0];
let bkc = [Boundkey::LO];
let blc = [1.0];
let buc = [INF];
let bkx = [Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = [0.0,
0.0,
0.0 ];
let bux = [INF,
INF,
INF ];
let asub = [ &[0i32], &[0i32], &[0i32] ];
let aval = [ &[1.0], &[1.0], &[1.0] ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Give MOSEK an estimate of the size of the input data.
// This is done to increase the speed of inputting data.
// However, it is optional.
// Append 'numcon' empty constraints.
// The constraints will initially have no bounds.
task.append_cons(NUMCON)?;
// Append 'numvar' variables.
// The variables will initially be fixed at zero (x=0).
task.append_vars(NUMVAR)?;
for (j,cj,bkj,blj,buj) in izip!(0..NUMVAR,c,bkx,blx,bux) {
// Set the linear term c_j in the objective.
task.put_c_j(j, cj)?;
// Set the bounds on variable j.
// blx[j] <= x_j <= bux[j]
task.put_var_bound(j, bkj, blj, buj)?;
}
for (j,asubj,avalj) in izip!(0..NUMVAR, asub, aval) {
/* Input column j of A */
task.put_a_col(j, /* Variable (column) index.*/
asubj, /* Row index of non-zeros in column j.*/
avalj)?; /* Non-zero Values of column j. */
}
// Set the bounds on constraints.
// for i=1, ...,numcon : blc[i] <= constraint i <= buc[i]
for (i,bki,bli,bui) in izip!(0..NUMCON,bkc,blc,buc) {
task.put_con_bound(i, bki, bli, bui)?;
}
{
// The lower triangular part of the Q
// matrix in the objective is specified.
let qosubi = &[ 0, 1, 2, 2 ];
let qosubj = &[ 0, 1, 0, 2 ];
let qoval = &[ 2.0, 0.2, -1.0, 2.0 ];
// Input the Q for the objective.
task.put_q_obj(qosubi, qosubj, qoval)?;
}
// The lower triangular part of the Q^0
// matrix in the first constraint is specified.
// This corresponds to adding the term
// x0^2 - x1^2 - 0.1 x2^2 + 0.2 x0 x2
{
let qsubi = &[0, 1, 2, 2 ];
let qsubj = &[0, 1, 2, 0 ];
let qval = &[-2.0, -2.0, -0.2, 0.2];
/* put Q^0 in constraint with index 0. */
task.put_q_con_k(0,
qsubi,
qsubj,
qval)?;
}
task.put_obj_sense(Objsense::MINIMIZE)?;
/* Solve the problem */
let _trm = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
let mut xx = vec![0.0; NUMVAR as usize];
task.get_xx(Soltype::ITR, // Interior solution.
xx.as_mut_slice())?;
match solsta {
Solsta::OPTIMAL => {
println!("Optimal primal solution");
for (j,xj) in izip!(0..NUMVAR,xx) {
println!("x[{}]: {}",j,xj);
}
},
Solsta::DUAL_INFEAS_CER|
Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility.\n"),
Solsta::UNKNOWN =>
println!("Unknown solution status.\n"),
_ =>
println!("Other solution status")
}
Ok(())
}
sourcepub fn put_c_list(&mut self, subj_: &[i32], val_: &[f64]) -> Result<(), String>
pub fn put_c_list(&mut self, subj_: &[i32], val_: &[f64]) -> Result<(), String>
Modifies a part of the linear objective coefficients.
§Arguments
subj_
Indices of variables for which objective coefficients should be changed.val_
New numerical values for the objective coefficients that should be modified.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putclist
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
sourcepub fn put_con_bound(
&mut self,
i_: i32,
bkc_: i32,
blc_: f64,
buc_: f64
) -> Result<(), String>
pub fn put_con_bound( &mut self, i_: i32, bkc_: i32, blc_: f64, buc_: f64 ) -> Result<(), String>
Changes the bound for one constraint.
§Arguments
-
i_
Index of the constraint. -
bkc_
New bound key.See Boundkey
-
blc_
New lower bound. -
buc_
New upper bound.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putconbound
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 3;
let numvar : i32 = 4;
let c = [3.0, 1.0, 5.0, 1.0];
let asub = [0, 1, 2,
0, 1, 2, 3,
1, 3];
let aval = [3.0, 1.0, 2.0,
2.0, 1.0, 3.0, 1.0,
2.0, 3.0];
let aptr = [0,3,7,9];
let bkc = [Boundkey::FX,
Boundkey::LO,
Boundkey::UP];
let blc = [30.0,
15.0,
-INF];
let buc = [30.0,
INF,
25.0];
let bkx = [Boundkey::LO,
Boundkey::RA,
Boundkey::LO,
Boundkey::LO];
let blx = [0.0,
0.0,
0.0,
0.0];
let bux = [INF,
10.0,
INF,
INF];
// Create a task object linked with the environment env.
let mut task = Task::new().unwrap().with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Give MOSEK an estimate of the size of the input data.
This is done to increase the speed of inputting data.
However, it is optional. */
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for (j,(&cj,&bkj,&blj,&buj)) in izip!(c.iter(),bkx.iter(),blx.iter(),bux.iter()).enumerate() {
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32, cj)?;
/* Set the bounds on variable j.
blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, bkj, blj, buj)?;
};
/* Set the bounds on constraints.
for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for (i,(&bki,&bli,&bui,&ptrb,&ptre)) in izip!(bkc.iter(),blc.iter(),buc.iter(),aptr[..aptr.len()-1].iter(),aptr[1..].iter()).enumerate() {
task.put_con_bound(i as i32, bki, bli, bui)?;
/* Input row i of A */
task.put_a_row(i as i32, /* Row index.*/
&asub[ptrb..ptre], /* Column indexes of non-zeros in row i.*/
&aval[ptrb..ptre])?; /* Non-zero Values of row i. */
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS, // Basic solution.
xx.as_mut_slice());
match solsta {
Solsta::OPTIMAL =>
println!("Optimal primal solution = {:?}",xx),
Solsta::DUAL_INFEAS_CER|Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility."),
Solsta::UNKNOWN =>
println!("Unknown solution status."),
_ =>
println!("Other solution status")
}
Ok(())
}
sourcepub fn put_con_bound_list(
&mut self,
sub_: &[i32],
bkc_: &[i32],
blc_: &[f64],
buc_: &[f64]
) -> Result<(), String>
pub fn put_con_bound_list( &mut self, sub_: &[i32], bkc_: &[i32], blc_: &[f64], buc_: &[f64] ) -> Result<(), String>
Changes the bounds of a list of constraints.
§Arguments
-
sub_
List of constraint indexes. -
bkc_
Bound keys for the constraints.See Boundkey
-
blc_
Lower bounds for the constraints. -
buc_
Upper bounds for the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putconboundlist
sourcepub fn put_con_bound_list_const(
&mut self,
sub_: &[i32],
bkc_: i32,
blc_: f64,
buc_: f64
) -> Result<(), String>
pub fn put_con_bound_list_const( &mut self, sub_: &[i32], bkc_: i32, blc_: f64, buc_: f64 ) -> Result<(), String>
Changes the bounds of a list of constraints.
§Arguments
-
sub_
List of constraint indexes. -
bkc_
New bound key for all constraints in the list.See Boundkey
-
blc_
New lower bound for all constraints in the list. -
buc_
New upper bound for all constraints in the list.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putconboundlistconst
sourcepub fn put_con_bound_slice(
&mut self,
first_: i32,
last_: i32,
bkc_: &[i32],
blc_: &[f64],
buc_: &[f64]
) -> Result<(), String>
pub fn put_con_bound_slice( &mut self, first_: i32, last_: i32, bkc_: &[i32], blc_: &[f64], buc_: &[f64] ) -> Result<(), String>
Changes the bounds for a slice of the constraints.
§Arguments
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
bkc_
Bound keys for the constraints.See Boundkey
-
blc_
Lower bounds for the constraints. -
buc_
Upper bounds for the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putconboundslice
Examples found in repository?
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
/* Input data */
let numcon : i32 = 2; /* Number of constraints. */
let dimbarvar : &[i32] = &[3, 4]; /* Dimension of semidefinite variables */
/* Objective coefficients concatenated */
let Cj : &[i32] = &[ 0, 0, 1, 1, 1, 1 ]; /* Which symmetric variable (j) */
let Ck : &[i32] = &[ 0, 2, 0, 1, 1, 2 ]; /* Which entry (k,l)->v */
let Cl : &[i32] = &[ 0, 2, 0, 0, 1, 2 ];
let Cv : &[f64] = &[ 1.0, 6.0, 1.0, -3.0, 2.0, 1.0 ];
/* Equality constraints coefficients concatenated */
let Ai : &[i32] = &[ 0, 0, 0, 0, 0, 0 ]; /* Which constraint (i = 0) */
let Aj : &[i32] = &[ 0, 0, 0, 1, 1, 1 ]; /* Which symmetric variable (j) */
let Ak : &[i32] = &[ 0, 2, 2, 1, 1, 3 ]; /* Which entry (k,l)->v */
let Al : &[i32] = &[ 0, 0, 2, 0, 1, 3 ];
let Av : &[f64] = &[ 1.0, 1.0, 2.0, 1.0, -1.0, -3.0 ];
/* The second constraint - one-term inequality */
let A2i : &[i32] = &[ 1 ]; /* Which constraint (i = 1) */
let A2j : &[i32] = &[ 1 ]; /* Which symmetric variable (j = 1) */
let A2k : &[i32] = &[ 1 ]; /* Which entry A(1,0) = A(0,1) = 0.5 */
let A2l : &[i32] = &[ 0 ];
let A2v : &[f64] = &[ 0.5 ];
let bkc = &[ mosek::Boundkey::FX,
mosek::Boundkey::UP ];
let blc = &[ 23.0, 0.0 ];
let buc = &[ 23.0, -3.0 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append numcon empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append numbarvar semidefinite variables. */
task.append_barvars(dimbarvar)?;
/* Set objective (6 nonzeros).*/
task.put_barc_block_triplet(Cj, Ck, Cl, Cv)?;
/* Set the equality constraint (6 nonzeros).*/
task.put_bara_block_triplet(Ai, Aj, Ak, Al, Av)?;
/* Set the inequality constraint (1 nonzero).*/
task.put_bara_block_triplet(A2i, A2j, A2k, A2l, A2v)?;
/* Set constraint bounds */
task.put_con_bound_slice(0, 2, bkc, blc, buc)?;
/* Run optimizer */
task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
//mosek.solsta[] solsta = new mosek.solsta[1];
let solsta = task.get_sol_sta (Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
/* Retrieve the soution for all symmetric variables */
println!("Solution (lower triangular part vectorized):");
for (i,dimbarvari) in dimbarvar.iter().enumerate() {
//let dim = dimbarvar[i] * (dimbarvar[i] + 1) / 2;
let dim = dimbarvari * (dimbarvari+1)/2;
//double[] barx = new double[dim];
let mut barx : Vec<f64> = vec![0.0; dim as usize];
task.get_barx_j(Soltype::ITR, i as i32, barx.as_mut_slice())?;
println!("X{}: {:?}",i+1,barx);
// for (int j = 0; j < dim; ++j)
// System.out.print(barx[j] + " ");
// System.out.println();
}
},
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(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn put_con_bound_slice_const(
&mut self,
first_: i32,
last_: i32,
bkc_: i32,
blc_: f64,
buc_: f64
) -> Result<(), String>
pub fn put_con_bound_slice_const( &mut self, first_: i32, last_: i32, bkc_: i32, blc_: f64, buc_: f64 ) -> Result<(), String>
Changes the bounds for a slice of the constraints.
§Arguments
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
bkc_
New bound key for all constraints in the slice.See Boundkey
-
blc_
New lower bound for all constraints in the slice. -
buc_
New upper bound for all constraints in the slice.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putconboundsliceconst
Examples found in repository?
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 129 130
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
More examples
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
sourcepub fn put_cone(
&mut self,
k_: i32,
ct_: i32,
conepar_: f64,
submem_: &[i32]
) -> Result<(), String>
pub fn put_cone( &mut self, k_: i32, ct_: i32, conepar_: f64, submem_: &[i32] ) -> Result<(), String>
Replaces a conic constraint.
§Arguments
-
k_
Index of the cone. -
ct_
Specifies the type of the cone.See Conetype
-
conepar_
For the power cone it denotes the exponent alpha. For other cone types it is unused and can be set to 0. -
submem_
Variable subscripts of the members in the cone.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putcone
sourcepub fn put_cone_name(&mut self, j_: i32, name_: &str) -> Result<(), String>
pub fn put_cone_name(&mut self, j_: i32, name_: &str) -> Result<(), String>
Sets the name of a cone.
§Arguments
j_
Index of the cone.name_
The name of the cone.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putconename
sourcepub fn put_con_name(&mut self, i_: i32, name_: &str) -> Result<(), String>
pub fn put_con_name(&mut self, i_: i32, name_: &str) -> Result<(), String>
Sets the name of a constraint.
§Arguments
i_
Index of the constraint.name_
The name of the constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putconname
Examples found in repository?
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
More examples
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
fn portfolio(w : f64,
mu : &[f64],
x0 : &[f64],
gammas : &[f64],
theta : &[f64],
GT : &Matrix) -> Result<Vec<(f64,f64)>,String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
let (kx,nx) = GT.size();
if mu.len() != nx { panic!("Mismatching data"); }
let k : i32 = kx.try_into().unwrap();
let n : i32 = nx.try_into().unwrap();
let total_budget : f64 = w + x0.iter().sum::<f64>();
//Offset of variables into the API variable.
let numvar = n;
let voff_x : i32 = 0;
// Constraint offset
let coff_bud : i32 = 0;
// Holding variable x of length n
// No other auxiliary variables are needed in this formulation
task.append_vars(numvar)?;
// Setting up variable x
for j in 0..n {
task.put_var_name(voff_x+j,format!("x[{}]",j+1).as_str())?;
}
task.put_var_bound_slice_const(voff_x,voff_x+n, Boundkey::LO,0.0, INF)?;
// One linear constraint: total budget
task.append_cons(1)?;
task.put_con_name(coff_bud, "budget")?;
/* Coefficients in the first row of A */
for j in 0..n {
task.put_aij(coff_bud,voff_x + j, 1.0)?;
}
task.put_con_bound(coff_bud, Boundkey::FX, total_budget, total_budget)?;
// Input (gamma, G_factor_T x, diag(sqrt(theta))*x) in the AFE (affine expression) storage
// We need k+n+1 rows and we fill them in in three parts
task.append_afes((k+n) as i64 + 1)?;
// 1. The first affine expression = gamma, will be specified later
// 2. The next k expressions comprise G_factor_T*x, we add them row by row
// transposing the matrix G_factor on the fly
task.put_afe_f_row_list((1..1+k as i64).collect::<Vec<i64>>().as_slice(), // f row idxs
vec![n; k as usize].as_slice(), // row lengths
(0..GT.len() as i64).step_by(n as usize).collect::<Vec<i64>>().as_slice(), // row ptr
iproduct!(0..k,0..n).map(|(_,b)| b).collect::<Vec<i32>>().as_slice(), // varidx, 0..n repeated k times
GT.data_by_row().as_slice())?;
// 3. The remaining n rows contain sqrt(theta) on the diagonal
for (i,thetai) in (0..n).zip(theta.iter()) {
task.put_afe_f_entry(i as i64 + 1 + k as i64, voff_x + i, thetai.sqrt())?;
}
// Input the affine conic constraint (gamma, GT*x) \in QCone
// Add the quadratic domain of dimension k+1
let qdom = task.append_quadratic_cone_domain(k as i64+ 1)?;
// Add the constraint
task.append_acc_seq(qdom, 0, vec![0.0; k as usize+1].as_slice())?;
task.put_acc_name(0, "risk")?;
// Objective: maximize expected return mu^T x
for (j,&muj) in (0..n).zip(mu.iter()) {
task.put_c_j(voff_x + j, muj)?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
Ok(gammas.iter().filter_map(|&gamma| {
// Specify gamma in ACC
task.put_afe_g(0, gamma).ok()?;
task.optimize().ok()?;
/* Display solution summary for quick inspection of results */
let _ = task.solution_summary(Streamtype::LOG);
let _ = task.write_data(format!("portfolio_6_factor-{}.ptf",gamma).as_str());
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR).ok()? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Read the results */
let mut xx = vec![0.0; n as usize];
task.get_xx_slice(Soltype::ITR, voff_x, voff_x + n, xx.as_mut_slice()).ok()?;
Some((gamma,xx.iter().zip(mu.iter()).map(|(&xj,&muj)| xj*muj).sum::<f64>()))
}).collect::<Vec<(f64,f64)>>())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn put_con_solution_i(
&mut self,
i_: i32,
whichsol_: i32,
sk_: i32,
x_: f64,
sl_: f64,
su_: f64
) -> Result<(), String>
pub fn put_con_solution_i( &mut self, i_: i32, whichsol_: i32, sk_: i32, x_: f64, sl_: f64, su_: f64 ) -> Result<(), String>
Sets the primal and dual solution information for a single constraint.
§Arguments
-
i_
Index of the constraint. -
whichsol_
Selects a solution.See Soltype
-
sk_
Status key of the constraint.See Stakey
-
x_
Primal solution value of the constraint. -
sl_
Solution value of the dual variable associated with the lower bound. -
su_
Solution value of the dual variable associated with the upper bound.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putconsolutioni
sourcepub fn put_c_slice(
&mut self,
first_: i32,
last_: i32,
slice_: &[f64]
) -> Result<(), String>
pub fn put_c_slice( &mut self, first_: i32, last_: i32, slice_: &[f64] ) -> Result<(), String>
Modifies a slice of the linear objective coefficients.
§Arguments
first_
First element in the slice of c.last_
Last element plus 1 of the slice in c to be changed.slice_
New numerical values for the objective coefficients that should be modified.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putcslice
Examples found in repository?
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
More examples
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
sourcepub fn put_djc(
&mut self,
djcidx_: i64,
domidxlist_: &[i64],
afeidxlist_: &[i64],
b_: &[f64],
termsizelist_: &[i64]
) -> Result<(), String>
pub fn put_djc( &mut self, djcidx_: i64, domidxlist_: &[i64], afeidxlist_: &[i64], b_: &[f64], termsizelist_: &[i64] ) -> Result<(), String>
Inputs a disjunctive constraint.
§Arguments
djcidx_
Index of the disjunctive constraint.domidxlist_
List of domain indexes.afeidxlist_
List of affine expression indexes.b_
The vector of constant terms modifying affine expressions.termsizelist_
List of term sizes.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putdjc
Examples found in repository?
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
sourcepub fn put_djc_name(&mut self, djcidx_: i64, name_: &str) -> Result<(), String>
pub fn put_djc_name(&mut self, djcidx_: i64, name_: &str) -> Result<(), String>
Sets the name of a disjunctive constraint.
§Arguments
djcidx_
Index of the disjunctive constraint.name_
The name of the disjunctive constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putdjcname
sourcepub fn put_djc_slice(
&mut self,
idxfirst_: i64,
idxlast_: i64,
domidxlist_: &[i64],
afeidxlist_: &[i64],
b_: &[f64],
termsizelist_: &[i64],
termsindjc_: &[i64]
) -> Result<(), String>
pub fn put_djc_slice( &mut self, idxfirst_: i64, idxlast_: i64, domidxlist_: &[i64], afeidxlist_: &[i64], b_: &[f64], termsizelist_: &[i64], termsindjc_: &[i64] ) -> Result<(), String>
Inputs a slice of disjunctive constraints.
§Arguments
idxfirst_
Index of the first disjunctive constraint in the slice.idxlast_
Index of the last disjunctive constraint in the slice plus 1.domidxlist_
List of domain indexes.afeidxlist_
List of affine expression indexes.b_
The vector of constant terms modifying affine expressions. Optional.termsizelist_
List of term sizes.termsindjc_
Number of terms in each of the disjunctive constraints in the slice.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putdjcslice
sourcepub fn put_domain_name(
&mut self,
domidx_: i64,
name_: &str
) -> Result<(), String>
pub fn put_domain_name( &mut self, domidx_: i64, name_: &str ) -> Result<(), String>
Sets the name of a domain.
§Arguments
domidx_
Index of the domain.name_
The name of the domain.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putdomainname
sourcepub fn put_dou_param(
&mut self,
param_: i32,
parvalue_: f64
) -> Result<(), String>
pub fn put_dou_param( &mut self, param_: i32, parvalue_: f64 ) -> Result<(), String>
Sets a double parameter.
§Arguments
-
param_
Which parameter.See Dparam
-
parvalue_
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putdouparam
sourcepub fn put_int_param(
&mut self,
param_: i32,
parvalue_: i32
) -> Result<(), String>
pub fn put_int_param( &mut self, param_: i32, parvalue_: i32 ) -> Result<(), String>
Sets an integer parameter.
§Arguments
-
param_
Which parameter.See Iparam
-
parvalue_
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putintparam
Examples found in repository?
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
fn feasrepairex1(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
match filename {
FileOrText::File(fname) => task.read_data(fname.as_str())?,
FileOrText::Text(data) => task.read_lp_string(data.as_str())?
}
task.put_int_param(mosek::Iparam::LOG_FEAS_REPAIR, 3)?;
let wc = vec![1.0; task.get_num_con()? as usize];
let wx = vec![1.0; task.get_num_var()? as usize];
task.primal_repair(wc.as_slice(),wc.as_slice(),wx.as_slice(),wx.as_slice())?;
let sum_viol = task.get_dou_inf(mosek::Dinfitem::PRIMAL_REPAIR_PENALTY_OBJ)?;
println!("Minimized sum of violations = {}", sum_viol);
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::MSG)?;
Ok(())
}
More examples
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
fn simple(filename : FileOrText, outfile : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(fname) => {
task.read_data(fname.as_str())?
},
FileOrText::Text(data) => {
task.read_ptf_string(data.as_str())?
}
}
// Solve the problem
let _ = task.optimize()?;
// Print a summary of the solution
task.solution_summary(Streamtype::LOG)?;
// If an output file was specified, save problem to file
if let Some(outfile) = outfile {
// If using OPF format, these parameters will specify what to include in output
task.put_int_param(Iparam::OPF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_PROBLEM, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_HINTS, Onoffkey::OFF)?;
task.put_int_param(Iparam::OPF_WRITE_PARAMETERS, Onoffkey::OFF)?;
task.put_int_param(Iparam::PTF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.write_data(outfile.as_str())?;
}
Ok(())
}
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
fn main() -> Result<(),String> {
let numvar : i32 = 4;
let numcon : i32 = 1;
let c = &[ 7.0, 10.0, 1.0, 5.0 ];
let bkc = &[Boundkey::UP];
let blc = &[ -INF ];
let buc = &[2.5];
let bkx = &[Boundkey::LO,
Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = &[0.0,
0.0,
0.0,
0.0 ];
let bux = &[INF,
INF,
INF,
INF];
let ptrb = &[0i64, 1, 2, 3];
let ptre = &[1i64, 2, 3, 4];
let aval = &[1.0, 1.0, 1.0, 1.0];
let asub = &[0i32, 0, 0, 0 ];
let intsub = &[0i32, 1, 2];
let inttype = &[Variabletype::TYPE_INT,
Variabletype::TYPE_INT,
Variabletype::TYPE_INT ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon, numvar,
c, 0.0,
ptrb, ptre,
asub, aval,
bkc, blc, buc,
bkx, blx, bux)?;
task.put_var_type_list(intsub, inttype)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MAXIMIZE)?;
// Assign values to integer variables
// We only set that slice of xx
task.put_xx_slice(Soltype::ITG, 0, 3, &[1.0,1.0,0.0])?;
// Request constructing the solution from integer variable values
task.put_int_param(mosek::Iparam::MIO_CONSTRUCT_SOL, mosek::Onoffkey::ON)?;
// solve
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::LOG)?;
// Read and print solution
let mut xx = vec![0.0; numvar as usize];
task.get_xx(mosek::Soltype::ITG, xx.as_mut_slice())?;
println!("Optimal solution:");
for (i,xi) in xx.iter().enumerate() {
println!("x[{}] = {}",i,*xi);
}
// Was the initial solution used?
let constr = task.get_int_inf(mosek::Iinfitem::MIO_CONSTRUCT_SOLUTION)?;
let constr_val = task.get_dou_inf(mosek::Dinfitem::MIO_CONSTRUCT_SOLUTION_OBJ)?;
println!("Construct solution utilization: {}", constr);
println!("Construct solution objective: {}", constr_val);
Ok(())
}
sourcepub fn put_max_num_acc(&mut self, maxnumacc_: i64) -> Result<(), String>
pub fn put_max_num_acc(&mut self, maxnumacc_: i64) -> Result<(), String>
Sets the number of preallocated affine conic constraints.
§Arguments
maxnumacc_
Number of preallocated affine conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putmaxnumacc
sourcepub fn put_max_num_afe(&mut self, maxnumafe_: i64) -> Result<(), String>
pub fn put_max_num_afe(&mut self, maxnumafe_: i64) -> Result<(), String>
Sets the number of preallocated affine expressions in the optimization task.
§Arguments
maxnumafe_
Number of preallocated affine expressions.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putmaxnumafe
sourcepub fn put_max_num_a_nz(&mut self, maxnumanz_: i64) -> Result<(), String>
pub fn put_max_num_a_nz(&mut self, maxnumanz_: i64) -> Result<(), String>
Sets the number of preallocated non-zero entries in the linear coefficient matrix.
§Arguments
maxnumanz_
New size of the storage reserved for storing the linear coefficient matrix.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putmaxnumanz
sourcepub fn put_max_num_barvar(&mut self, maxnumbarvar_: i32) -> Result<(), String>
pub fn put_max_num_barvar(&mut self, maxnumbarvar_: i32) -> Result<(), String>
Sets the number of preallocated symmetric matrix variables.
§Arguments
maxnumbarvar_
Number of preallocated symmetric matrix variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putmaxnumbarvar
sourcepub fn put_max_num_con(&mut self, maxnumcon_: i32) -> Result<(), String>
pub fn put_max_num_con(&mut self, maxnumcon_: i32) -> Result<(), String>
Sets the number of preallocated constraints in the optimization task.
§Arguments
maxnumcon_
Number of preallocated constraints in the optimization task.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putmaxnumcon
sourcepub fn put_max_num_cone(&mut self, maxnumcone_: i32) -> Result<(), String>
pub fn put_max_num_cone(&mut self, maxnumcone_: i32) -> Result<(), String>
Sets the number of preallocated conic constraints in the optimization task.
§Arguments
maxnumcone_
Number of preallocated conic constraints in the optimization task.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putmaxnumcone
sourcepub fn put_max_num_djc(&mut self, maxnumdjc_: i64) -> Result<(), String>
pub fn put_max_num_djc(&mut self, maxnumdjc_: i64) -> Result<(), String>
Sets the number of preallocated disjunctive constraints.
§Arguments
maxnumdjc_
Number of preallocated disjunctive constraints in the task.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putmaxnumdjc
sourcepub fn put_max_num_domain(&mut self, maxnumdomain_: i64) -> Result<(), String>
pub fn put_max_num_domain(&mut self, maxnumdomain_: i64) -> Result<(), String>
Sets the number of preallocated domains in the optimization task.
§Arguments
maxnumdomain_
Number of preallocated domains.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putmaxnumdomain
sourcepub fn put_max_num_q_nz(&mut self, maxnumqnz_: i64) -> Result<(), String>
pub fn put_max_num_q_nz(&mut self, maxnumqnz_: i64) -> Result<(), String>
Sets the number of preallocated non-zero entries in quadratic terms.
§Arguments
maxnumqnz_
Number of non-zero elements preallocated in quadratic coefficient matrices.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putmaxnumqnz
sourcepub fn put_max_num_var(&mut self, maxnumvar_: i32) -> Result<(), String>
pub fn put_max_num_var(&mut self, maxnumvar_: i32) -> Result<(), String>
Sets the number of preallocated variables in the optimization task.
§Arguments
maxnumvar_
Number of preallocated variables in the optimization task.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putmaxnumvar
sourcepub fn put_na_dou_param(
&mut self,
paramname_: &str,
parvalue_: f64
) -> Result<(), String>
pub fn put_na_dou_param( &mut self, paramname_: &str, parvalue_: f64 ) -> Result<(), String>
Sets a double parameter.
§Arguments
paramname_
Name of a parameter.parvalue_
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putnadouparam
sourcepub fn put_na_int_param(
&mut self,
paramname_: &str,
parvalue_: i32
) -> Result<(), String>
pub fn put_na_int_param( &mut self, paramname_: &str, parvalue_: i32 ) -> Result<(), String>
Sets an integer parameter.
§Arguments
paramname_
Name of a parameter.parvalue_
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putnaintparam
sourcepub fn put_na_str_param(
&mut self,
paramname_: &str,
parvalue_: &str
) -> Result<(), String>
pub fn put_na_str_param( &mut self, paramname_: &str, parvalue_: &str ) -> Result<(), String>
Sets a string parameter.
§Arguments
paramname_
Name of a parameter.parvalue_
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putnastrparam
sourcepub fn put_obj_name(&mut self, objname_: &str) -> Result<(), String>
pub fn put_obj_name(&mut self, objname_: &str) -> Result<(), String>
Assigns a new name to the objective.
§Arguments
objname_
Name of the objective.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putobjname
Examples found in repository?
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
fn solve() -> Result<(),String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.put_obj_name("solvebasis")?;
let numcon : i32 = 2;
let numvar : i32 = 2;
let mut w1 = vec![2.0, 6.0];
let mut w2 = vec![1.0, 0.0];
task.input_data(numcon, numvar,
&[1.0, 1.0], // c
0.0, // cfix
&[0,2], // ptrb
&[2,3], // ptre
&[0,1,
0,1], // sub
&[1.0, 1.0,
2.0, 1.0], // val
&[Boundkey::UP,
Boundkey::UP], // bkc
&[0.0,0.0], // blc
&[2.0,6.0], // buc
&[Boundkey::LO,
Boundkey::LO], // bkx
&[0.0, 0.0], // blx
&[0.0,0.0])?; // bux;
task.put_obj_sense(Objsense::MAXIMIZE)?;
let _ = task.optimize()?;
let mut basis = vec![0i32; numcon as usize];
task.init_basis_solve(basis.as_mut_slice())?;
// List basis variables corresponding to columns of B
let mut varsub = vec![0i32, 1];
for i in 0..numcon {
if basis[varsub[i as usize] as usize] < numcon {
println!("Basis variable no {} is xc{}",i,basis[varsub[i as usize] as usize]);
}
else {
println!("Basis variable no {} is x{}",i,basis[i as usize]-numcon);
// solve Bx = w1
// varsub contains index of non-zeros in b.
// On return b contains the solution x and
// varsub the index of the non-zeros in x.
{
let nz = task.solve_with_basis(false, 2, varsub.as_mut_slice(), w1.as_mut_slice())?;
println!("nz = {}",nz);
println!("Solution to Bx = {:?}",w1);
for vsubi in &varsub[0..nz as usize] {
if basis[*vsubi as usize] < numcon {
println!("xc {} = {}",basis[*vsubi as usize],w1[*vsubi as usize]);
}
else {
println!("x{} = {}",basis[*vsubi as usize] - numcon,w1[*vsubi as usize])
}
}
}
// Solve B^Tx = w2
{
varsub[0] = 1;
let nz = task.solve_with_basis(true,1,varsub.as_mut_slice(),w2.as_mut_slice())?;
println!("nz = {}",nz);
println!("Solution to B^Tx = {:?}",w2);
for vsubi in &varsub[0..nz as usize] {
if basis[*vsubi as usize] < numcon {
print!("xc{} = {}",basis[*vsubi as usize],w2[*vsubi as usize]);
}
else {
print!("x{} = {}",basis[*vsubi as usize] - numcon,w2[*vsubi as usize]);
}
}
}
}
}
Ok(())
}
sourcepub fn put_obj_sense(&mut self, sense_: i32) -> Result<(), String>
pub fn put_obj_sense(&mut self, sense_: i32) -> Result<(), String>
Sets the objective sense.
§Arguments
-
sense_
The objective sense of the taskSee Objsense
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putobjsense
Examples found in repository?
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
More examples
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
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
fn main() -> Result<(),String> {
let numvar : i32 = 4;
let numcon : i32 = 1;
let c = &[ 7.0, 10.0, 1.0, 5.0 ];
let bkc = &[Boundkey::UP];
let blc = &[ -INF ];
let buc = &[2.5];
let bkx = &[Boundkey::LO,
Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = &[0.0,
0.0,
0.0,
0.0 ];
let bux = &[INF,
INF,
INF,
INF];
let ptrb = &[0i64, 1, 2, 3];
let ptre = &[1i64, 2, 3, 4];
let aval = &[1.0, 1.0, 1.0, 1.0];
let asub = &[0i32, 0, 0, 0 ];
let intsub = &[0i32, 1, 2];
let inttype = &[Variabletype::TYPE_INT,
Variabletype::TYPE_INT,
Variabletype::TYPE_INT ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon, numvar,
c, 0.0,
ptrb, ptre,
asub, aval,
bkc, blc, buc,
bkx, blx, bux)?;
task.put_var_type_list(intsub, inttype)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MAXIMIZE)?;
// Assign values to integer variables
// We only set that slice of xx
task.put_xx_slice(Soltype::ITG, 0, 3, &[1.0,1.0,0.0])?;
// Request constructing the solution from integer variable values
task.put_int_param(mosek::Iparam::MIO_CONSTRUCT_SOL, mosek::Onoffkey::ON)?;
// solve
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::LOG)?;
// Read and print solution
let mut xx = vec![0.0; numvar as usize];
task.get_xx(mosek::Soltype::ITG, xx.as_mut_slice())?;
println!("Optimal solution:");
for (i,xi) in xx.iter().enumerate() {
println!("x[{}] = {}",i,*xi);
}
// Was the initial solution used?
let constr = task.get_int_inf(mosek::Iinfitem::MIO_CONSTRUCT_SOLUTION)?;
let constr_val = task.get_dou_inf(mosek::Dinfitem::MIO_CONSTRUCT_SOLUTION_OBJ)?;
println!("Construct solution utilization: {}", constr);
println!("Construct solution objective: {}", constr_val);
Ok(())
}
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
sourcepub fn put_optserver_host(&mut self, host_: &str) -> Result<(), String>
pub fn put_optserver_host(&mut self, host_: &str) -> Result<(), String>
Specify an OptServer for remote calls.
§Arguments
host_
A URL specifying the optimization server to be used.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putoptserverhost
Examples found in repository?
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
fn opt_server_sync(inputfile : FileOrText, addr : String, cert : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Load some data into the task
match inputfile {
FileOrText::File(filename) => task.read_data(filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Set OptServer URL
task.put_optserver_host(addr.as_str())?;
// Path to certificate, if any
if let Some(cert) = cert {
task.put_str_param(Sparam::REMOTE_TLS_CERT_PATH, cert.as_str())?;
}
// Optimize remotely, no access token
let _trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
Ok(())
}
sourcepub fn put_param(
&mut self,
parname_: &str,
parvalue_: &str
) -> Result<(), String>
pub fn put_param( &mut self, parname_: &str, parvalue_: &str ) -> Result<(), String>
Modifies the value of parameter.
§Arguments
parname_
Parameter name.parvalue_
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putparam
sourcepub fn put_q_con(
&mut self,
qcsubk_: &[i32],
qcsubi_: &[i32],
qcsubj_: &[i32],
qcval_: &[f64]
) -> Result<(), String>
pub fn put_q_con( &mut self, qcsubk_: &[i32], qcsubi_: &[i32], qcsubj_: &[i32], qcval_: &[f64] ) -> Result<(), String>
Replaces all quadratic terms in constraints.
§Arguments
qcsubk_
Constraint subscripts for quadratic coefficients.qcsubi_
Row subscripts for quadratic constraint matrix.qcsubj_
Column subscripts for quadratic constraint matrix.qcval_
Quadratic constraint coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putqcon
sourcepub fn put_q_con_k(
&mut self,
k_: i32,
qcsubi_: &[i32],
qcsubj_: &[i32],
qcval_: &[f64]
) -> Result<(), String>
pub fn put_q_con_k( &mut self, k_: i32, qcsubi_: &[i32], qcsubj_: &[i32], qcval_: &[f64] ) -> Result<(), String>
Replaces all quadratic terms in a single constraint.
§Arguments
k_
The constraint in which the new quadratic elements are inserted.qcsubi_
Row subscripts for quadratic constraint matrix.qcsubj_
Column subscripts for quadratic constraint matrix.qcval_
Quadratic constraint coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putqconk
Examples found in repository?
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 129 130 131 132 133 134 135 136 137 138 139 140
fn main() -> Result<(),String> {
const NUMCON : i32 = 1; /* Number of constraints. */
const NUMVAR : i32 = 3; /* Number of variables. */
let c = [0.0, -1.0, 0.0];
let bkc = [Boundkey::LO];
let blc = [1.0];
let buc = [INF];
let bkx = [Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = [0.0,
0.0,
0.0 ];
let bux = [INF,
INF,
INF ];
let asub = [ &[0i32], &[0i32], &[0i32] ];
let aval = [ &[1.0], &[1.0], &[1.0] ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Give MOSEK an estimate of the size of the input data.
// This is done to increase the speed of inputting data.
// However, it is optional.
// Append 'numcon' empty constraints.
// The constraints will initially have no bounds.
task.append_cons(NUMCON)?;
// Append 'numvar' variables.
// The variables will initially be fixed at zero (x=0).
task.append_vars(NUMVAR)?;
for (j,cj,bkj,blj,buj) in izip!(0..NUMVAR,c,bkx,blx,bux) {
// Set the linear term c_j in the objective.
task.put_c_j(j, cj)?;
// Set the bounds on variable j.
// blx[j] <= x_j <= bux[j]
task.put_var_bound(j, bkj, blj, buj)?;
}
for (j,asubj,avalj) in izip!(0..NUMVAR, asub, aval) {
/* Input column j of A */
task.put_a_col(j, /* Variable (column) index.*/
asubj, /* Row index of non-zeros in column j.*/
avalj)?; /* Non-zero Values of column j. */
}
// Set the bounds on constraints.
// for i=1, ...,numcon : blc[i] <= constraint i <= buc[i]
for (i,bki,bli,bui) in izip!(0..NUMCON,bkc,blc,buc) {
task.put_con_bound(i, bki, bli, bui)?;
}
{
// The lower triangular part of the Q
// matrix in the objective is specified.
let qosubi = &[ 0, 1, 2, 2 ];
let qosubj = &[ 0, 1, 0, 2 ];
let qoval = &[ 2.0, 0.2, -1.0, 2.0 ];
// Input the Q for the objective.
task.put_q_obj(qosubi, qosubj, qoval)?;
}
// The lower triangular part of the Q^0
// matrix in the first constraint is specified.
// This corresponds to adding the term
// x0^2 - x1^2 - 0.1 x2^2 + 0.2 x0 x2
{
let qsubi = &[0, 1, 2, 2 ];
let qsubj = &[0, 1, 2, 0 ];
let qval = &[-2.0, -2.0, -0.2, 0.2];
/* put Q^0 in constraint with index 0. */
task.put_q_con_k(0,
qsubi,
qsubj,
qval)?;
}
task.put_obj_sense(Objsense::MINIMIZE)?;
/* Solve the problem */
let _trm = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
let mut xx = vec![0.0; NUMVAR as usize];
task.get_xx(Soltype::ITR, // Interior solution.
xx.as_mut_slice())?;
match solsta {
Solsta::OPTIMAL => {
println!("Optimal primal solution");
for (j,xj) in izip!(0..NUMVAR,xx) {
println!("x[{}]: {}",j,xj);
}
},
Solsta::DUAL_INFEAS_CER|
Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility.\n"),
Solsta::UNKNOWN =>
println!("Unknown solution status.\n"),
_ =>
println!("Other solution status")
}
Ok(())
}
sourcepub fn put_q_obj(
&mut self,
qosubi_: &[i32],
qosubj_: &[i32],
qoval_: &[f64]
) -> Result<(), String>
pub fn put_q_obj( &mut self, qosubi_: &[i32], qosubj_: &[i32], qoval_: &[f64] ) -> Result<(), String>
Replaces all quadratic terms in the objective.
§Arguments
qosubi_
Row subscripts for quadratic objective coefficients.qosubj_
Column subscripts for quadratic objective coefficients.qoval_
Quadratic objective coefficient values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putqobj
Examples found in repository?
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 129 130 131 132 133 134 135 136 137
fn main() -> Result<(),String> {
let c = vec![ 0.0,-1.0,0.0 ];
let bkc = vec![ mosek::Boundkey::LO ];
let blc = vec![ 1.0 ];
let buc = vec![ INF ];
let bkx = vec![ Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = vec![ 0.0,
0.0,
0.0 ];
let bux = vec![ INF,
INF,
INF ];
let aptrb = vec![ 0, 1, 2 ];
let aptre = vec![ 1, 2, 3 ];
let asub = vec![ 0, 0, 0 ];
let aval = vec![ 1.0, 1.0, 1.0 ];
let qsubi = vec![ 0, 1, 2, 2 ];
let qsubj = vec![ 0, 1, 0, 2 ];
let qval = vec![ 2.0,0.2,-1.0,2.0 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
//r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for j in 0..NUMVAR
{
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32,c[j])?;
/* Set the bounds on variable j.
* blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, /* Index of variable.*/
bkx[j], /* Bound key.*/
blx[j], /* Numerical value of lower bound.*/
bux[j])?; /* Numerical value of upper bound.*/
/* Input column j of A */
task.put_a_col(j as i32, /* Variable (column) index.*/
&asub[aptrb[j]..aptre[j]], /* Pointer to row indexes of column j.*/
&aval[aptrb[j]..aptre[j]])?; /* Pointer to Values of column j.*/
}
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
for i in 0..NUMCON
{
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
/*
* The lower triangular part of the Q
* matrix in the objective is specified.
*/
/* Input the Q for the objective. */
task.put_q_obj(&qsubi,&qsubj,&qval)?;
}
let _trmcode = task.optimize()?;
/* Run optimizer */
/* Print a summary containing information
about the solution for debugging purposes*/
task.solution_summary(Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0, 0.0, 0.0];
task.get_xx(Soltype::ITR, /* Request the interior solution. */
& mut xx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR
{
println!("x[{}]: {}",j,xx[j]);
}
}
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.");
}
}
return Ok(());
}
More examples
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 129 130 131 132 133 134 135 136 137 138 139 140
fn main() -> Result<(),String> {
const NUMCON : i32 = 1; /* Number of constraints. */
const NUMVAR : i32 = 3; /* Number of variables. */
let c = [0.0, -1.0, 0.0];
let bkc = [Boundkey::LO];
let blc = [1.0];
let buc = [INF];
let bkx = [Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = [0.0,
0.0,
0.0 ];
let bux = [INF,
INF,
INF ];
let asub = [ &[0i32], &[0i32], &[0i32] ];
let aval = [ &[1.0], &[1.0], &[1.0] ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Give MOSEK an estimate of the size of the input data.
// This is done to increase the speed of inputting data.
// However, it is optional.
// Append 'numcon' empty constraints.
// The constraints will initially have no bounds.
task.append_cons(NUMCON)?;
// Append 'numvar' variables.
// The variables will initially be fixed at zero (x=0).
task.append_vars(NUMVAR)?;
for (j,cj,bkj,blj,buj) in izip!(0..NUMVAR,c,bkx,blx,bux) {
// Set the linear term c_j in the objective.
task.put_c_j(j, cj)?;
// Set the bounds on variable j.
// blx[j] <= x_j <= bux[j]
task.put_var_bound(j, bkj, blj, buj)?;
}
for (j,asubj,avalj) in izip!(0..NUMVAR, asub, aval) {
/* Input column j of A */
task.put_a_col(j, /* Variable (column) index.*/
asubj, /* Row index of non-zeros in column j.*/
avalj)?; /* Non-zero Values of column j. */
}
// Set the bounds on constraints.
// for i=1, ...,numcon : blc[i] <= constraint i <= buc[i]
for (i,bki,bli,bui) in izip!(0..NUMCON,bkc,blc,buc) {
task.put_con_bound(i, bki, bli, bui)?;
}
{
// The lower triangular part of the Q
// matrix in the objective is specified.
let qosubi = &[ 0, 1, 2, 2 ];
let qosubj = &[ 0, 1, 0, 2 ];
let qoval = &[ 2.0, 0.2, -1.0, 2.0 ];
// Input the Q for the objective.
task.put_q_obj(qosubi, qosubj, qoval)?;
}
// The lower triangular part of the Q^0
// matrix in the first constraint is specified.
// This corresponds to adding the term
// x0^2 - x1^2 - 0.1 x2^2 + 0.2 x0 x2
{
let qsubi = &[0, 1, 2, 2 ];
let qsubj = &[0, 1, 2, 0 ];
let qval = &[-2.0, -2.0, -0.2, 0.2];
/* put Q^0 in constraint with index 0. */
task.put_q_con_k(0,
qsubi,
qsubj,
qval)?;
}
task.put_obj_sense(Objsense::MINIMIZE)?;
/* Solve the problem */
let _trm = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
let mut xx = vec![0.0; NUMVAR as usize];
task.get_xx(Soltype::ITR, // Interior solution.
xx.as_mut_slice())?;
match solsta {
Solsta::OPTIMAL => {
println!("Optimal primal solution");
for (j,xj) in izip!(0..NUMVAR,xx) {
println!("x[{}]: {}",j,xj);
}
},
Solsta::DUAL_INFEAS_CER|
Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility.\n"),
Solsta::UNKNOWN =>
println!("Unknown solution status.\n"),
_ =>
println!("Other solution status")
}
Ok(())
}
sourcepub fn put_q_obj_i_j(
&mut self,
i_: i32,
j_: i32,
qoij_: f64
) -> Result<(), String>
pub fn put_q_obj_i_j( &mut self, i_: i32, j_: i32, qoij_: f64 ) -> Result<(), String>
Replaces one coefficient in the quadratic term in the objective.
§Arguments
i_
Row index for the coefficient to be replaced.j_
Column index for the coefficient to be replaced.qoij_
The new coefficient value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putqobjij
sourcepub fn put_skc(&mut self, whichsol_: i32, skc_: &[i32]) -> Result<(), String>
pub fn put_skc(&mut self, whichsol_: i32, skc_: &[i32]) -> Result<(), String>
Sets the status keys for the constraints.
§Arguments
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putskc
sourcepub fn put_skc_slice(
&mut self,
whichsol_: i32,
first_: i32,
last_: i32,
skc_: &[i32]
) -> Result<(), String>
pub fn put_skc_slice( &mut self, whichsol_: i32, first_: i32, last_: i32, skc_: &[i32] ) -> Result<(), String>
Sets the status keys for a slice of the constraints.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
skc_
Status keys for the constraints.See Stakey
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putskcslice
sourcepub fn put_skx(&mut self, whichsol_: i32, skx_: &[i32]) -> Result<(), String>
pub fn put_skx(&mut self, whichsol_: i32, skx_: &[i32]) -> Result<(), String>
Sets the status keys for the scalar variables.
§Arguments
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putskx
sourcepub fn put_skx_slice(
&mut self,
whichsol_: i32,
first_: i32,
last_: i32,
skx_: &[i32]
) -> Result<(), String>
pub fn put_skx_slice( &mut self, whichsol_: i32, first_: i32, last_: i32, skx_: &[i32] ) -> Result<(), String>
Sets the status keys for a slice of the variables.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
skx_
Status keys for the variables.See Stakey
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putskxslice
sourcepub fn put_slc(&mut self, whichsol_: i32, slc_: &[f64]) -> Result<(), String>
pub fn put_slc(&mut self, whichsol_: i32, slc_: &[f64]) -> Result<(), String>
Sets the slc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
slc_
Dual variables corresponding to the lower bounds on the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putslc
sourcepub fn put_slc_slice(
&mut self,
whichsol_: i32,
first_: i32,
last_: i32,
slc_: &[f64]
) -> Result<(), String>
pub fn put_slc_slice( &mut self, whichsol_: i32, first_: i32, last_: i32, slc_: &[f64] ) -> Result<(), String>
Sets a slice of the slc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
slc_
Dual variables corresponding to the lower bounds on the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putslcslice
sourcepub fn put_slx(&mut self, whichsol_: i32, slx_: &[f64]) -> Result<(), String>
pub fn put_slx(&mut self, whichsol_: i32, slx_: &[f64]) -> Result<(), String>
Sets the slx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
slx_
Dual variables corresponding to the lower bounds on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putslx
sourcepub fn put_slx_slice(
&mut self,
whichsol_: i32,
first_: i32,
last_: i32,
slx_: &[f64]
) -> Result<(), String>
pub fn put_slx_slice( &mut self, whichsol_: i32, first_: i32, last_: i32, slx_: &[f64] ) -> Result<(), String>
Sets a slice of the slx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
slx_
Dual variables corresponding to the lower bounds on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putslxslice
sourcepub fn put_snx(&mut self, whichsol_: i32, sux_: &[f64]) -> Result<(), String>
pub fn put_snx(&mut self, whichsol_: i32, sux_: &[f64]) -> Result<(), String>
Sets the snx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sux_
Dual variables corresponding to the upper bounds on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putsnx
sourcepub fn put_snx_slice(
&mut self,
whichsol_: i32,
first_: i32,
last_: i32,
snx_: &[f64]
) -> Result<(), String>
pub fn put_snx_slice( &mut self, whichsol_: i32, first_: i32, last_: i32, snx_: &[f64] ) -> Result<(), String>
Sets a slice of the snx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
snx_
Dual variables corresponding to the conic constraints on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putsnxslice
sourcepub fn put_solution(
&mut self,
whichsol_: i32,
skc_: &[i32],
skx_: &[i32],
skn_: &[i32],
xc_: &[f64],
xx_: &[f64],
y_: &[f64],
slc_: &[f64],
suc_: &[f64],
slx_: &[f64],
sux_: &[f64],
snx_: &[f64]
) -> Result<(), String>
pub fn put_solution( &mut self, whichsol_: i32, skc_: &[i32], skx_: &[i32], skn_: &[i32], xc_: &[f64], xx_: &[f64], y_: &[f64], slc_: &[f64], suc_: &[f64], slx_: &[f64], sux_: &[f64], snx_: &[f64] ) -> Result<(), String>
Inserts a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
skc_
Status keys for the constraints.See Stakey
-
skx_
Status keys for the variables.See Stakey
-
skn_
Status keys for the conic constraints.See Stakey
-
xc_
Primal constraint solution. -
xx_
Primal variable solution. -
y_
Vector of dual variables corresponding to the constraints. -
slc_
Dual variables corresponding to the lower bounds on the constraints. -
suc_
Dual variables corresponding to the upper bounds on the constraints. -
slx_
Dual variables corresponding to the lower bounds on the variables. -
sux_
Dual variables corresponding to the upper bounds on the variables. -
snx_
Dual variables corresponding to the conic constraints on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putsolution
sourcepub fn put_solution_new(
&mut self,
whichsol_: i32,
skc_: &[i32],
skx_: &[i32],
skn_: &[i32],
xc_: &[f64],
xx_: &[f64],
y_: &[f64],
slc_: &[f64],
suc_: &[f64],
slx_: &[f64],
sux_: &[f64],
snx_: &[f64],
doty_: &[f64]
) -> Result<(), String>
pub fn put_solution_new( &mut self, whichsol_: i32, skc_: &[i32], skx_: &[i32], skn_: &[i32], xc_: &[f64], xx_: &[f64], y_: &[f64], slc_: &[f64], suc_: &[f64], slx_: &[f64], sux_: &[f64], snx_: &[f64], doty_: &[f64] ) -> Result<(), String>
Inserts a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
skc_
Status keys for the constraints.See Stakey
-
skx_
Status keys for the variables.See Stakey
-
skn_
Status keys for the conic constraints.See Stakey
-
xc_
Primal constraint solution. -
xx_
Primal variable solution. -
y_
Vector of dual variables corresponding to the constraints. -
slc_
Dual variables corresponding to the lower bounds on the constraints. -
suc_
Dual variables corresponding to the upper bounds on the constraints. -
slx_
Dual variables corresponding to the lower bounds on the variables. -
sux_
Dual variables corresponding to the upper bounds on the variables. -
snx_
Dual variables corresponding to the conic constraints on the variables. -
doty_
Dual variables corresponding to affine conic constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putsolutionnew
sourcepub fn put_solution_y_i(
&mut self,
i_: i32,
whichsol_: i32,
y_: f64
) -> Result<(), String>
pub fn put_solution_y_i( &mut self, i_: i32, whichsol_: i32, y_: f64 ) -> Result<(), String>
Inputs the dual variable of a solution.
§Arguments
-
i_
Index of the dual variable. -
whichsol_
Selects a solution.See Soltype
-
y_
Solution value of the dual variable.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putsolutionyi
sourcepub fn put_str_param(
&mut self,
param_: i32,
parvalue_: &str
) -> Result<(), String>
pub fn put_str_param( &mut self, param_: i32, parvalue_: &str ) -> Result<(), String>
Sets a string parameter.
§Arguments
-
param_
Which parameter.See Sparam
-
parvalue_
Parameter value.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putstrparam
Examples found in repository?
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
fn opt_server_sync(inputfile : FileOrText, addr : String, cert : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Load some data into the task
match inputfile {
FileOrText::File(filename) => task.read_data(filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Set OptServer URL
task.put_optserver_host(addr.as_str())?;
// Path to certificate, if any
if let Some(cert) = cert {
task.put_str_param(Sparam::REMOTE_TLS_CERT_PATH, cert.as_str())?;
}
// Optimize remotely, no access token
let _trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
Ok(())
}
sourcepub fn put_suc(&mut self, whichsol_: i32, suc_: &[f64]) -> Result<(), String>
pub fn put_suc(&mut self, whichsol_: i32, suc_: &[f64]) -> Result<(), String>
Sets the suc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
suc_
Dual variables corresponding to the upper bounds on the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putsuc
sourcepub fn put_suc_slice(
&mut self,
whichsol_: i32,
first_: i32,
last_: i32,
suc_: &[f64]
) -> Result<(), String>
pub fn put_suc_slice( &mut self, whichsol_: i32, first_: i32, last_: i32, suc_: &[f64] ) -> Result<(), String>
Sets a slice of the suc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
suc_
Dual variables corresponding to the upper bounds on the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putsucslice
sourcepub fn put_sux(&mut self, whichsol_: i32, sux_: &[f64]) -> Result<(), String>
pub fn put_sux(&mut self, whichsol_: i32, sux_: &[f64]) -> Result<(), String>
Sets the sux vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
sux_
Dual variables corresponding to the upper bounds on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putsux
sourcepub fn put_sux_slice(
&mut self,
whichsol_: i32,
first_: i32,
last_: i32,
sux_: &[f64]
) -> Result<(), String>
pub fn put_sux_slice( &mut self, whichsol_: i32, first_: i32, last_: i32, sux_: &[f64] ) -> Result<(), String>
Sets a slice of the sux vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
sux_
Dual variables corresponding to the upper bounds on the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putsuxslice
sourcepub fn put_task_name(&mut self, taskname_: &str) -> Result<(), String>
pub fn put_task_name(&mut self, taskname_: &str) -> Result<(), String>
Assigns a new name to the task.
§Arguments
taskname_
Name assigned to the task.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.puttaskname
sourcepub fn put_var_bound(
&mut self,
j_: i32,
bkx_: i32,
blx_: f64,
bux_: f64
) -> Result<(), String>
pub fn put_var_bound( &mut self, j_: i32, bkx_: i32, blx_: f64, bux_: f64 ) -> Result<(), String>
Changes the bounds for one variable.
§Arguments
-
j_
Index of the variable. -
bkx_
New bound key.See Boundkey
-
blx_
New lower bound. -
bux_
New upper bound.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putvarbound
Examples found in repository?
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
More examples
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
fn main() -> Result<(),String> {
let numcon : i32 = 3;
let numvar : i32 = 4;
let c = [3.0, 1.0, 5.0, 1.0];
let asub = [0, 1, 2,
0, 1, 2, 3,
1, 3];
let aval = [3.0, 1.0, 2.0,
2.0, 1.0, 3.0, 1.0,
2.0, 3.0];
let aptr = [0,3,7,9];
let bkc = [Boundkey::FX,
Boundkey::LO,
Boundkey::UP];
let blc = [30.0,
15.0,
-INF];
let buc = [30.0,
INF,
25.0];
let bkx = [Boundkey::LO,
Boundkey::RA,
Boundkey::LO,
Boundkey::LO];
let blx = [0.0,
0.0,
0.0,
0.0];
let bux = [INF,
10.0,
INF,
INF];
// Create a task object linked with the environment env.
let mut task = Task::new().unwrap().with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Give MOSEK an estimate of the size of the input data.
This is done to increase the speed of inputting data.
However, it is optional. */
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for (j,(&cj,&bkj,&blj,&buj)) in izip!(c.iter(),bkx.iter(),blx.iter(),bux.iter()).enumerate() {
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32, cj)?;
/* Set the bounds on variable j.
blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, bkj, blj, buj)?;
};
/* Set the bounds on constraints.
for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for (i,(&bki,&bli,&bui,&ptrb,&ptre)) in izip!(bkc.iter(),blc.iter(),buc.iter(),aptr[..aptr.len()-1].iter(),aptr[1..].iter()).enumerate() {
task.put_con_bound(i as i32, bki, bli, bui)?;
/* Input row i of A */
task.put_a_row(i as i32, /* Row index.*/
&asub[ptrb..ptre], /* Column indexes of non-zeros in row i.*/
&aval[ptrb..ptre])?; /* Non-zero Values of row i. */
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS, // Basic solution.
xx.as_mut_slice());
match solsta {
Solsta::OPTIMAL =>
println!("Optimal primal solution = {:?}",xx),
Solsta::DUAL_INFEAS_CER|Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility."),
Solsta::UNKNOWN =>
println!("Unknown solution status."),
_ =>
println!("Other solution status")
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137
fn main() -> Result<(),String> {
let c = vec![ 0.0,-1.0,0.0 ];
let bkc = vec![ mosek::Boundkey::LO ];
let blc = vec![ 1.0 ];
let buc = vec![ INF ];
let bkx = vec![ Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = vec![ 0.0,
0.0,
0.0 ];
let bux = vec![ INF,
INF,
INF ];
let aptrb = vec![ 0, 1, 2 ];
let aptre = vec![ 1, 2, 3 ];
let asub = vec![ 0, 0, 0 ];
let aval = vec![ 1.0, 1.0, 1.0 ];
let qsubi = vec![ 0, 1, 2, 2 ];
let qsubj = vec![ 0, 1, 0, 2 ];
let qval = vec![ 2.0,0.2,-1.0,2.0 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
//r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
task.append_cons(NUMCON as i32)?;
/* Append 'NUMVAR' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(NUMVAR as i32)?;
/* Optionally add a constant term to the objective. */
task.put_cfix(0.0)?;
for j in 0..NUMVAR
{
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32,c[j])?;
/* Set the bounds on variable j.
* blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, /* Index of variable.*/
bkx[j], /* Bound key.*/
blx[j], /* Numerical value of lower bound.*/
bux[j])?; /* Numerical value of upper bound.*/
/* Input column j of A */
task.put_a_col(j as i32, /* Variable (column) index.*/
&asub[aptrb[j]..aptre[j]], /* Pointer to row indexes of column j.*/
&aval[aptrb[j]..aptre[j]])?; /* Pointer to Values of column j.*/
}
/* Set the bounds on constraints.
* for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
for i in 0..NUMCON
{
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
/*
* The lower triangular part of the Q
* matrix in the objective is specified.
*/
/* Input the Q for the objective. */
task.put_q_obj(&qsubi,&qsubj,&qval)?;
}
let _trmcode = task.optimize()?;
/* Run optimizer */
/* Print a summary containing information
about the solution for debugging purposes*/
task.solution_summary(Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0, 0.0, 0.0];
task.get_xx(Soltype::ITR, /* Request the interior solution. */
& mut xx[..])?;
println!("Optimal primal solution");
for j in 0..NUMVAR
{
println!("x[{}]: {}",j,xx[j]);
}
}
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.");
}
}
return Ok(());
}
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 129 130 131 132 133 134 135 136 137 138 139 140
fn main() -> Result<(),String> {
const NUMCON : i32 = 1; /* Number of constraints. */
const NUMVAR : i32 = 3; /* Number of variables. */
let c = [0.0, -1.0, 0.0];
let bkc = [Boundkey::LO];
let blc = [1.0];
let buc = [INF];
let bkx = [Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = [0.0,
0.0,
0.0 ];
let bux = [INF,
INF,
INF ];
let asub = [ &[0i32], &[0i32], &[0i32] ];
let aval = [ &[1.0], &[1.0], &[1.0] ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Give MOSEK an estimate of the size of the input data.
// This is done to increase the speed of inputting data.
// However, it is optional.
// Append 'numcon' empty constraints.
// The constraints will initially have no bounds.
task.append_cons(NUMCON)?;
// Append 'numvar' variables.
// The variables will initially be fixed at zero (x=0).
task.append_vars(NUMVAR)?;
for (j,cj,bkj,blj,buj) in izip!(0..NUMVAR,c,bkx,blx,bux) {
// Set the linear term c_j in the objective.
task.put_c_j(j, cj)?;
// Set the bounds on variable j.
// blx[j] <= x_j <= bux[j]
task.put_var_bound(j, bkj, blj, buj)?;
}
for (j,asubj,avalj) in izip!(0..NUMVAR, asub, aval) {
/* Input column j of A */
task.put_a_col(j, /* Variable (column) index.*/
asubj, /* Row index of non-zeros in column j.*/
avalj)?; /* Non-zero Values of column j. */
}
// Set the bounds on constraints.
// for i=1, ...,numcon : blc[i] <= constraint i <= buc[i]
for (i,bki,bli,bui) in izip!(0..NUMCON,bkc,blc,buc) {
task.put_con_bound(i, bki, bli, bui)?;
}
{
// The lower triangular part of the Q
// matrix in the objective is specified.
let qosubi = &[ 0, 1, 2, 2 ];
let qosubj = &[ 0, 1, 0, 2 ];
let qoval = &[ 2.0, 0.2, -1.0, 2.0 ];
// Input the Q for the objective.
task.put_q_obj(qosubi, qosubj, qoval)?;
}
// The lower triangular part of the Q^0
// matrix in the first constraint is specified.
// This corresponds to adding the term
// x0^2 - x1^2 - 0.1 x2^2 + 0.2 x0 x2
{
let qsubi = &[0, 1, 2, 2 ];
let qsubj = &[0, 1, 2, 0 ];
let qval = &[-2.0, -2.0, -0.2, 0.2];
/* put Q^0 in constraint with index 0. */
task.put_q_con_k(0,
qsubi,
qsubj,
qval)?;
}
task.put_obj_sense(Objsense::MINIMIZE)?;
/* Solve the problem */
let _trm = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
let mut xx = vec![0.0; NUMVAR as usize];
task.get_xx(Soltype::ITR, // Interior solution.
xx.as_mut_slice())?;
match solsta {
Solsta::OPTIMAL => {
println!("Optimal primal solution");
for (j,xj) in izip!(0..NUMVAR,xx) {
println!("x[{}]: {}",j,xj);
}
},
Solsta::DUAL_INFEAS_CER|
Solsta::PRIM_INFEAS_CER =>
println!("Primal or dual infeasibility.\n"),
Solsta::UNKNOWN =>
println!("Unknown solution status.\n"),
_ =>
println!("Other solution status")
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
fn main() -> Result<(),String> {
let numvar = 4;
let numcon = 3;
let c = vec![3.0, 1.0, 5.0, 1.0];
/* Below is the sparse representation of the A
* matrix stored by column. */
let aptrb = vec![ 0, 2, 5, 7 ];
let aptre = vec![ 2, 5, 7, 9 ];
let asub = vec![ 0, 1,
0, 1, 2,
0, 1,
1, 2 ];
let aval = vec![ 3.0, 2.0,
1.0, 1.0, 2.0,
2.0, 3.0,
1.0, 3.0 ];
/* Bounds on constraints. */
let bkc = vec![ Boundkey::FX, Boundkey::LO, Boundkey::UP ];
let blc = vec![ 30.0, 15.0, -INF ];
let buc = vec![ 30.0, INF, 25.0 ];
/* Bounds on variables. */
let bkx = vec![ Boundkey::LO, Boundkey::RA, Boundkey::LO, Boundkey::LO ];
let blx = vec![ 0.0, 0.0, 0.0, 0.0 ];
let bux = vec![ INF, 10.0, INF, INF ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
/* Directs the log task stream to the 'printstr' function. */
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(numcon as i32)?;
/* Append 'numvar' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar as i32)?;
for j in 0..numvar
{
/* Set the linear term c_j in the objective.*/
task.put_c_j(j as i32,c[j])?;
/* Set the bounds on variable j.
* blx[j] <= x_j <= bux[j] */
task.put_var_bound(j as i32, /* Index of variable.*/
bkx[j], /* Bound key.*/
blx[j], /* Numerical value of lower bound.*/
bux[j])?; /* Numerical value of upper bound.*/
/* Input column j of A */
task.put_a_col(j as i32, /* Variable (column) index.*/
& asub[aptrb[j]..aptre[j]], /* Pointer to row indexes of column j.*/
& aval[aptrb[j]..aptre[j]])?; /* Pointer to Values of column j.*/
}
/* Set the bounds on constraints.
* for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for i in 0..numcon {
task.put_con_bound(i as i32, /* Index of constraint.*/
bkc[i], /* Bound key.*/
blc[i], /* Numerical value of lower bound.*/
buc[i])?; /* Numerical value of upper bound.*/
}
/* Maximize objective function. */
task.put_obj_sense(Objsense::MAXIMIZE)?;
/* Run optimizer */
let _trmcode = task.optimize()?;
/* Print a summary containing information
* about the solution for debugging purposes. */
task.solution_summary(Streamtype::LOG)?;
let solsta = task.get_sol_sta(Soltype::BAS)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0,0.0,0.0,0.0];
task.get_xx(Soltype::BAS, /* Request the basic solution. */
& mut xx[..])?;
println!("Optimal primal solution");
for j in 0..numvar as usize
{
println!("x[{}]: {}",j,xx[j]);
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN =>
{
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",solsta);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
fn main() -> Result<(),String>
{
let numvar : i32 = 6;
let numcon : i32 = 1;
let bkc = &[ mosek::Boundkey::FX ];
let blc = &[ 1.0 ];
let buc = &[ 1.0 ];
let bkx = &[ mosek::Boundkey::LO,
mosek::Boundkey::LO,
mosek::Boundkey::LO,
mosek::Boundkey::FR,
mosek::Boundkey::FR,
mosek::Boundkey::FR];
let blx = &[ 0.0, 0.0, 0.0, -INF, -INF, -INF ];
let bux = &[ INF, INF, INF, INF, INF, INF ];
let c = &[ 0.0, 0.0, 0.0, 1.0, 1.0, 1.0 ];
let asub = &[0, 1, 2];
let aval = &[1.0, 1.0, 1.0];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
* The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
* The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
for (j,&cj,&bkj,&blj,&buj) in izip!(0..numvar,c,bkx,blx,bux) {
/* Set the linear term c_j in the objective.*/
task.put_c_j(j,cj)?;
/* Set the bounds on variable j.
* blx[j] <= x_j <= bux[j] */
task.put_var_bound( j, /* Index of variable.*/
bkj, /* Bound key.*/
blj, /* Numerical value of lower bound.*/
buj)?; /* Numerical value of upper bound.*/
}
/* Input columns of A */
task.put_a_row(0, asub, aval)?;
/* Set the bounds on constraints.
* for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
for (i,&bki,&bli,&bui) in izip!(0..numcon,bkc,blc,buc) {
task.put_con_bound( i, /* Index of constraint.*/
bki, /* Bound key.*/
bli, /* Numerical value of lower bound.*/
bui)?; /* Numerical value of upper bound.*/
}
/* Append the first cone. */
// Create a matrix F such that F * x = [x(3),x(0),x(1),x(4),x(5),x(2)]
{
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0,1,2,3,4,5], // Rows
&[3, 0, 1, 4, 5, 2], // Columns
&[1.0,1.0,1.0,1.0,1.0,1.0])?;
// Quadratic cone (x(3),x(0),x(1)) \in QUAD_3
let qconedom = task.append_quadratic_cone_domain(3)?;
task.append_acc(qconedom, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
// Rotated quadratic cone (x(4),x(5),x(2)) \in RQUAD_3
let rqconedom = task.append_r_quadratic_cone_domain(3)?;
task.append_acc(rqconedom, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
}
/* Run optimizer */
let trm = task.optimize()?;
task.write_data("cqo1.ptf")?;
/* Print a summary containing information
* about the solution for debugging purposes*/
task.solution_summary (Streamtype::MSG)?;
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta
{
Solsta::OPTIMAL =>
{
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR, /* Request the basic solution. */
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,xj) in izip!(0..numvar,xx) {
println!("x[{}]: {}",j,xj);
}
}
Solsta::DUAL_INFEAS_CER |
Solsta::PRIM_INFEAS_CER =>
{
println!("Primal or dual infeasibility certificate found.");
}
Solsta::UNKNOWN => {
/* If the solutions status is unknown, print the termination code
* indicating why the optimizer terminated prematurely. */
println!("The solution status is unknown.");
println!("The optimizer terminitated with code: {}",trm);
}
_ =>
{
println!("Other solution status.");
}
}
Ok(())
}
sourcepub fn put_var_bound_list(
&mut self,
sub_: &[i32],
bkx_: &[i32],
blx_: &[f64],
bux_: &[f64]
) -> Result<(), String>
pub fn put_var_bound_list( &mut self, sub_: &[i32], bkx_: &[i32], blx_: &[f64], bux_: &[f64] ) -> Result<(), String>
Changes the bounds of a list of variables.
§Arguments
-
sub_
List of variable indexes. -
bkx_
Bound keys for the variables.See Boundkey
-
blx_
Lower bounds for the variables. -
bux_
Upper bounds for the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putvarboundlist
sourcepub fn put_var_bound_list_const(
&mut self,
sub_: &[i32],
bkx_: i32,
blx_: f64,
bux_: f64
) -> Result<(), String>
pub fn put_var_bound_list_const( &mut self, sub_: &[i32], bkx_: i32, blx_: f64, bux_: f64 ) -> Result<(), String>
Changes the bounds of a list of variables.
§Arguments
-
sub_
List of variable indexes. -
bkx_
New bound key for all variables in the list.See Boundkey
-
blx_
New lower bound for all variables in the list. -
bux_
New upper bound for all variables in the list.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putvarboundlistconst
sourcepub fn put_var_bound_slice(
&mut self,
first_: i32,
last_: i32,
bkx_: &[i32],
blx_: &[f64],
bux_: &[f64]
) -> Result<(), String>
pub fn put_var_bound_slice( &mut self, first_: i32, last_: i32, bkx_: &[i32], blx_: &[f64], bux_: &[f64] ) -> Result<(), String>
Changes the bounds for a slice of the variables.
§Arguments
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
bkx_
Bound keys for the variables.See Boundkey
-
blx_
Lower bounds for the variables. -
bux_
Upper bounds for the variables.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putvarboundslice
sourcepub fn put_var_bound_slice_const(
&mut self,
first_: i32,
last_: i32,
bkx_: i32,
blx_: f64,
bux_: f64
) -> Result<(), String>
pub fn put_var_bound_slice_const( &mut self, first_: i32, last_: i32, bkx_: i32, blx_: f64, bux_: f64 ) -> Result<(), String>
Changes the bounds for a slice of the variables.
§Arguments
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
bkx_
New bound key for all variables in the slice.See Boundkey
-
blx_
New lower bound for all variables in the slice. -
bux_
New upper bound for all variables in the slice.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putvarboundsliceconst
Examples found in repository?
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
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
fn max_volume_box(Aw : f64,
Af : f64,
alpha : f64,
beta : f64,
gamma : f64,
delta : f64) -> Result<Vec<f64>,String>
{
let numvar = 3i32; // Variables in original problem
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method task_msg_obj.stream
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Add variables and constraints
task.append_vars(numvar)?;
let x = 0i32;
let y = 1i32;
let z = 2i32;
// Objective is the sum of three first variables
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0, numvar, &[1.0,1.0,1.0])?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
task.append_cons(3)?;
// s0+s1 < 1 <=> log(s0+s1) < 0
task.put_aij_list(&[0,0,1,1,2,2],
&[y, z, x, y, z, y],
&[1.0, 1.0, 1.0, -1.0, 1.0, -1.0])?;
task.put_con_bound(0,Boundkey::UP,-INF,Af.ln())?;
task.put_con_bound(1,Boundkey::RA,alpha.ln(),beta.ln())?;
task.put_con_bound(2,Boundkey::RA,gamma.ln(),delta.ln())?;
{
let afei = task.get_num_afe()?;
let u1 = task.get_num_var()?;
let u2 = u1+1;
let afeidx = &[0, 1, 2, 2, 3, 3, 5, 5];
let varidx = &[u1, u2, x, y, x, z, u1, u2];
let fval = &[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let gfull = &[0.0, 0.0, (2.0/Aw).ln(), (2.0/Aw).ln(), 1.0, -1.0];
task.append_vars(2)?;
task.append_afes(6)?;
task.put_var_bound_slice_const(u1, u1+2, Boundkey::FR, -INF, INF)?;
// Affine expressions appearing in affine conic constraints
// in this order:
// u1, u2, x+y+log(2/Awall), x+z+log(2/Awall), 1.0, u1+u2-1.0
task.put_afe_f_entry_list(afeidx, varidx, fval)?;
task.put_afe_g_slice(afei, afei+6, gfull)?;
{
let dom = task.append_primal_exp_cone_domain()?;
// (u1, 1, x+y+log(2/Awall)) \in EXP
task.append_acc(dom, &[0, 4, 2], &[0.0,0.0,0.0])?;
// (u2, 1, x+z+log(2/Awall)) \in EXP
task.append_acc(dom, &[1, 4, 3], &[0.0,0.0,0.0])?;
}
{
let dom = task.append_rzero_domain(1)?;
// The constraint u1+u2-1 \in \ZERO is added also as an ACC
task.append_acc(dom, &[5], &[0.0])?;
}
}
let _trm = task.optimize()?;
task.write_data("gp1.ptf")?;
let mut xyz = vec![0.0; 3];
task.get_xx_slice(Soltype::ITR, 0i32, numvar, xyz.as_mut_slice())?;
// task.write_data("gp1.ptf")?;
Ok(xyz.iter().map(|v| v.exp()).collect())
}
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
fn main() -> Result<(),String> {
// Create a task object
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Append free variables
let numvar : i32 = 4;
task.append_vars(numvar)?;
let x : Vec<i32> = (0..numvar).collect();
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
// The linear part: the linear constraint
task.append_cons(1)?;
task.put_a_row(0, x.as_slice(), vec![1.0; numvar as usize].as_slice())?;
task.put_con_bound(0, Boundkey::LO, -10.0, -10.0)?;
// The linear part: objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_list(x.as_slice(), &[2.0, 1.0, 3.0, 1.0])?;
// Fill in the affine expression storage F, g
let numafe : i64 = 10;
task.append_afes(numafe)?;
let fafeidx : &[i64] = &[0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let fvaridx : &[i32] = &[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3];
let fval = &[1.0, -2.0, 1.0, -3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
let g = &[1.0, 2.0, 0.0, 0.0, 0.0, 0.0, -2.5, -2.5, -2.5, -2.5];
task.put_afe_f_entry_list(fafeidx, fvaridx, fval)?;
task.put_afe_g_slice(0, numafe, g)?;
// Create domains
let zero1 = task.append_rzero_domain(1)?;
let zero2 = task.append_rzero_domain(2)?;
let rminus1 = task.append_rminus_domain(1)?;
// Append disjunctive constraints
let numdjc : i64 = 2;
task.append_djcs(numdjc)?;
// First disjunctive constraint
task.put_djc(0, // DJC index
&[rminus1, zero2, rminus1, zero2], // Domains (domidxlist)
&[0, 4, 5, 1, 2, 3], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0,0.0,0.0], // Unused
&[2, 2])?; // Term sizes (termsizelist)
// Second disjunctive constraint
task.put_djc(1, // DJC index
&[zero1, zero1, zero1, zero1], // Domains (domidxlist)
&[6, 7, 8, 9], // AFE indices (afeidxlist)
&[0.0,0.0,0.0,0.0], // Unused
&[1, 1, 1, 1])?; // Term sizes (termidxlist)
// Useful for debugging
task.write_data("djc1.ptf")?; // Write file in human-readable format
// Solve the problem
let _ = task.optimize()?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::MSG)?;
// Get status information about the solution
let sta = task.get_sol_sta(Soltype::ITG)?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITG,xx.as_mut_slice())?;
println!("Optimal solution: ");
for (i,&xi) in xx.iter().enumerate() {
println!("x[{}]={}",i,xi);
}
Ok(())
}
sourcepub fn put_var_name(&mut self, j_: i32, name_: &str) -> Result<(), String>
pub fn put_var_name(&mut self, j_: i32, name_: &str) -> Result<(), String>
Sets the name of a variable.
§Arguments
j_
Index of the variable.name_
The variable name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putvarname
Examples found in repository?
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
fn portfolio(n : i32, // number of assets
gamma : f64, // risk bound: maximum stddev
mu : &[f64], // vector of expected returns
GT : &[f64], // covariance matrix factor
x0 : &[f64], // initial investment
w : f64) // initial wealth
-> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Total budget */
let total_budget = w + x0.iter().sum::<f64>();
/* Constraints. */
task.append_cons(1i32)?;
/* Variables. */
task.append_vars(n)?;
let x : Vec<i32> = (0i32..n).collect();
/* Total budget constraint - set bounds l^c = u^c */
task.put_con_bound(0i32, mosek::Boundkey::FX, total_budget, total_budget)?;
task.put_con_name(0i32,"budget")?;
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_slice(0,n,mu)?;
/* x variables. */
for (j,xj) in x.iter().enumerate() {
/* Coefficients in the first row of A */
task.put_aij(0, *xj, 1.0)?;
/* No short-selling - x^l = 0, x^u = inf */
task.put_var_bound(*xj, mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*xj, format!("x[{}]",j+1).as_str())?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
/* Dump the problem to a human readable OPF file. */
// task.write_data("portfolio_1_basic.ptf")?;
let _trm = task.optimize()?;
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR)? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
task.write_data("portfolio_1_basic.ptf")?;
/* Read the x variables one by one and compute expected return. */
/* Can also be obtained as value of the objective. */
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let expret = task.get_primal_obj(Soltype::ITR)?;
Ok((level.to_vec(),expret))
}
More examples
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
fn portfolio(w : f64,
mu : &[f64],
x0 : &[f64],
gammas : &[f64],
theta : &[f64],
GT : &Matrix) -> Result<Vec<(f64,f64)>,String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
let (kx,nx) = GT.size();
if mu.len() != nx { panic!("Mismatching data"); }
let k : i32 = kx.try_into().unwrap();
let n : i32 = nx.try_into().unwrap();
let total_budget : f64 = w + x0.iter().sum::<f64>();
//Offset of variables into the API variable.
let numvar = n;
let voff_x : i32 = 0;
// Constraint offset
let coff_bud : i32 = 0;
// Holding variable x of length n
// No other auxiliary variables are needed in this formulation
task.append_vars(numvar)?;
// Setting up variable x
for j in 0..n {
task.put_var_name(voff_x+j,format!("x[{}]",j+1).as_str())?;
}
task.put_var_bound_slice_const(voff_x,voff_x+n, Boundkey::LO,0.0, INF)?;
// One linear constraint: total budget
task.append_cons(1)?;
task.put_con_name(coff_bud, "budget")?;
/* Coefficients in the first row of A */
for j in 0..n {
task.put_aij(coff_bud,voff_x + j, 1.0)?;
}
task.put_con_bound(coff_bud, Boundkey::FX, total_budget, total_budget)?;
// Input (gamma, G_factor_T x, diag(sqrt(theta))*x) in the AFE (affine expression) storage
// We need k+n+1 rows and we fill them in in three parts
task.append_afes((k+n) as i64 + 1)?;
// 1. The first affine expression = gamma, will be specified later
// 2. The next k expressions comprise G_factor_T*x, we add them row by row
// transposing the matrix G_factor on the fly
task.put_afe_f_row_list((1..1+k as i64).collect::<Vec<i64>>().as_slice(), // f row idxs
vec![n; k as usize].as_slice(), // row lengths
(0..GT.len() as i64).step_by(n as usize).collect::<Vec<i64>>().as_slice(), // row ptr
iproduct!(0..k,0..n).map(|(_,b)| b).collect::<Vec<i32>>().as_slice(), // varidx, 0..n repeated k times
GT.data_by_row().as_slice())?;
// 3. The remaining n rows contain sqrt(theta) on the diagonal
for (i,thetai) in (0..n).zip(theta.iter()) {
task.put_afe_f_entry(i as i64 + 1 + k as i64, voff_x + i, thetai.sqrt())?;
}
// Input the affine conic constraint (gamma, GT*x) \in QCone
// Add the quadratic domain of dimension k+1
let qdom = task.append_quadratic_cone_domain(k as i64+ 1)?;
// Add the constraint
task.append_acc_seq(qdom, 0, vec![0.0; k as usize+1].as_slice())?;
task.put_acc_name(0, "risk")?;
// Objective: maximize expected return mu^T x
for (j,&muj) in (0..n).zip(mu.iter()) {
task.put_c_j(voff_x + j, muj)?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
Ok(gammas.iter().filter_map(|&gamma| {
// Specify gamma in ACC
task.put_afe_g(0, gamma).ok()?;
task.optimize().ok()?;
/* Display solution summary for quick inspection of results */
let _ = task.solution_summary(Streamtype::LOG);
let _ = task.write_data(format!("portfolio_6_factor-{}.ptf",gamma).as_str());
// Check if the interior point solution is an optimal point
if task.get_sol_sta(Soltype::ITR).ok()? != Solsta::OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
/* Read the results */
let mut xx = vec![0.0; n as usize];
task.get_xx_slice(Soltype::ITR, voff_x, voff_x + n, xx.as_mut_slice()).ok()?;
Some((gamma,xx.iter().zip(mu.iter()).map(|(&xj,&muj)| xj*muj).sum::<f64>()))
}).collect::<Vec<(f64,f64)>>())
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn softplus(task : & mut TaskCB, d : i32, n : i32, theta : i32, t : i32, X : &[f64], Y : &[bool]) -> Result<(),String> {
let nvar = task.get_num_var()?;
let ncon = task.get_num_con()?;
let nafe = task.get_num_afe()?;
task.append_vars(2*n)?; // z1, z2
task.append_cons(n)?; // z1 + z2 = 1
task.append_afes(4*n as i64)?; //theta * X[i] - t[i], -t[i], z1[i], z2[i]
let z1 = nvar;
let z2 = nvar+n;
let zcon = ncon;
let thetaafe = nafe;
let tafe = nafe+n as i64;
let z1afe = tafe+n as i64;
let z2afe = z1afe+n as i64;
// Linear constraints
{
let mut subi = vec![0i32; 2*n as usize];
let mut subj = vec![0i32; 2*n as usize];
let mut aval = vec![0.0; 2*n as usize];
for i in 0..n {
task.put_var_name(z1+i,format!("z1[{}]",i).as_str())?;
task.put_var_name(z2+i,format!("z2[{}]",i).as_str())?;
}
for ((i,&zx),si, sj, av) in izip!(iproduct!(0..n,&[z1,z2]),
subi.iter_mut(),
subj.iter_mut(),
aval.iter_mut()) {
*si = zcon+i;
*sj = zx+i as i32;
*av = 1.0;
}
task.put_aij_list(subi.as_slice(), subj.as_slice(), aval.as_slice())?;
task.put_con_bound_slice_const(zcon, zcon+n, Boundkey::FX, 1.0, 1.0)?;
task.put_var_bound_slice_const(nvar, nvar+2*n, Boundkey::FR, -INF, INF)?;
}
// Affine conic expressions
let mut afeidx = vec![0i64; (d*n+4*n) as usize];
let mut varidx = vec![0i32; (d*n+4*n) as usize];
let mut fval = vec![0.0; (d*n+4*n) as usize];
// Thetas
let mut k : usize = 0;
for ((i,j),afei,vari) in izip!(iproduct!(0..n,0..d),
& mut afeidx[k..k+(n*d) as usize],
& mut varidx[k..k+(n*d) as usize]) {
*afei = thetaafe + i as i64;
*vari = theta + j;
}
for ((&yi,_j),&xij,fv) in izip!(iproduct!(Y,0..d), X, & mut fval[k..k+(n*d) as usize]) {
*fv = (if yi {-1.0} else {1.0}) * xij;
}
k += (n*d) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = -1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = thetaafe+i as i64; *vari = t+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = tafe+i as i64; *vari = t+i;
}
k += (n*2) as usize;
for fv in fval[k..k+(2*n) as usize].iter_mut() { *fv = 1.0; }
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z1afe+i as i64; *vari = z1+i;
}
for (i,afei,vari) in izip!(0..n,
&mut afeidx[k+1..k+(2*n) as usize].iter_mut().step_by(2),
&mut varidx[k+1..k+(2*n) as usize].iter_mut().step_by(2)) {
*afei = z2afe+i as i64; *vari = z2+i;
}
// Add the expressions
task.put_afe_f_entry_list(afeidx.as_slice(), varidx.as_slice(), fval.as_slice())?;
{
// Add a single row with the constant expression "1.0"
let oneafe = task.get_num_afe()?;
task.append_afes(1)?;
task.put_afe_g(oneafe, 1.0)?;
// Add an exponential cone domain
let dom = task.append_primal_exp_cone_domain()?;
// Conic constraints
let zeros = &[0.0,0.0,0.0];
let mut acci = task.get_num_acc()?;
for i in 0..n as i64 {
task.append_acc(dom, &[z1afe+i, oneafe, thetaafe+i], zeros)?;
task.append_acc(dom, &[z2afe+i, oneafe, tafe+i], zeros)?;
task.put_acc_name(acci,format!("z1:theta[{}]",i).as_str())?;
task.put_acc_name(acci+1,format!("z2:t[{}]",i).as_str())?;
acci += 2;
}
}
Ok(())
}
// Model logistic regression (regularized with full 2-norm of theta)
// X - n x d matrix of data points
// y - length n vector classifying training points
// lamb - regularization parameter
#[allow(non_snake_case)]
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn put_var_solution_j(
&mut self,
j_: i32,
whichsol_: i32,
sk_: i32,
x_: f64,
sl_: f64,
su_: f64,
sn_: f64
) -> Result<(), String>
pub fn put_var_solution_j( &mut self, j_: i32, whichsol_: i32, sk_: i32, x_: f64, sl_: f64, su_: f64, sn_: f64 ) -> Result<(), String>
Sets the primal and dual solution information for a single variable.
§Arguments
-
j_
Index of the variable. -
whichsol_
Selects a solution.See Soltype
-
sk_
Status key of the variable.See Stakey
-
x_
Primal solution value of the variable. -
sl_
Solution value of the dual variable associated with the lower bound. -
su_
Solution value of the dual variable associated with the upper bound. -
sn_
Solution value of the dual variable associated with the conic constraint.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putvarsolutionj
sourcepub fn put_var_type(&mut self, j_: i32, vartype_: i32) -> Result<(), String>
pub fn put_var_type(&mut self, j_: i32, vartype_: i32) -> Result<(), String>
Sets the variable type of one variable.
§Arguments
-
j_
Index of the variable. -
vartype_
The new variable type.See Variabletype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putvartype
Examples found in repository?
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
fn portfolio(n : i32,
mu : &[f64],
f : &[f64],
g : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let k = (GT.len() / n as usize) as i32;
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Compute total wealth */
let w0 = w + x0.iter().sum::<f64>();
task.append_cons(1i32)?;
task.append_vars(3*n)?;
for i in 0i32..n {
task.put_var_name(i, format!("x[{}]",i+1).as_str())?;
task.put_var_name(i+n, format!("y[{}]",i+1).as_str())?;
task.put_var_name(i+2*n,format!("z[{}]",i+1).as_str())?;
task.put_var_type(i+n, Variabletype::TYPE_INT)?;
}
let all_vars : Vec<i32> = (0i32..3*n).collect();
let x = &all_vars[0..n as usize];
let y = &all_vars[n as usize..2*n as usize];
let z = &all_vars[2*n as usize..3*n as usize];
task.put_var_bound_slice_const(0i32,n, mosek::Boundkey::LO, 0.0,0.0)?;
task.put_var_bound_slice_const(n,2*n, mosek::Boundkey::RA, 0.0,1.0)?;
task.put_var_bound_slice_const(2*n,3*n, mosek::Boundkey::FR, 0.0,0.0)?;
/* Constraints. */
task.put_con_name(0,"budget")?;
{
let zeros = vec![0i32; n as usize];
let fones = vec![1.0; n as usize];
task.put_aij_list(zeros.as_slice(), x, fones.as_slice())?;
task.put_aij_list(zeros.as_slice(), y, f)?;
task.put_aij_list(zeros.as_slice(), z, g)?;
task.put_con_bound(0i32,mosek::Boundkey::FX,w0,w0)?;
}
// objective
task.put_obj_sense(Objsense::MAXIMIZE)?;
for (xi,mui) in x.iter().zip(mu.iter()) {
task.put_c_j(*xi, *mui)?;
}
// risk bound
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// Switch
{
let coni = task.get_num_con()?;
task.append_cons(n)?;
for i in 0..n {
task.put_con_name(coni + i, format!("switch[{}]",i+1).as_str())?;
}
let conlist : Vec<i32> = (coni..coni+n).collect();
task.put_aij_list(conlist.as_slice(), z, vec![1.0; n as usize].as_slice())?;
task.put_aij_list(conlist.as_slice(), y, vec![-w0; n as usize].as_slice())?;
task.put_con_bound_slice_const(coni,coni+n, Boundkey::UP, 0.0,0.0)?;
}
let _ = task.optimize()?;
task.write_data("portfolio_4_transcost.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
// Check if the integer solution is an optimal point
if task.get_sol_sta(Soltype::ITG)? != Solsta::INTEGER_OPTIMAL {
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
eprintln!("Solution not optimal!");
std::process::exit(1);
}
let mut xx = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITG, 0,n, xx.as_mut_slice())?;
let expret = xx[0..n as usize].iter().zip(mu.iter()).map(|(a,b)| a*b).sum::<f64>();
Ok((xx,expret))
}
sourcepub fn put_var_type_list(
&mut self,
subj_: &[i32],
vartype_: &[i32]
) -> Result<(), String>
pub fn put_var_type_list( &mut self, subj_: &[i32], vartype_: &[i32] ) -> Result<(), String>
Sets the variable type for one or more variables.
§Arguments
-
subj_
A list of variable indexes for which the variable type should be changed. -
vartype_
A list of variable types.See Variabletype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putvartypelist
Examples found in repository?
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
let numvar : i32 = 4;
let numcon : i32 = 1;
let c = &[ 7.0, 10.0, 1.0, 5.0 ];
let bkc = &[Boundkey::UP];
let blc = &[ -INF ];
let buc = &[2.5];
let bkx = &[Boundkey::LO,
Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = &[0.0,
0.0,
0.0,
0.0 ];
let bux = &[INF,
INF,
INF,
INF];
let ptrb = &[0i64, 1, 2, 3];
let ptre = &[1i64, 2, 3, 4];
let aval = &[1.0, 1.0, 1.0, 1.0];
let asub = &[0i32, 0, 0, 0 ];
let intsub = &[0i32, 1, 2];
let inttype = &[Variabletype::TYPE_INT,
Variabletype::TYPE_INT,
Variabletype::TYPE_INT ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon, numvar,
c, 0.0,
ptrb, ptre,
asub, aval,
bkc, blc, buc,
bkx, blx, bux)?;
task.put_var_type_list(intsub, inttype)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MAXIMIZE)?;
// Assign values to integer variables
// We only set that slice of xx
task.put_xx_slice(Soltype::ITG, 0, 3, &[1.0,1.0,0.0])?;
// Request constructing the solution from integer variable values
task.put_int_param(mosek::Iparam::MIO_CONSTRUCT_SOL, mosek::Onoffkey::ON)?;
// solve
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::LOG)?;
// Read and print solution
let mut xx = vec![0.0; numvar as usize];
task.get_xx(mosek::Soltype::ITG, xx.as_mut_slice())?;
println!("Optimal solution:");
for (i,xi) in xx.iter().enumerate() {
println!("x[{}] = {}",i,*xi);
}
// Was the initial solution used?
let constr = task.get_int_inf(mosek::Iinfitem::MIO_CONSTRUCT_SOLUTION)?;
let constr_val = task.get_dou_inf(mosek::Dinfitem::MIO_CONSTRUCT_SOLUTION_OBJ)?;
println!("Construct solution utilization: {}", constr);
println!("Construct solution objective: {}", constr_val);
Ok(())
}
sourcepub fn put_xc(&mut self, whichsol_: i32, xc_: &mut [f64]) -> Result<(), String>
pub fn put_xc(&mut self, whichsol_: i32, xc_: &mut [f64]) -> Result<(), String>
Sets the xc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
xc_
Primal constraint solution.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putxc
sourcepub fn put_xc_slice(
&mut self,
whichsol_: i32,
first_: i32,
last_: i32,
xc_: &[f64]
) -> Result<(), String>
pub fn put_xc_slice( &mut self, whichsol_: i32, first_: i32, last_: i32, xc_: &[f64] ) -> Result<(), String>
Sets a slice of the xc vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
xc_
Primal constraint solution.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putxcslice
sourcepub fn put_xx(&mut self, whichsol_: i32, xx_: &[f64]) -> Result<(), String>
pub fn put_xx(&mut self, whichsol_: i32, xx_: &[f64]) -> Result<(), String>
Sets the xx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
xx_
Primal variable solution.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putxx
sourcepub fn put_xx_slice(
&mut self,
whichsol_: i32,
first_: i32,
last_: i32,
xx_: &[f64]
) -> Result<(), String>
pub fn put_xx_slice( &mut self, whichsol_: i32, first_: i32, last_: i32, xx_: &[f64] ) -> Result<(), String>
Sets a slice of the xx vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
xx_
Primal variable solution.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putxxslice
Examples found in repository?
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
fn main() -> Result<(),String> {
let numvar : i32 = 4;
let numcon : i32 = 1;
let c = &[ 7.0, 10.0, 1.0, 5.0 ];
let bkc = &[Boundkey::UP];
let blc = &[ -INF ];
let buc = &[2.5];
let bkx = &[Boundkey::LO,
Boundkey::LO,
Boundkey::LO,
Boundkey::LO ];
let blx = &[0.0,
0.0,
0.0,
0.0 ];
let bux = &[INF,
INF,
INF,
INF];
let ptrb = &[0i64, 1, 2, 3];
let ptre = &[1i64, 2, 3, 4];
let aval = &[1.0, 1.0, 1.0, 1.0];
let asub = &[0i32, 0, 0, 0 ];
let intsub = &[0i32, 1, 2];
let inttype = &[Variabletype::TYPE_INT,
Variabletype::TYPE_INT,
Variabletype::TYPE_INT ];
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.input_data(numcon, numvar,
c, 0.0,
ptrb, ptre,
asub, aval,
bkc, blc, buc,
bkx, blx, bux)?;
task.put_var_type_list(intsub, inttype)?;
/* A maximization problem */
task.put_obj_sense(Objsense::MAXIMIZE)?;
// Assign values to integer variables
// We only set that slice of xx
task.put_xx_slice(Soltype::ITG, 0, 3, &[1.0,1.0,0.0])?;
// Request constructing the solution from integer variable values
task.put_int_param(mosek::Iparam::MIO_CONSTRUCT_SOL, mosek::Onoffkey::ON)?;
// solve
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::LOG)?;
// Read and print solution
let mut xx = vec![0.0; numvar as usize];
task.get_xx(mosek::Soltype::ITG, xx.as_mut_slice())?;
println!("Optimal solution:");
for (i,xi) in xx.iter().enumerate() {
println!("x[{}] = {}",i,*xi);
}
// Was the initial solution used?
let constr = task.get_int_inf(mosek::Iinfitem::MIO_CONSTRUCT_SOLUTION)?;
let constr_val = task.get_dou_inf(mosek::Dinfitem::MIO_CONSTRUCT_SOLUTION_OBJ)?;
println!("Construct solution utilization: {}", constr);
println!("Construct solution objective: {}", constr_val);
Ok(())
}
sourcepub fn put_y(&mut self, whichsol_: i32, y_: &[f64]) -> Result<(), String>
pub fn put_y(&mut self, whichsol_: i32, y_: &[f64]) -> Result<(), String>
Sets the y vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
y_
Vector of dual variables corresponding to the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.puty
sourcepub fn put_y_slice(
&mut self,
whichsol_: i32,
first_: i32,
last_: i32,
y_: &[f64]
) -> Result<(), String>
pub fn put_y_slice( &mut self, whichsol_: i32, first_: i32, last_: i32, y_: &[f64] ) -> Result<(), String>
Sets a slice of the y vector for a solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
first_
First index in the sequence. -
last_
Last index plus 1 in the sequence. -
y_
Vector of dual variables corresponding to the constraints.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.putyslice
sourcepub fn read_b_solution(
&self,
filename_: &str,
compress_: i32
) -> Result<(), String>
pub fn read_b_solution( &self, filename_: &str, compress_: i32 ) -> Result<(), String>
Read a binary dump of the task solution and information items.
§Arguments
-
filename_
A valid file name. -
compress_
Data compression type.See Compresstype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readbsolution
sourcepub fn read_data(&mut self, filename_: &str) -> Result<(), String>
pub fn read_data(&mut self, filename_: &str) -> Result<(), String>
Reads problem data from a file.
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readdataautoformat
Examples found in repository?
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
fn opt_server_sync(inputfile : FileOrText, addr : String, cert : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Load some data into the task
match inputfile {
FileOrText::File(filename) => task.read_data(filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Set OptServer URL
task.put_optserver_host(addr.as_str())?;
// Path to certificate, if any
if let Some(cert) = cert {
task.put_str_param(Sparam::REMOTE_TLS_CERT_PATH, cert.as_str())?;
}
// Optimize remotely, no access token
let _trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
Ok(())
}
More examples
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
fn feasrepairex1(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
match filename {
FileOrText::File(fname) => task.read_data(fname.as_str())?,
FileOrText::Text(data) => task.read_lp_string(data.as_str())?
}
task.put_int_param(mosek::Iparam::LOG_FEAS_REPAIR, 3)?;
let wc = vec![1.0; task.get_num_con()? as usize];
let wx = vec![1.0; task.get_num_var()? as usize];
task.primal_repair(wc.as_slice(),wc.as_slice(),wx.as_slice(),wx.as_slice())?;
let sum_viol = task.get_dou_inf(mosek::Dinfitem::PRIMAL_REPAIR_PENALTY_OBJ)?;
println!("Minimized sum of violations = {}", sum_viol);
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::MSG)?;
Ok(())
}
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
fn simple(filename : FileOrText, outfile : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(fname) => {
task.read_data(fname.as_str())?
},
FileOrText::Text(data) => {
task.read_ptf_string(data.as_str())?
}
}
// Solve the problem
let _ = task.optimize()?;
// Print a summary of the solution
task.solution_summary(Streamtype::LOG)?;
// If an output file was specified, save problem to file
if let Some(outfile) = outfile {
// If using OPF format, these parameters will specify what to include in output
task.put_int_param(Iparam::OPF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_PROBLEM, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_HINTS, Onoffkey::OFF)?;
task.put_int_param(Iparam::OPF_WRITE_PARAMETERS, Onoffkey::OFF)?;
task.put_int_param(Iparam::PTF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.write_data(outfile.as_str())?;
}
Ok(())
}
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
fn main() -> Result<(),String> {
let args: Vec<String> = env::args().collect();
let mut task = Task::new().unwrap().with_callbacks();
if args.len() < 2 {
task.read_ptf_string(CQO1_PTF)?;
}
else {
task.read_data(args[1].as_str())?;
}
// Perform optimization.
let trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Handle solution status. We expect Optimal
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
// Fetch and print the solution
println!("An optimal interior point solution is located.");
let numvar = task.get_num_var()?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR, xx.as_mut_slice())?;
println!("xx = {:?}",xx)
},
Solsta::DUAL_INFEAS_CER =>
println!("Dual infeasibility certificate found."),
Solsta::PRIM_INFEAS_CER =>
println!("Primal infeasibility certificate found."),
Solsta::UNKNOWN => {
// The solutions status is unknown. The termination code
// indicates why the optimizer terminated prematurely.
println!("The solution status is unknown.");
let (symname,desc) = mosek::get_code_desc(trm)?;
println!(" Termination code: {} {}\n", symname, desc)
},
_ =>
println!("Unexpected solution status {}\n",solsta)
}
Ok(())
}
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
fn solutionquality(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(filename) => task.read_data (filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Solve the problem
let _ = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut pobj : f64 = 0.0;
let mut pviolcon : f64 = 0.0;
let mut pviolvar : f64 = 0.0;
let mut pviolbarvar : f64 = 0.0;
let mut pviolcones : f64 = 0.0;
let mut pviolitg : f64 = 0.0;
let mut dobj : f64 = 0.0;
let mut dviolcon : f64 = 0.0;
let mut dviolvar : f64 = 0.0;
let mut dviolbarvar : f64 = 0.0;
let mut dviolcones : f64 = 0.0;
task.get_solution_info(Soltype::BAS,
& mut pobj, & mut pviolcon, & mut pviolvar, & mut pviolbarvar, & mut pviolcones, & mut pviolitg,
& mut dobj, & mut dviolcon, & mut dviolvar, & mut dviolbarvar, & mut dviolcones)?;
match solsta {
Solsta::OPTIMAL => {
let abs_obj_gap = (dobj-pobj).abs();
let rel_obj_gap = abs_obj_gap / (1.0 + f64::min(pobj.abs(), dobj.abs()));
let max_primal_viol = f64::max(pviolcon, pviolvar);
let max_primal_viol = f64::max(max_primal_viol , pviolbarvar);
let max_primal_viol = f64::max(max_primal_viol , pviolcones);
let max_dual_viol = f64::max(dviolcon, dviolvar);
let max_dual_viol = f64::max(max_dual_viol, dviolbarvar);
let max_dual_viol = f64::max(max_dual_viol, dviolcones);
// Assume the application needs the solution to be within
// 1e-6 ofoptimality in an absolute sense. Another approach
// would be looking at the relative objective gap
println!("Customized solution information.");
println!(" Absolute objective gap: {:.3e}", abs_obj_gap);
println!(" Relative objective gap: {:.3e}", rel_obj_gap);
println!(" Max primal violation : {:.3e}", max_primal_viol);
println!(" Max dual violation : {:.3e}", max_dual_viol);
let mut accepted = true;
if rel_obj_gap > 1e-6 {
println!("Warning: The relative objective gap is LARGE.");
accepted = false;
}
// We will accept a primal infeasibility of 1e-8 and
// dual infeasibility of 1e-6. These number should chosen problem
// dependent.
if max_primal_viol > 1e-8 {
println!("Warning: Primal violation is too LARGE");
accepted = false;
}
if max_dual_viol > 1e-6 {
println!("Warning: Dual violation is too LARGE.");
accepted = false;
}
if accepted {
let numvar = task.get_num_var()?;
println!("Optimal primal solution");
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS,xx.as_mut_slice())?;
for (j,&xj) in (0..numvar).zip(xx.iter()) {
println!("x[{}]: {}",j,xj);
}
} else {
// print etailed information about the solution
task.analyze_solution(Streamtype::LOG, Soltype::BAS)?;
}
},
Solsta::DUAL_INFEAS_CER => println!("Primal or dual infeasibility certificate found."),
Solsta::UNKNOWN => println!("The status of the solution is unknown."),
_ => println!("Other solution status"),
}
Ok(())
}
sourcepub fn read_data_format(
&mut self,
filename_: &str,
format_: i32,
compress_: i32
) -> Result<(), String>
pub fn read_data_format( &mut self, filename_: &str, format_: i32, compress_: i32 ) -> Result<(), String>
Reads problem data from a file.
§Arguments
-
filename_
A valid file name. -
format_
File data format.See Dataformat
-
compress_
File compression type.See Compresstype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readdataformat
sourcepub fn read_json_sol(&mut self, filename_: &str) -> Result<(), String>
pub fn read_json_sol(&mut self, filename_: &str) -> Result<(), String>
Reads a solution from a JSOL file.
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readjsonsol
sourcepub fn read_json_string(&mut self, data_: &str) -> Result<(), String>
pub fn read_json_string(&mut self, data_: &str) -> Result<(), String>
Load task data from a string in JSON format.
§Arguments
data_
Problem data in text format.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readjsonstring
sourcepub fn read_lp_string(&mut self, data_: &str) -> Result<(), String>
pub fn read_lp_string(&mut self, data_: &str) -> Result<(), String>
Load task data from a string in LP format.
§Arguments
data_
Problem data in text format.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readlpstring
Examples found in repository?
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
fn feasrepairex1(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
match filename {
FileOrText::File(fname) => task.read_data(fname.as_str())?,
FileOrText::Text(data) => task.read_lp_string(data.as_str())?
}
task.put_int_param(mosek::Iparam::LOG_FEAS_REPAIR, 3)?;
let wc = vec![1.0; task.get_num_con()? as usize];
let wx = vec![1.0; task.get_num_var()? as usize];
task.primal_repair(wc.as_slice(),wc.as_slice(),wx.as_slice(),wx.as_slice())?;
let sum_viol = task.get_dou_inf(mosek::Dinfitem::PRIMAL_REPAIR_PENALTY_OBJ)?;
println!("Minimized sum of violations = {}", sum_viol);
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::MSG)?;
Ok(())
}
sourcepub fn read_opf_string(&mut self, data_: &str) -> Result<(), String>
pub fn read_opf_string(&mut self, data_: &str) -> Result<(), String>
Load task data from a string in OPF format.
§Arguments
data_
Problem data in text format.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readopfstring
sourcepub fn read_param_file(&mut self, filename_: &str) -> Result<(), String>
pub fn read_param_file(&mut self, filename_: &str) -> Result<(), String>
Reads a parameter file.
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readparamfile
sourcepub fn read_ptf_string(&mut self, data_: &str) -> Result<(), String>
pub fn read_ptf_string(&mut self, data_: &str) -> Result<(), String>
Load task data from a string in PTF format.
§Arguments
data_
Problem data in text format.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readptfstring
Examples found in repository?
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
fn opt_server_sync(inputfile : FileOrText, addr : String, cert : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Load some data into the task
match inputfile {
FileOrText::File(filename) => task.read_data(filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Set OptServer URL
task.put_optserver_host(addr.as_str())?;
// Path to certificate, if any
if let Some(cert) = cert {
task.put_str_param(Sparam::REMOTE_TLS_CERT_PATH, cert.as_str())?;
}
// Optimize remotely, no access token
let _trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
Ok(())
}
More examples
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
fn simple(filename : FileOrText, outfile : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(fname) => {
task.read_data(fname.as_str())?
},
FileOrText::Text(data) => {
task.read_ptf_string(data.as_str())?
}
}
// Solve the problem
let _ = task.optimize()?;
// Print a summary of the solution
task.solution_summary(Streamtype::LOG)?;
// If an output file was specified, save problem to file
if let Some(outfile) = outfile {
// If using OPF format, these parameters will specify what to include in output
task.put_int_param(Iparam::OPF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_PROBLEM, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_HINTS, Onoffkey::OFF)?;
task.put_int_param(Iparam::OPF_WRITE_PARAMETERS, Onoffkey::OFF)?;
task.put_int_param(Iparam::PTF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.write_data(outfile.as_str())?;
}
Ok(())
}
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
fn main() -> Result<(),String> {
let args: Vec<String> = env::args().collect();
let mut task = Task::new().unwrap().with_callbacks();
if args.len() < 2 {
task.read_ptf_string(CQO1_PTF)?;
}
else {
task.read_data(args[1].as_str())?;
}
// Perform optimization.
let trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Handle solution status. We expect Optimal
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
// Fetch and print the solution
println!("An optimal interior point solution is located.");
let numvar = task.get_num_var()?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR, xx.as_mut_slice())?;
println!("xx = {:?}",xx)
},
Solsta::DUAL_INFEAS_CER =>
println!("Dual infeasibility certificate found."),
Solsta::PRIM_INFEAS_CER =>
println!("Primal infeasibility certificate found."),
Solsta::UNKNOWN => {
// The solutions status is unknown. The termination code
// indicates why the optimizer terminated prematurely.
println!("The solution status is unknown.");
let (symname,desc) = mosek::get_code_desc(trm)?;
println!(" Termination code: {} {}\n", symname, desc)
},
_ =>
println!("Unexpected solution status {}\n",solsta)
}
Ok(())
}
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
fn solutionquality(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(filename) => task.read_data (filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Solve the problem
let _ = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
let solsta = task.get_sol_sta(Soltype::BAS)?;
let mut pobj : f64 = 0.0;
let mut pviolcon : f64 = 0.0;
let mut pviolvar : f64 = 0.0;
let mut pviolbarvar : f64 = 0.0;
let mut pviolcones : f64 = 0.0;
let mut pviolitg : f64 = 0.0;
let mut dobj : f64 = 0.0;
let mut dviolcon : f64 = 0.0;
let mut dviolvar : f64 = 0.0;
let mut dviolbarvar : f64 = 0.0;
let mut dviolcones : f64 = 0.0;
task.get_solution_info(Soltype::BAS,
& mut pobj, & mut pviolcon, & mut pviolvar, & mut pviolbarvar, & mut pviolcones, & mut pviolitg,
& mut dobj, & mut dviolcon, & mut dviolvar, & mut dviolbarvar, & mut dviolcones)?;
match solsta {
Solsta::OPTIMAL => {
let abs_obj_gap = (dobj-pobj).abs();
let rel_obj_gap = abs_obj_gap / (1.0 + f64::min(pobj.abs(), dobj.abs()));
let max_primal_viol = f64::max(pviolcon, pviolvar);
let max_primal_viol = f64::max(max_primal_viol , pviolbarvar);
let max_primal_viol = f64::max(max_primal_viol , pviolcones);
let max_dual_viol = f64::max(dviolcon, dviolvar);
let max_dual_viol = f64::max(max_dual_viol, dviolbarvar);
let max_dual_viol = f64::max(max_dual_viol, dviolcones);
// Assume the application needs the solution to be within
// 1e-6 ofoptimality in an absolute sense. Another approach
// would be looking at the relative objective gap
println!("Customized solution information.");
println!(" Absolute objective gap: {:.3e}", abs_obj_gap);
println!(" Relative objective gap: {:.3e}", rel_obj_gap);
println!(" Max primal violation : {:.3e}", max_primal_viol);
println!(" Max dual violation : {:.3e}", max_dual_viol);
let mut accepted = true;
if rel_obj_gap > 1e-6 {
println!("Warning: The relative objective gap is LARGE.");
accepted = false;
}
// We will accept a primal infeasibility of 1e-8 and
// dual infeasibility of 1e-6. These number should chosen problem
// dependent.
if max_primal_viol > 1e-8 {
println!("Warning: Primal violation is too LARGE");
accepted = false;
}
if max_dual_viol > 1e-6 {
println!("Warning: Dual violation is too LARGE.");
accepted = false;
}
if accepted {
let numvar = task.get_num_var()?;
println!("Optimal primal solution");
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::BAS,xx.as_mut_slice())?;
for (j,&xj) in (0..numvar).zip(xx.iter()) {
println!("x[{}]: {}",j,xj);
}
} else {
// print etailed information about the solution
task.analyze_solution(Streamtype::LOG, Soltype::BAS)?;
}
},
Solsta::DUAL_INFEAS_CER => println!("Primal or dual infeasibility certificate found."),
Solsta::UNKNOWN => println!("The status of the solution is unknown."),
_ => println!("Other solution status"),
}
Ok(())
}
sourcepub fn read_solution(
&mut self,
whichsol_: i32,
filename_: &str
) -> Result<(), String>
pub fn read_solution( &mut self, whichsol_: i32, filename_: &str ) -> Result<(), String>
Reads a solution from a file.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readsolution
sourcepub fn read_solution_file(&self, filename_: &str) -> Result<(), String>
pub fn read_solution_file(&self, filename_: &str) -> Result<(), String>
Read solution file in format determined by the filename
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readsolutionfile
sourcepub fn read_summary(&mut self, whichstream_: i32) -> Result<(), String>
pub fn read_summary(&mut self, whichstream_: i32) -> Result<(), String>
Prints information about last file read.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readsummary
sourcepub fn read_task(&mut self, filename_: &str) -> Result<(), String>
pub fn read_task(&mut self, filename_: &str) -> Result<(), String>
Load task data from a file.
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.readtask
sourcepub fn remove_barvars(&mut self, subset_: &[i32]) -> Result<(), String>
pub fn remove_barvars(&mut self, subset_: &[i32]) -> Result<(), String>
Removes a number of symmetric matrices.
§Arguments
subset_
Indexes of symmetric matrices which should be removed.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.removebarvars
sourcepub fn remove_cones(&mut self, subset_: &[i32]) -> Result<(), String>
pub fn remove_cones(&mut self, subset_: &[i32]) -> Result<(), String>
Removes a number of conic constraints from the problem.
§Arguments
subset_
Indexes of cones which should be removed.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.removecones
sourcepub fn remove_cons(&mut self, subset_: &[i32]) -> Result<(), String>
pub fn remove_cons(&mut self, subset_: &[i32]) -> Result<(), String>
Removes a number of constraints.
§Arguments
subset_
Indexes of constraints which should be removed.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.removecons
sourcepub fn remove_vars(&mut self, subset_: &[i32]) -> Result<(), String>
pub fn remove_vars(&mut self, subset_: &[i32]) -> Result<(), String>
Removes a number of variables.
§Arguments
subset_
Indexes of variables which should be removed.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.removevars
sourcepub fn resize_task(
&mut self,
maxnumcon_: i32,
maxnumvar_: i32,
maxnumcone_: i32,
maxnumanz_: i64,
maxnumqnz_: i64
) -> Result<(), String>
pub fn resize_task( &mut self, maxnumcon_: i32, maxnumvar_: i32, maxnumcone_: i32, maxnumanz_: i64, maxnumqnz_: i64 ) -> Result<(), String>
Resizes an optimization task.
§Arguments
maxnumcon_
New maximum number of constraints.maxnumvar_
New maximum number of variables.maxnumcone_
New maximum number of cones.maxnumanz_
New maximum number of linear non-zero elements.maxnumqnz_
New maximum number of quadratic non-zeros elements.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.resizetask
sourcepub fn sensitivity_report(&self, whichstream_: i32) -> Result<(), String>
pub fn sensitivity_report(&self, whichstream_: i32) -> Result<(), String>
Creates a sensitivity report.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.sensitivityreport
sourcepub fn set_defaults(&mut self) -> Result<(), String>
pub fn set_defaults(&mut self) -> Result<(), String>
Resets all parameter values.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.setdefaults
sourcepub fn solution_def(&self, whichsol_: i32) -> Result<bool, String>
pub fn solution_def(&self, whichsol_: i32) -> Result<bool, String>
Checks whether a solution is defined.
§Arguments
-
whichsol_
Selects a solution.See Soltype
§Returns
isdef
Is non-zero if the requested solution is defined.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.solutiondef
Examples found in repository?
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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
pub fn portfolio(n : i32,
mu : &[f64],
m : &[f64],
GT : &[f64],
x0 : &[f64],
gamma : f64,
w : f64) -> Result<(Vec<f64>,f64),String> {
let k = (GT.len() / n as usize) as i32;
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(3*n)?;
let allvars : Vec<i32> = (0i32..3*n).collect();
let var_x = &allvars[0..n as usize];
let var_c = &allvars[n as usize..2*n as usize];
let var_xc = &allvars[0..2*n as usize];
let var_z = &allvars[2*n as usize..3*n as usize];
for (i,j) in var_x.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::LO, 0.0, 0.0)?;
task.put_var_name(*j,format!("x[{}]",i+1).as_str())?; }
for (i,j) in var_c.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("c[{}]",i+1).as_str())?;
}
for (i,j) in var_z.iter().enumerate() {
task.put_var_bound(*j,mosek::Boundkey::FR, 0.0, 0.0)?;
task.put_var_name(*j,format!("z[{}]",i+1).as_str())?;
}
task.put_obj_sense(Objsense::MAXIMIZE)?;
for i in var_x {
task.put_c_j(*i,mu[*i as usize])?;
}
task.append_cons(1)?;
let con_budget = 0i32;
// budget
task.put_con_name(0,"budget")?;
let wealth = w + x0.iter().sum::<f64>();
task.put_a_row(con_budget,
&var_xc,
(0..n).map(|_| 1.0).chain(m.iter().map(|v| *v)).collect::<Vec<f64>>().as_slice())?;
task.put_con_bound(con_budget,mosek::Boundkey::FX, wealth,wealth)?;
// |x-x0| <= z
{
let coni = task.get_num_con()?;
task.append_cons(2 * n)?;
for i in 0..n {
task.put_con_name(coni+i, format!("zabs1[{}]",1 + i).as_str())?;
task.put_con_name(coni+n+i, format!("zabs2[{}]",1 + i).as_str())?;
}
let ones = vec![1.0; n as usize];
let minusones = vec![-1.0; n as usize];
let con_abs1 : Vec<i32> = (coni..coni+n).collect();
let con_abs2 : Vec<i32> = (coni+n..coni+2*n).collect();
task.put_aij_list(con_abs1.as_slice(), var_x, minusones.as_slice())?;
task.put_aij_list(con_abs1.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni,coni+n, vec![Boundkey::LO; n as usize].as_slice(), x0.iter().map(|&v| -v).collect::<Vec<f64>>().as_slice(), vec![INF; n as usize].as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_x, ones.as_slice())?;
task.put_aij_list(con_abs2.as_slice(), var_z, ones.as_slice())?;
task.put_con_bound_slice(coni+n,coni+n*2, vec![Boundkey::LO; n as usize].as_slice(), x0, vec![INF; n as usize].as_slice())?;
}
// GT
{
let acci = task.get_num_acc()?;
let afei = task.get_num_afe()?;
task.append_afes(k as i64 + 1)?;
let dom = task.append_quadratic_cone_domain(k as i64+1)?;
task.append_acc_seq(dom,
afei,
vec![0.0; k as usize + 1].as_slice())?;
task.put_acc_name(acci,"risk")?;
task.put_afe_g(afei,gamma)?;
for ((i,j),v) in iproduct!(0..n,0..n).zip(GT).filter(|(_,v)| **v != 0.0) {
task.put_afe_f_entry(afei + i as i64 + 1, j as i32, *v)?;
}
}
// MI
{
let mut acci = task.get_num_acc()?;
let mut afei = task.get_num_afe()?;
let afe0 = afei;
task.append_afes(n as i64 * 2+1)?;
let dom = task.append_primal_power_cone_domain(3,&[2.0, 1.0])?;
task.put_afe_g(afe0,1.0)?;
afei += 1;
for (i,&cj,&zj,&x0j) in izip!(0..n,var_c,var_z,x0) {
task.put_afe_f_entry(afei,cj,1.0)?;
task.put_afe_f_entry(afei+1,zj,1.0)?;
task.put_afe_g(afei+1, - x0j)?;
task.append_acc(dom,
&[afei,afe0,afei+1],
&[0.0, 0.0, 0.0])?;
task.put_acc_name(acci,format!("market_impact[{}]",i+1).as_str())?;
afei += 2;
acci += 1;
}
}
let _ = task.optimize()?;
task.write_data("portfolio_3_impact.ptf")?;
/* Display the solution summary for quick inspection of results. */
task.solution_summary(Streamtype::MSG)?;
if ! task.solution_def(Soltype::ITR)? {
return Err("No solultion defined".to_string());
}
// See https://docs.mosek.com/latest/rustapi/accessing-solution.html about handling solution statuses.
let solsta = task.get_sol_sta(Soltype::ITR)?;
if solsta != Solsta::OPTIMAL {
return Err("Unexpected solution status".to_string());
}
let mut level = vec![0.0;n as usize];
task.get_xx_slice(Soltype::ITR,0,n,level.as_mut_slice())?;
let obj = task.get_primal_obj(Soltype::ITR)?;
Ok((level,obj))
}
sourcepub fn solution_summary(&self, whichstream_: i32) -> Result<(), String>
pub fn solution_summary(&self, whichstream_: i32) -> Result<(), String>
Prints a short summary of the current solutions.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.solutionsummary
Examples found in repository?
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
fn opt_server_sync(inputfile : FileOrText, addr : String, cert : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Load some data into the task
match inputfile {
FileOrText::File(filename) => task.read_data(filename.as_str())?,
FileOrText::Text(data) => task.read_ptf_string(data.as_str())?
}
// Set OptServer URL
task.put_optserver_host(addr.as_str())?;
// Path to certificate, if any
if let Some(cert) = cert {
task.put_str_param(Sparam::REMOTE_TLS_CERT_PATH, cert.as_str())?;
}
// Optimize remotely, no access token
let _trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
Ok(())
}
More examples
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
fn feasrepairex1(filename : FileOrText) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
match filename {
FileOrText::File(fname) => task.read_data(fname.as_str())?,
FileOrText::Text(data) => task.read_lp_string(data.as_str())?
}
task.put_int_param(mosek::Iparam::LOG_FEAS_REPAIR, 3)?;
let wc = vec![1.0; task.get_num_con()? as usize];
let wx = vec![1.0; task.get_num_var()? as usize];
task.primal_repair(wc.as_slice(),wc.as_slice(),wx.as_slice(),wx.as_slice())?;
let sum_viol = task.get_dou_inf(mosek::Dinfitem::PRIMAL_REPAIR_PENALTY_OBJ)?;
println!("Minimized sum of violations = {}", sum_viol);
let _ = task.optimize()?;
task.solution_summary(mosek::Streamtype::MSG)?;
Ok(())
}
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
fn simple(filename : FileOrText, outfile : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(fname) => {
task.read_data(fname.as_str())?
},
FileOrText::Text(data) => {
task.read_ptf_string(data.as_str())?
}
}
// Solve the problem
let _ = task.optimize()?;
// Print a summary of the solution
task.solution_summary(Streamtype::LOG)?;
// If an output file was specified, save problem to file
if let Some(outfile) = outfile {
// If using OPF format, these parameters will specify what to include in output
task.put_int_param(Iparam::OPF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_PROBLEM, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_HINTS, Onoffkey::OFF)?;
task.put_int_param(Iparam::OPF_WRITE_PARAMETERS, Onoffkey::OFF)?;
task.put_int_param(Iparam::PTF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.write_data(outfile.as_str())?;
}
Ok(())
}
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
fn main() -> Result<(),String> {
let args: Vec<String> = env::args().collect();
let mut task = Task::new().unwrap().with_callbacks();
if args.len() < 2 {
task.read_ptf_string(CQO1_PTF)?;
}
else {
task.read_data(args[1].as_str())?;
}
// Perform optimization.
let trm = task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Handle solution status. We expect Optimal
let solsta = task.get_sol_sta(Soltype::ITR)?;
match solsta {
Solsta::OPTIMAL => {
// Fetch and print the solution
println!("An optimal interior point solution is located.");
let numvar = task.get_num_var()?;
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR, xx.as_mut_slice())?;
println!("xx = {:?}",xx)
},
Solsta::DUAL_INFEAS_CER =>
println!("Dual infeasibility certificate found."),
Solsta::PRIM_INFEAS_CER =>
println!("Primal infeasibility certificate found."),
Solsta::UNKNOWN => {
// The solutions status is unknown. The termination code
// indicates why the optimizer terminated prematurely.
println!("The solution status is unknown.");
let (symname,desc) = mosek::get_code_desc(trm)?;
println!(" Termination code: {} {}\n", symname, desc)
},
_ =>
println!("Unexpected solution status {}\n",solsta)
}
Ok(())
}
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
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
fn main() -> Result<(),String> {
/* Create the optimization task. */
let mut task = match Task::new() {
Some(t) => t,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
let infinity = 0.0; // for symbolic use, value is irrelevant
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.append_vars(6)?;
task.append_cons(3)?;
task.put_var_bound_slice_const(0, 6, Boundkey::FR, -infinity, infinity)?;
// Integrality constraints
task.put_var_type_list(vec![1i32,2i32].as_slice(),
vec![Variabletype::TYPE_INT, Variabletype::TYPE_INT].as_slice())?;
// Set up the three auxiliary linear constraints
task.put_aij_list(vec![0i32,0i32,1i32,2i32,2i32].as_slice(),
vec![1i32,3i32,4i32,2i32,5i32].as_slice(),
vec![-1.0,1.0,1.0,1.0,-1.0].as_slice())?;
task.put_con_bound_slice(0, 3,
vec![Boundkey::FX, Boundkey::FX, Boundkey::FX].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice(),
vec![-3.8, 1.0, 0.0].as_slice())?;
// Objective
task.put_obj_sense(Objsense::MINIMIZE)?;
task.put_c_j(0, 1.0)?;
// Conic part of the problem
task.append_afes(6)?;
for i in 0..6 {
task.put_afe_f_entry(i as i64, i as i32, 1.0)?;
}
{
let domidx = task.append_quadratic_cone_domain(3)?;
task.append_acc(domidx,
vec![0i64,1i64,2i64].as_slice(),
vec![0.0,0.0,0.0].as_slice())?;
}
{
let domidx = task.append_primal_exp_cone_domain()?;
task.append_acc(domidx,vec![3i64,4i64,5i64].as_slice(),vec![0.0,0.0,0.0].as_slice())?;
}
// Optimize the task
let _trm = task.optimize()?;
task.solution_summary(Streamtype::MSG)?;
let mut xx = vec![0.0; 2];
task.get_xx_slice(Soltype::ITG, 1, 3, xx.as_mut_slice())?;
println!("x = {} y = {}",xx[0],xx[1]);
Ok(())
}
- examples/mioinitsol.rs
- examples/pow1.rs
- examples/portfolio_1_basic.rs
- examples/djc1.rs
- examples/sdo_lmi.rs
- examples/lo2.rs
- examples/sdo2.rs
- examples/qo1.rs
- examples/qcqo1.rs
- examples/solutionquality.rs
- examples/portfolio_6_factor.rs
- examples/lo1.rs
- examples/cqo1.rs
- examples/portfolio_4_transcost.rs
- examples/portfolio_3_impact.rs
- examples/sdo1.rs
sourcepub fn solve_with_basis(
&mut self,
transp_: bool,
numnz_: i32,
sub_: &mut [i32],
val_: &mut [f64]
) -> Result<i32, String>
pub fn solve_with_basis( &mut self, transp_: bool, numnz_: i32, sub_: &mut [i32], val_: &mut [f64] ) -> Result<i32, String>
Solve a linear equation system involving a basis matrix.
§Arguments
transp_
Controls which problem formulation is solved.numnz_
Input (number of non-zeros in right-hand side).sub_
Input (indexes of non-zeros in right-hand side) and output (indexes of non-zeros in solution vector).val_
Input (right-hand side values) and output (solution vector values).
§Returns
numnzout
Output (number of non-zeros in solution vector).
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.solvewithbasis
Examples found in repository?
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
fn main() -> Result<(),String> {
let numcon : i32 = 2;
let numvar : i32 = 2;
let aval = &[ -1.0 ,
1.0, 1.0 ];
let asub = &[ 1,
0, 1 ];
let ptrb = &[0, 1];
let ptre = &[1, 3];
// int[] bsub = new int[numvar];
// double[] b = new double[numvar];
// int[] basis = new int[numvar];
let mut task = Task::new().unwrap();
// Put A matrix and factor A. Call this function only once for a
// given task.
let basis = setup(& mut task,
aval,
asub,
ptrb,
ptre,
numvar)?;
let mut task = task.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* now solve rhs */
let mut b = vec![0.0; numvar as usize];
let mut bsub = vec![0; numvar as usize];
b[0] = 1.0; b[1] = -2.0;
bsub[0] = 0; bsub[1] = 1;
let nz = task.solve_with_basis(false, 2, bsub.as_mut_slice(), b.as_mut_slice())?;
println!("\nSolution to Bx = b:\n");
// Print solution and show correspondents to original variables in
// the problem
for &bsubi in bsub[..nz as usize].iter() {
if basis[bsubi as usize] < numcon {
println!("This should never happen");
}
else {
println!("x{} = {}",basis[bsubi as usize] - numcon, b[bsubi as usize]);
}
}
b[0] = 7.0;
bsub[0] = 0;
let nz = task.solve_with_basis(false, 1, bsub.as_mut_slice(), b.as_mut_slice())?;
println!("Solution to Bx = b:");
// Print solution and show correspondents to original variables in
// the problem
for &bsubi in bsub[..nz as usize].iter() {
if basis[bsubi as usize] < numcon {
println!("This should never happen");
}
else {
println!("x{} = {}",basis[bsubi as usize] - numcon,b[bsubi as usize]);
}
}
Ok(())
}
More examples
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
fn solve() -> Result<(),String> {
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
task.put_obj_name("solvebasis")?;
let numcon : i32 = 2;
let numvar : i32 = 2;
let mut w1 = vec![2.0, 6.0];
let mut w2 = vec![1.0, 0.0];
task.input_data(numcon, numvar,
&[1.0, 1.0], // c
0.0, // cfix
&[0,2], // ptrb
&[2,3], // ptre
&[0,1,
0,1], // sub
&[1.0, 1.0,
2.0, 1.0], // val
&[Boundkey::UP,
Boundkey::UP], // bkc
&[0.0,0.0], // blc
&[2.0,6.0], // buc
&[Boundkey::LO,
Boundkey::LO], // bkx
&[0.0, 0.0], // blx
&[0.0,0.0])?; // bux;
task.put_obj_sense(Objsense::MAXIMIZE)?;
let _ = task.optimize()?;
let mut basis = vec![0i32; numcon as usize];
task.init_basis_solve(basis.as_mut_slice())?;
// List basis variables corresponding to columns of B
let mut varsub = vec![0i32, 1];
for i in 0..numcon {
if basis[varsub[i as usize] as usize] < numcon {
println!("Basis variable no {} is xc{}",i,basis[varsub[i as usize] as usize]);
}
else {
println!("Basis variable no {} is x{}",i,basis[i as usize]-numcon);
// solve Bx = w1
// varsub contains index of non-zeros in b.
// On return b contains the solution x and
// varsub the index of the non-zeros in x.
{
let nz = task.solve_with_basis(false, 2, varsub.as_mut_slice(), w1.as_mut_slice())?;
println!("nz = {}",nz);
println!("Solution to Bx = {:?}",w1);
for vsubi in &varsub[0..nz as usize] {
if basis[*vsubi as usize] < numcon {
println!("xc {} = {}",basis[*vsubi as usize],w1[*vsubi as usize]);
}
else {
println!("x{} = {}",basis[*vsubi as usize] - numcon,w1[*vsubi as usize])
}
}
}
// Solve B^Tx = w2
{
varsub[0] = 1;
let nz = task.solve_with_basis(true,1,varsub.as_mut_slice(),w2.as_mut_slice())?;
println!("nz = {}",nz);
println!("Solution to B^Tx = {:?}",w2);
for vsubi in &varsub[0..nz as usize] {
if basis[*vsubi as usize] < numcon {
print!("xc{} = {}",basis[*vsubi as usize],w2[*vsubi as usize]);
}
else {
print!("x{} = {}",basis[*vsubi as usize] - numcon,w2[*vsubi as usize]);
}
}
}
}
}
Ok(())
}
sourcepub fn str_to_cone_type(
&self,
str_: &str,
conetype_: &mut i32
) -> Result<(), String>
pub fn str_to_cone_type( &self, str_: &str, conetype_: &mut i32 ) -> Result<(), String>
Obtains a cone type code.
§Arguments
-
str_
String corresponding to the cone type code. -
conetype_
The cone type corresponding to str.See Conetype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.strtoconetype
sourcepub fn str_to_sk(&self, str_: &str, sk_: &mut i32) -> Result<(), String>
pub fn str_to_sk(&self, str_: &str, sk_: &mut i32) -> Result<(), String>
Obtains a status key.
§Arguments
-
str_
A status key abbreviation string. -
sk_
Status key corresponding to the string.See Stakey
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.strtosk
sourcepub fn toconic(&mut self) -> Result<(), String>
pub fn toconic(&mut self) -> Result<(), String>
In-place reformulation of a QCQO to a conic quadratic problem.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.toconic
sourcepub fn unlink_func_from_stream(
&mut self,
whichstream_: i32
) -> Result<(), String>
pub fn unlink_func_from_stream( &mut self, whichstream_: i32 ) -> Result<(), String>
Disconnects a user-defined function from a task stream.
§Arguments
-
whichstream_
Index of the stream.See Streamtype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.unlinkfuncfromtaskstream
sourcepub fn update_solution_info(&mut self, whichsol_: i32) -> Result<(), String>
pub fn update_solution_info(&mut self, whichsol_: i32) -> Result<(), String>
Update the information items related to the solution.
§Arguments
-
whichsol_
Selects a solution.See Soltype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.updatesolutioninfo
sourcepub fn which_param(
&self,
parname_: &str,
partype_: &mut i32,
param_: &mut i32
) -> Result<(), String>
pub fn which_param( &self, parname_: &str, partype_: &mut i32, param_: &mut i32 ) -> Result<(), String>
Checks a parameter name.
§Arguments
-
parname_
Parameter name. -
partype_
Parameter type.See Parametertype
-
param_
Which parameter.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.whichparam
sourcepub fn write_b_solution(
&self,
filename_: &str,
compress_: i32
) -> Result<(), String>
pub fn write_b_solution( &self, filename_: &str, compress_: i32 ) -> Result<(), String>
Write a binary dump of the task solution and information items.
§Arguments
-
filename_
A valid file name. -
compress_
Data compression type.See Compresstype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.writebsolution
sourcepub fn write_data(&self, filename_: &str) -> Result<(), String>
pub fn write_data(&self, filename_: &str) -> Result<(), String>
Writes problem data to a file.
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.writedata
Examples found in repository?
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
fn simple(filename : FileOrText, outfile : Option<String>) -> Result<(),String> {
let mut task = Task::new().unwrap().with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// We assume that a problem file was given as the first command
// line argument (received in `args')
match filename {
FileOrText::File(fname) => {
task.read_data(fname.as_str())?
},
FileOrText::Text(data) => {
task.read_ptf_string(data.as_str())?
}
}
// Solve the problem
let _ = task.optimize()?;
// Print a summary of the solution
task.solution_summary(Streamtype::LOG)?;
// If an output file was specified, save problem to file
if let Some(outfile) = outfile {
// If using OPF format, these parameters will specify what to include in output
task.put_int_param(Iparam::OPF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_PROBLEM, Onoffkey::ON)?;
task.put_int_param(Iparam::OPF_WRITE_HINTS, Onoffkey::OFF)?;
task.put_int_param(Iparam::OPF_WRITE_PARAMETERS, Onoffkey::OFF)?;
task.put_int_param(Iparam::PTF_WRITE_SOLUTIONS, Onoffkey::ON)?;
task.write_data(outfile.as_str())?;
}
Ok(())
}
More examples
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
fn main() -> Result<(),String> {
// In this example we set up a simple problem
// One could use any task or a task read from a file
let mut task = test_problem()?.with_callbacks();
let n = task.get_num_var()?;
let m = task.get_num_con()?;
// Useful for debugging
task.write_data("pinfeas.ptf")?; // Write file in human-readable format
// Attach a log stream printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Perform the optimization.
task.optimize()?;
task.solution_summary(Streamtype::LOG)?;
// Check problem status, we use the interior point solution
if task.get_pro_sta(Soltype::ITR)? == Prosta::PRIM_INFEAS {
// Set the tolerance at which we consider a dual value as essential
let eps = 1e-7;
println!("Variable bounds important for infeasibility: ");
let mut slx = vec![0.0; n as usize]; task.get_slx(Soltype::ITR, slx.as_mut_slice())?;
let mut sux = vec![0.0; n as usize]; task.get_sux(Soltype::ITR, sux.as_mut_slice())?;
analyze_certificate(slx.as_slice(), sux.as_slice(), eps);
println!("Constraint bounds important for infeasibility: ");
let mut slc = vec![0.0; m as usize]; task.get_slc(Soltype::ITR, slc.as_mut_slice())?;
let mut suc = vec![0.0; m as usize]; task.get_suc(Soltype::ITR, suc.as_mut_slice())?;
analyze_certificate(slc.as_mut_slice(), suc.as_mut_slice(), eps);
}
else {
println!("The problem is not primal infeasible, no certificate to show");
}
Ok(())
}
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
fn logistic_regression(X : &[f64],
Y : &[bool],
lamb : f64) -> Result<Vec<f64>,String> {
let n = Y.len() as i32;
let d = (X.len()/Y.len()) as i32; // num samples, dimension
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Variables [r; theta; t]
let nvar : i32 = 1+d+n;
task.append_vars(nvar)?;
task.put_var_bound_slice_const(0, nvar, Boundkey::FR, -INF, INF)?;
let (r,theta,t) = (0i32,1i32,1+d);
task.put_var_name(r,"r")?;
for j in 0..d { task.put_var_name(theta+j,format!("theta[{}]",j).as_str())?; }
for j in 0..n { task.put_var_name(t+j,format!("t[{}]",j).as_str())?; }
// Objective lambda*r + sum(t)
task.put_c_j(r, lamb)?;
for i in 0..n { task.put_c_j(t+i, 1.0)?; }
task.put_obj_sense(Objsense::MINIMIZE)?;
// Softplus function constraints
softplus(& mut task, d, n, theta, t, X, Y)?;
// Regularization
// Append a sequence of linear expressions (r, theta) to F
let numafe = task.get_num_afe()?;
task.append_afes(1+d as i64)?;
task.put_afe_f_entry(numafe, r, 1.0)?;
for i in 0..d {
task.put_afe_f_entry(numafe + i as i64 + 1, theta + i, 1.0)?;
}
// Add the constraint
{
let dom = task.append_quadratic_cone_domain((1+d) as i64)?;
task.append_acc_seq(dom,
numafe,
vec![0.0; 1+d as usize].as_slice())?;
}
// Solution
task.write_data("logistic.ptf")?;
task.optimize()?;
let mut xx = vec![0.0; d as usize];
task.get_xx_slice(Soltype::ITR, theta, theta+d as i32,xx.as_mut_slice())?;
Ok(xx)
}
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
fn main() -> Result<(),String> {
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0, 0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// One linear constraint - sum(x) = 1
task.append_cons(1)?;
task.put_a_row(0,x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_con_bound(0, Boundkey::FX, 1.0, 1.0)?;
// Append empty AFE rows for affine expression storage
task.append_afes(k + 1)?;
// G matrix in sparse form
let Gsubi : &[i64] = &[0, 0, 1, 1];
let Gsubj : &[i32] = &[0, 1, 0, 2];
let Gval = &[1.5, 0.1, 0.3, 2.1];
// Other data
let h = &[0.0, 0.1];
let gamma = 0.03;
// Construct F matrix in sparse form
let Fsubi : Vec<i64> = Gsubi.iter().map(|i| *i+1).collect(); // G will be placed from row number 1 in F
let Fsubj = Gsubj;
let Fval = Gval;
// Fill in F storage
task.put_afe_f_entry_list(Fsubi.as_slice(), Fsubj, Fval)?;
// Fill in g storage
task.put_afe_g(0, gamma)?;
task.put_afe_g_slice(1, k+1, h)?;
// Define a conic quadratic domain
let quadDom = task.append_quadratic_cone_domain(k + 1)?;
// Create the ACC
task.append_acc(quadDom, // Domain index
(0..k+1).collect::<Vec<i64>>().as_slice(), // Indices of AFE rows [0,...,k]
vec![0.0; (k+1) as usize].as_slice())?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc1.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert!(task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; (k+1) as usize];
let mut doty = vec![0.0; (k+1) as usize];
task.evaluate_acc(Soltype::ITR,0,activity.as_mut_slice())?;
println!("Activity of ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,0,doty.as_mut_slice())?;
println!("Dual of ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
// Define problem data
const n : i32 = 3;
const k : i64 = 2;
// Create a task
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Attach a printer to the task
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
// Create n free variables
task.append_vars(n)?;
let x : Vec<i32> = (0..n).collect();
task.put_var_bound_slice_const(0, n, Boundkey::FR, 0.0,0.0)?;
// Set up the objective
let c = &[2.0, 3.0, -1.0];
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.put_c_list(x.as_slice(), c)?;
// Set AFE rows representing the linear constraint
task.append_afes(1)?;
task.put_afe_f_row(0, x.as_slice(), vec![1.0; n as usize].as_slice())?;
task.put_afe_g(0, -1.0)?;
// Set AFE rows representing the quadratic constraint
task.append_afes(k + 1)?;
task.put_afe_f_row(2, // afeidx, row number
&[0i32, 1], // varidx, column numbers
&[1.5, 0.1])?; // values
task.put_afe_f_row(3, // afeidx, row number
&[0i32, 2], // varidx, column numbers
&[0.3, 2.1])?; // values
let h = &[0.0, 0.1];
let gamma = 0.03;
task.put_afe_g(1, gamma)?;
task.put_afe_g_slice(2, k+2, h)?;
// Define domains
let zero_dom = task.append_rzero_domain(1)?;
let quad_dom = task.append_quadratic_cone_domain(k + 1)?;
// Append affine conic constraints
task.append_acc(zero_dom, // Domain index
&[0i64], // Indices of AFE rows
&[0.0])?; // Ignored
task.append_acc(quad_dom, // Domain index
&[1i64,2,3], // Indices of AFE rows
&[0.0,0.0,0.0])?; // Ignored
// Solve and retrieve solution
let _ = task.optimize()?;
task.write_data("acc2.ptf")?;
let mut xx = vec![0.0; n as usize];
task.get_xx(Soltype::ITR,xx.as_mut_slice())?;
assert! (task.get_sol_sta(Soltype::ITR)? == Solsta::OPTIMAL);
println!("Solution: {:?}",xx);
// Demonstrate retrieving activity of ACC
let mut activity = vec![0.0; 3];
let mut doty = vec![0.0; 3];
task.evaluate_acc(Soltype::ITR,1,activity.as_mut_slice())?;
println!("Activity of quadratic ACC:: {:?}",activity);
// Demonstrate retrieving the dual of ACC
task.get_acc_dot_y(Soltype::ITR,1,doty.as_mut_slice())?;
println!("Dual of quadratic ACC:: {:?}",doty);
Ok(())
}
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
fn main() -> Result<(),String> {
let numcon : i32 = 1;
let numvar : i32 = 5;
// Since the value infinity is never used, we define
// 'infinity' symbolic purposes only
let cval = vec![ 1.0, 1.0, -1.0 ];
let csub = vec![ 3, 4, 0 ];
let aval = vec![ 1.0, 1.0, 0.5 ];
let asub = vec![ 0, 1, 2 ];
/* Create the optimization task. */
let mut task = match Task::new() {
Some(e) => e,
None => return Err("Failed to create task".to_string()),
}.with_callbacks();
// Directs the log task stream to the user specified
// method msgclass.streamCB
task.put_stream_callback(Streamtype::LOG, |msg| print!("{}",msg))?;
/* Append 'numcon' empty constraints.
The constraints will initially have no bounds. */
task.append_cons(numcon)?;
/* Append 'numvar' variables.
The variables will initially be fixed at zero (x=0). */
task.append_vars(numvar)?;
/* Set up the linear part of the problem */
task.put_c_list(&csub, &cval)?;
task.put_a_row(0, &asub, &aval)?;
task.put_con_bound(0, Boundkey::FX, 2.0, 2.0)?;
task.put_var_bound_slice_const(0, numvar, Boundkey::FR, -INF, INF)?;
/* Add a conic constraint */
let pc1 = task.append_primal_power_cone_domain(3, &[0.2, 0.8])?;
let pc2 = task.append_primal_power_cone_domain(3, &[4.0, 6.0])?;
// Create data structures F,g so that
//
// F * x + g = (x(0), x(1), x(3), x(2), 1.0, x(4))
//
task.append_afes(6)?;
task.put_afe_f_entry_list(&[0, 1, 2, 3, 5], // Rows
&[0, 1, 3, 2, 4], // Columns
&[1.0, 1.0, 1.0, 1.0, 1.0])?;
task.put_afe_g(4, 1.0)?;
// Append the two conic constraints
task.append_acc(pc1, // Domain
&[0, 1, 2], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.append_acc(pc2, // Domain
&[3, 4, 5], // Rows from F
&[0.0,0.0,0.0])?; // Unused
task.put_obj_sense(Objsense::MAXIMIZE)?;
task.optimize()?;
task.write_data("pow1.ptf")?;
// Print a summary containing information
// about the solution for debugging purposes
task.solution_summary(Streamtype::LOG)?;
/* Get status information about the solution */
let solsta = task.get_sol_sta(Soltype::ITR)?;
assert!(solsta == Solsta::OPTIMAL);
let mut xx = vec![0.0; numvar as usize];
task.get_xx(Soltype::ITR,
xx.as_mut_slice())?;
println!("Optimal primal solution");
for (j,&xj) in xx[0..3].iter().enumerate() {
println!("x[{}]: {}",j+1,xj);
}
Ok(())
}
sourcepub fn write_json_sol(&self, filename_: &str) -> Result<(), String>
pub fn write_json_sol(&self, filename_: &str) -> Result<(), String>
Writes a solution to a JSON file.
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.writejsonsol
sourcepub fn write_param_file(&self, filename_: &str) -> Result<(), String>
pub fn write_param_file(&self, filename_: &str) -> Result<(), String>
Writes all the parameters to a parameter file.
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.writeparamfile
sourcepub fn write_solution(
&self,
whichsol_: i32,
filename_: &str
) -> Result<(), String>
pub fn write_solution( &self, whichsol_: i32, filename_: &str ) -> Result<(), String>
Write a solution to a file.
§Arguments
-
whichsol_
Selects a solution.See Soltype
-
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.writesolution
sourcepub fn write_solution_file(&self, filename_: &str) -> Result<(), String>
pub fn write_solution_file(&self, filename_: &str) -> Result<(), String>
Write solution file in format determined by the filename
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.writesolutionfile
sourcepub fn write_stat(&mut self, filename_: &str) -> Result<(), String>
pub fn write_stat(&mut self, filename_: &str) -> Result<(), String>
Appends a record to the statistics file.
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.writestat
sourcepub fn write_task(&self, filename_: &str) -> Result<(), String>
pub fn write_task(&self, filename_: &str) -> Result<(), String>
Write a complete binary dump of the task data.
§Arguments
filename_
A valid file name.
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.writetask
sourcepub fn write_task_solver_result_file(
&self,
filename_: &str,
compress_: i32
) -> Result<(), String>
pub fn write_task_solver_result_file( &self, filename_: &str, compress_: i32 ) -> Result<(), String>
Internal
§Arguments
-
filename_
A valid file name. -
compress_
Data compression type.See Compresstype
Full documentation: https://docs.mosek.com/latest/capi/alphabetic-functionalities.html#mosek.env.writetasksolverresult_file