Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | FirstOrderProblem returns primal information along minorants. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
9a0f6816f581a9e7ac1096d93f345575 |
| User & Date: | fifr 2016-09-30 19:42:04.510 |
Context
|
2016-10-01
| ||
| 07:47 | vector: Implement `FromIterator` for `DVector`. check-in: b19701a2cb user: fifr tags: trunk | |
|
2016-09-30
| ||
| 19:42 | FirstOrderProblem returns primal information along minorants. check-in: 9a0f6816f5 user: fifr tags: trunk | |
| 19:14 | cpx: Update quadratic term when aggregating minorants. check-in: 3386c2a253 user: fifr tags: trunk | |
Changes
Changes to examples/quadratic.rs.
| ︙ | ︙ | |||
39 40 41 42 43 44 45 |
c : 3.0,
}
}
}
impl<'a> FirstOrderProblem<'a> for QuadraticProblem {
type Error = io::Error;
| > | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
c : 3.0,
}
}
}
impl<'a> FirstOrderProblem<'a> for QuadraticProblem {
type Error = io::Error;
type Primal = ();
type EvalResult = SimpleEvaluation<()>;
fn num_variables(&self) -> usize { 2 }
#[allow(unused_variables)]
fn evaluate(&'a mut self, fidx : usize, x : &DVector, nullstep_bnd : Real, relprec : Real) -> Result<Self::EvalResult, Self::Error> {
assert!(fidx == 0);
let mut objective = self.c;
|
| ︙ | ︙ | |||
64 65 66 67 68 69 70 |
debug!("Evaluation at {}", x);
debug!(" objective={}", objective);
debug!(" subgradient={}", g);
Ok(SimpleEvaluation {
objective: objective,
minorants: vec![
| | | | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
debug!("Evaluation at {}", x);
debug!(" objective={}", objective);
debug!(" subgradient={}", g);
Ok(SimpleEvaluation {
objective: objective,
minorants: vec![
(Minorant {
constant: objective,
linear: g,
},())
],
})
}
}
fn main() {
env_logger::init().unwrap();
|
| ︙ | ︙ |
Changes to src/firstorderproblem.rs.
| ︙ | ︙ | |||
27 28 29 30 31 32 33 | * * An evaluation returns the function value at the point of evaluation * and one or more subgradients. * * The subgradients (linear minorants) can be obtained by iterating over the result. The * subgradients are centered around the point of evaluation. */ | | | | | | | | | > > > | | 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 |
*
* An evaluation returns the function value at the point of evaluation
* and one or more subgradients.
*
* The subgradients (linear minorants) can be obtained by iterating over the result. The
* subgradients are centered around the point of evaluation.
*/
pub trait Evaluation<P> : IntoIterator<Item=(Minorant, P)> {
/// Return the function value at the point of evaluation.
fn objective(&self) -> Real;
}
/**
* Simple standard evaluation result.
*
* This result consists of the function value and a list of one or
* more minorants and associated primal information.
*/
pub struct SimpleEvaluation<P> {
pub objective : Real,
pub minorants : Vec<(Minorant, P)>,
}
impl<P> IntoIterator for SimpleEvaluation<P> {
type Item = (Minorant, P);
type IntoIter = IntoIter<(Minorant, P)>;
fn into_iter(self) -> Self::IntoIter {
self.minorants.into_iter()
}
}
impl<P> Evaluation<P> for SimpleEvaluation<P> {
fn objective(&self) -> Real {
self.objective
}
}
/**
* Trait for implementing a first-order problem description.
*
*/
pub trait FirstOrderProblem<'a> {
/// Custom error type for evaluating this oracle.
type Error : error::Error + 'static;
/// The primal information associated with a minorant.
type Primal;
/// Custom evaluation result value.
type EvalResult : Evaluation<Self::Primal>;
/// Return the number of variables.
fn num_variables(&self) -> usize;
/**
* Return the lower bounds on the variables.
*
|
| ︙ | ︙ |
Changes to src/mcf/problem.rs.
| ︙ | ︙ | |||
170 171 172 173 174 175 176 |
})
}
}
impl<'a> FirstOrderProblem<'a> for MMCFProblem {
type Error = Error;
| > > | | 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
})
}
}
impl<'a> FirstOrderProblem<'a> for MMCFProblem {
type Error = Error;
type Primal = ();
type EvalResult = SimpleEvaluation<()>;
fn num_variables(&self) -> usize { self.lhs.len() }
fn lower_bounds(&self) -> Option<Vector> {
Some(Vector::new_sparse(self.lhs.len(), &[], &[]))
}
|
| ︙ | ︙ | |||
239 240 241 242 243 244 245 |
for elem in &self.lhs[i][fidx] {
subg[i] -= elem.val * sol[elem.ind];
}
}
Ok(SimpleEvaluation {
objective: objective,
| | | | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
for elem in &self.lhs[i][fidx] {
subg[i] -= elem.val * sol[elem.ind];
}
}
Ok(SimpleEvaluation {
objective: objective,
minorants: vec![(Minorant { constant: objective, linear: subg }, ())],
})
} else {
let mut objective = self.rhsval;
let mut sols = Vec::with_capacity(self.nets.len());
for i in 0..self.nets.len() {
objective -= try!(self.nets[i].objective());
sols.push(try!(self.nets[i].get_solution()));
}
let mut subg = self.rhs.clone();
for i in 0..self.lhs.len() {
for (fidx, flhs) in self.lhs[i].iter().enumerate() {
for elem in flhs {
subg[i] -= elem.val * sols[fidx][elem.ind];
}
}
}
Ok(SimpleEvaluation {
objective: objective,
minorants: vec![(Minorant { constant: objective, linear: subg }, ())],
})
}
}
}
|
Changes to src/solver.rs.
| ︙ | ︙ | |||
543 544 545 546 547 548 549 |
Ok(r) => r,
Err(err) => return Err(Error::Eval(Box::new(err))),
};
self.cur_vals[i] = result.objective();
self.cur_val += self.cur_vals[i];
let mut minorants = result.into_iter();
| | | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 |
Ok(r) => r,
Err(err) => return Err(Error::Eval(Box::new(err))),
};
self.cur_vals[i] = result.objective();
self.cur_val += self.cur_vals[i];
let mut minorants = result.into_iter();
if let Some((minorant, _)) = minorants.next() {
self.cur_mods[i] = minorant.constant;
self.cur_mod += self.cur_mods[i];
self.minorants[i].push(MinorantInfo {
index: try!(self.master.add_minorant(i, minorant)),
multiplier: 0,
});
} else {
|
| ︙ | ︙ | |||
672 673 674 675 676 677 678 |
Err(err) => return Err(Error::Eval(Box::new(err))),
};
let fun_ub = result.objective();
let mut minorants = result.into_iter();
let mut nxt_minorant = match minorants.next() {
| | | 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 |
Err(err) => return Err(Error::Eval(Box::new(err))),
};
let fun_ub = result.objective();
let mut minorants = result.into_iter();
let mut nxt_minorant = match minorants.next() {
Some((m, _)) => m,
None => return Err(Error::NoMinorant)
};
let fun_lb = nxt_minorant.constant;
nxt_lb += fun_lb;
nxt_ub += fun_ub;
self.nxt_vals[fidx] = fun_ub;
|
| ︙ | ︙ |