use crate::matrix::coo::CooMat;
use crate::problem::base::ProblemEval;
pub struct ProblemMinlp
{
x0: Option<Vec<f64>>,
phi: f64,
gphi: Vec<f64>,
hphi: CooMat<f64>,
a: CooMat<f64>,
b: Vec<f64>,
f: Vec<f64>,
j: CooMat<f64>,
h: Vec<CooMat<f64>>,
hcomb: CooMat<f64>,
l: Vec<f64>,
u: Vec<f64>,
p: Vec<bool>,
eval_fn: ProblemEval,
}
impl ProblemMinlp {
pub fn new(hphi: CooMat<f64>,
a: CooMat<f64>,
b: Vec<f64>,
j: CooMat<f64>,
h: Vec<CooMat<f64>>,
l: Vec<f64>,
u: Vec<f64>,
p: Vec<bool>,
x0: Option<Vec<f64>>,
eval_fn: ProblemEval) -> Self {
let nx = a.cols();
let na = a.rows();
let nf = j.rows();
assert_eq!(hphi.cols(), nx);
assert_eq!(hphi.rows(), nx);
assert_eq!(a.cols(), nx);
assert_eq!(a.rows(), na);
assert_eq!(b.len(), na);
assert_eq!(j.cols(), nx);
assert_eq!(j.rows(), nf);
assert_eq!(h.len(), nf);
for hh in h.iter() {
assert_eq!(hh.rows(), nx);
assert_eq!(hh.cols(), nx);
}
assert_eq!(l.len(), nx);
assert_eq!(u.len(), nx);
assert_eq!(p.len(), nx);
let mut k: usize = 0;
let hcomb_nnz = h.iter().map(|h| h.nnz()).sum();
let mut hcomb = CooMat::from_nnz((nx, nx), hcomb_nnz);
for hh in h.iter() {
for (row, col, _val) in hh.iter() {
hcomb.set_row_ind(k, *row);
hcomb.set_col_ind(k, *col);
k += 1;
}
}
Self {
x0: x0,
phi: 0.,
gphi: vec![0.;nx],
hphi: hphi,
a: a,
b: b,
f: vec![0.;nf],
j: j,
h: h,
hcomb: hcomb,
l: l,
u: u,
p: p,
eval_fn: eval_fn
}
}
pub fn x0(&self) -> Option<&[f64]> {
match &self.x0 {
Some(xx) => Some(&xx),
None => None
}
}
pub fn phi(&self) -> f64 { self.phi }
pub fn gphi(&self) -> &[f64] { &self.gphi }
pub fn hphi(&self) -> &CooMat<f64> { &self.hphi }
pub fn a(&self) -> &CooMat<f64> { &self.a }
pub fn b(&self) -> &[f64] { &self.b }
pub fn f(&self) -> &[f64] { &self.f }
pub fn j(&self) -> &CooMat<f64> { &self.j }
pub fn h(&self) -> &Vec<CooMat<f64>> { &self.h }
pub fn hcomb(&self) -> &CooMat<f64> { &self.hcomb }
pub fn l(&self) -> &[f64] { &self.l }
pub fn u(&self) -> &[f64] { &self.u }
pub fn p(&self) -> &[bool] { &self.p }
pub fn nx(&self) -> usize { self.a().cols() }
pub fn na(&self) -> usize { self.b().len() }
pub fn nf(&self) -> usize { self.f().len() }
pub fn evaluate(&mut self, x: &[f64]) -> () {
(self.eval_fn)(&mut self.phi,
&mut self.gphi,
&mut self.hphi,
&mut self.f,
&mut self.j,
&mut self.h,
x)
}
pub fn combine_h(&mut self, nu: &[f64]) -> () {
assert_eq!(self.nf(), nu.len());
let mut k: usize = 0;
let data = self.hcomb.data_mut();
for (h, nuval) in self.h.iter().zip(nu.iter()) {
for val in h.data().iter() {
data[k] = (*nuval)*(*val);
k += 1;
}
}
}
}