1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
//! Copyright : Copyright (c) MOSEK ApS, Denmark. All rights reserved.
//!
//! File : solvelinear.rs
//!
//! Purpose : To demonstrate the usage of MSK_solvewithbasis
//! when solving the linear system:
//!
//! 1.0 x1 = b1
//! -1.0 x0 + 1.0 x1 = b2
//!
//! with two different right hand sides
//!
//! b = (1.0, -2.0)
//!
//! and
//!
//! b = (7.0, 0.0)
extern crate mosek;
use mosek::{Task,Boundkey,Streamtype,Soltype,Stakey};
const INF : f64 = 0.0;
fn setup(task : & mut mosek::Task,
aval : &[f64],
asub : &[i32],
ptrb : &[i64],
ptre : &[i64],
numvar : i32) -> Result<Vec<i32>,String> {
// mosek.stakey[] skx = new mosek.stakey [numvar];
// mosek.stakey[] skc = new mosek.stakey [numvar];
// for (int i = 0; i < numvar ; ++i) {
// skx[i] = mosek.stakey.bas;
// skc[i] = mosek.stakey.fix;
// }
task.append_vars(numvar)?;
task.append_cons(numvar)?;
task.put_a_col_slice(0,numvar,ptrb,ptre,asub,aval)?;
task.put_con_bound_slice_const(0,numvar,Boundkey::FX,0.0,0.0)?;
task.put_var_bound_slice_const(0,numvar,Boundkey::FR,-INF,INF)?;
/* Define a basic solution by specifying
status keys for variables & constraints. */
task.delete_solution(Soltype::BAS)?;
task.put_skc_slice(Soltype::BAS, 0, numvar, vec![Stakey::FIX; numvar as usize].as_slice())?;
task.put_skx_slice(Soltype::BAS, 0, numvar, vec![Stakey::BAS; numvar as usize].as_slice())?;
let mut basis = vec![0; numvar as usize];
task.init_basis_solve(basis.as_mut_slice())?;
Ok(basis)
}
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(())
}
#[cfg(test)]
mod tests {
#[test]
fn test() {
super::main().unwrap();
}
}