Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add `IterationInfo` to update state. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
8d6b8944913e2d44a03f0d7694fc1b05 |
| User & Date: | fifr 2016-10-10 14:43:45.406 |
Context
|
2016-10-10
| ||
| 20:33 | solver: Add `cur_y` and `nxt_y` fields to `UpdateState`. check-in: 2b281a925b user: fifr tags: trunk | |
| 14:43 | Add `IterationInfo` to update state. check-in: 8d6b894491 user: fifr tags: trunk | |
|
2016-10-07
| ||
| 19:11 | Add `Vector::scaled`. check-in: 56a92dca28 user: fifr tags: trunk | |
Changes
Changes to src/lib.rs.
| ︙ | ︙ | |||
43 44 45 46 47 48 49 |
pub mod minorant;
pub use minorant::Minorant;
pub mod firstorderproblem;
pub use firstorderproblem::{Evaluation, SimpleEvaluation, Update, FirstOrderProblem};
pub mod solver;
| | > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
pub mod minorant;
pub use minorant::Minorant;
pub mod firstorderproblem;
pub use firstorderproblem::{Evaluation, SimpleEvaluation, Update, FirstOrderProblem};
pub mod solver;
pub use solver::{Solver, SolverParams, BundleState, Terminator, StandardTerminator,
Weighter, Step, UpdateState, IterationInfo};
mod hkweighter;
pub use hkweighter::HKWeighter;
mod master;
pub mod mcf;
|
Changes to src/solver.rs.
| ︙ | ︙ | |||
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
/// The minorant's index in the master problem
index: usize,
/// Current multiplier.
multiplier: Real,
/// Primal associated with this minorant.
primal: Option<Pr>,
}
/// State information for the update callback.
pub struct UpdateState<'a, Pr:'a> {
/// Current model minorants.
minorants: &'a [Vec<MinorantInfo<Pr>>],
/// The last step type.
pub step: Step,
}
impl<'a, Pr:'a> UpdateState<'a, Pr> {
pub fn aggregated_primals(&self, subproblem : usize) -> Vec<(Real, &Pr)> {
self.minorants[subproblem].iter().map(|m| {
(m.multiplier, m.primal.as_ref().unwrap())
}).collect()
| > > > > > > > > > > > | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
/// The minorant's index in the master problem
index: usize,
/// Current multiplier.
multiplier: Real,
/// Primal associated with this minorant.
primal: Option<Pr>,
}
/// Information about the last iteration.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum IterationInfo {
NewMinorantTooHigh{ new: Real, old: Real },
UpperBoundNullStep,
ShallowCut,
}
/// State information for the update callback.
pub struct UpdateState<'a, Pr:'a> {
/// Current model minorants.
minorants: &'a [Vec<MinorantInfo<Pr>>],
/// The last step type.
pub step: Step,
/// Iteration information.
pub iteration_info: &'a [IterationInfo],
}
impl<'a, Pr:'a> UpdateState<'a, Pr> {
pub fn aggregated_primals(&self, subproblem : usize) -> Vec<(Real, &Pr)> {
self.minorants[subproblem].iter().map(|m| {
(m.multiplier, m.primal.as_ref().unwrap())
}).collect()
|
| ︙ | ︙ | |||
392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
start_time : Instant,
/// The master problem.
master: Box<MasterProblem<MinorantIndex=usize>>,
/// The active minorant indices for each subproblem.
minorants: Vec<Vec<MinorantInfo<Pr>>>,
}
impl<P, Pr, E> Solver<P, Pr, E>
where P : for <'a> FirstOrderProblem<'a, Primal=Pr,EvalResult=E>,
E : Evaluation<Pr>
{
| > > > | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 |
start_time : Instant,
/// The master problem.
master: Box<MasterProblem<MinorantIndex=usize>>,
/// The active minorant indices for each subproblem.
minorants: Vec<Vec<MinorantInfo<Pr>>>,
/// Accumulated information about the last iteration.
iterinfos: Vec<IterationInfo>,
}
impl<P, Pr, E> Solver<P, Pr, E>
where P : for <'a> FirstOrderProblem<'a, Primal=Pr,EvalResult=E>,
E : Evaluation<Pr>
{
|
| ︙ | ︙ | |||
436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
cnt_null: 0,
start_time: Instant::now(),
master: match BoxedMasterProblem::<MinimalMaster>::new() {
Ok(master) => Box::new(master),
Err(err) => return Err(Error::Master(Box::new(err))),
},
minorants: vec![],
})
}
/// A new solver with default parameter.
pub fn new(problem : P) -> Result<Solver<P,Pr,E>> {
Solver::new_params(problem, SolverParams::default())
}
| > | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
cnt_null: 0,
start_time: Instant::now(),
master: match BoxedMasterProblem::<MinimalMaster>::new() {
Ok(master) => Box::new(master),
Err(err) => return Err(Error::Master(Box::new(err))),
},
minorants: vec![],
iterinfos: vec![],
})
}
/// A new solver with default parameter.
pub fn new(problem : P) -> Result<Solver<P,Pr,E>> {
Solver::new_params(problem, SolverParams::default())
}
|
| ︙ | ︙ | |||
516 517 518 519 520 521 522 |
}
/// Called to update the problem.
///
/// Calling this function typically triggers the problem to
/// separate new constraints depending on the current solution.
fn update_problem(&mut self, term: Step) -> Result<bool> {
| | | 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
}
/// Called to update the problem.
///
/// Calling this function typically triggers the problem to
/// separate new constraints depending on the current solution.
fn update_problem(&mut self, term: Step) -> Result<bool> {
let state = UpdateState {minorants: &self.minorants, step: term, iteration_info: &self.iterinfos};
let updates = match self.problem.update(&state) {
Ok(updates) => updates,
Err(err) => return Err(Error::Update(Box::new(err))),
};
let mut newvars = Vec::with_capacity(updates.len());
for u in updates {
|
| ︙ | ︙ | |||
734 735 736 737 738 739 740 |
let new_weight = self.weighter.weight(¤t_state!(self, Step::Null), &self.params);
self.master.set_weight(new_weight);
self.cnt_null += 1;
debug!("Null Step");
}
/// Perform one bundle iteration.
| | > | | 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 |
let new_weight = self.weighter.weight(¤t_state!(self, Step::Null), &self.params);
self.master.set_weight(new_weight);
self.cnt_null += 1;
debug!("Null Step");
}
/// Perform one bundle iteration.
pub fn step(&mut self) -> Result<Step> {
self.iterinfos.clear();
if !self.cur_valid {
// current point needs new evaluation
try!(self.init_master());
}
try!(self.solve_model());
if self.terminator.terminate(¤t_state!(self, Step::Term), &self.params) {
|
| ︙ | ︙ | |||
793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 |
primal: Some(nxt_primal),
});
}
if self.new_cutval > self.cur_val + 1e-3 {
warn!("New minorant has higher value in center new:{} old:{}", self.new_cutval, self.cur_val);
self.cur_val = self.new_cutval;
}
self.nxt_val = nxt_ub;
// check for potential problems with relative precision of all kinds
if nxt_lb <= descent_bnd {
// lower bound gives descent step
if nxt_ub > descent_bnd {
// upper bound will produce null-step
if self.cur_val - nxt_lb > (self.cur_val - self.nxt_mod) * self.params.nullstep_factor.max(0.5) {
| > | > > | 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 |
primal: Some(nxt_primal),
});
}
if self.new_cutval > self.cur_val + 1e-3 {
warn!("New minorant has higher value in center new:{} old:{}", self.new_cutval, self.cur_val);
self.cur_val = self.new_cutval;
self.iterinfos.push(IterationInfo::NewMinorantTooHigh{new: self.new_cutval, old: self.cur_val});
}
self.nxt_val = nxt_ub;
// check for potential problems with relative precision of all kinds
if nxt_lb <= descent_bnd {
// lower bound gives descent step
if nxt_ub > descent_bnd {
// upper bound will produce null-step
if self.cur_val - nxt_lb > (self.cur_val - self.nxt_mod) * self.params.nullstep_factor.max(0.5) {
warn!("Relative precision of returned objective interval enforces null-step.");
self.iterinfos.push(IterationInfo::UpperBoundNullStep);
}
}
} else {
// lower bound gives already a null step
if self.cur_val - nxt_lb > 0.8 * (self.cur_val - self.nxt_mod) {
// subgradient won't yield much improvement
warn!("Shallow cut (subgradient won't yield much improvement)");
self.iterinfos.push(IterationInfo::ShallowCut);
}
}
debug!("Step");
debug!(" cur_val ={}", self.cur_val);
debug!(" nxt_mod ={}", self.nxt_mod);
debug!(" nxt_ub ={}", self.nxt_val);
|
| ︙ | ︙ |