| ︙ | | | ︙ | |
362
363
364
365
366
367
368
369
370
371
372
373
374
375
|
*
* This is actually the time of the last call to `Solver::init`.
*/
start_time : Instant,
/// The master problem.
master: Box<MasterProblem<MinorantIndex=usize>>,
}
impl<P> Solver<P>
where P : for <'a> FirstOrderProblem<'a>
{
/**
|
>
>
>
|
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
|
*
* This is actually the time of the last call to `Solver::init`.
*/
start_time : Instant,
/// The master problem.
master: Box<MasterProblem<MinorantIndex=usize>>,
/// The active minorant indices for each subproblem.
minorants: Vec<Vec<usize>>,
}
impl<P> Solver<P>
where P : for <'a> FirstOrderProblem<'a>
{
/**
|
| ︙ | | | ︙ | |
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
|
expected_progress: 0.0,
cnt_descent: 0,
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))),
}
})
}
/// A new solver with default parameter.
pub fn new(problem : P) -> Result<Solver<P>> {
Solver::new_params(problem, SolverParams::default())
}
|
|
>
|
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
|
expected_progress: 0.0,
cnt_descent: 0,
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>> {
Solver::new_params(problem, SolverParams::default())
}
|
| ︙ | | | ︙ | |
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
|
}
}
self.master.set_num_subproblems(m);
self.master.set_vars(self.problem.num_variables(), lb, ub);
self.master.set_max_updates(self.params.max_updates);
self.cur_val = 0.0;
for i in 0..m {
let result = match self.problem.evaluate(i, &self.cur_y, INFINITY, 0.0) {
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];
try!(self.master.add_minorant(i, minorant));
} else {
return Err(Error::NoMinorant);
}
}
self.cur_valid = true;
self.master.set_weight(1.0);
|
>
>
|
|
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
|
}
}
self.master.set_num_subproblems(m);
self.master.set_vars(self.problem.num_variables(), lb, ub);
self.master.set_max_updates(self.params.max_updates);
self.minorants = vec![vec![]; m];
self.cur_val = 0.0;
for i in 0..m {
let result = match self.problem.evaluate(i, &self.cur_y, INFINITY, 0.0) {
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(try!(self.master.add_minorant(i, minorant)));
} else {
return Err(Error::NoMinorant);
}
}
self.cur_valid = true;
self.master.set_weight(1.0);
|
| ︙ | | | ︙ | |
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
|
debug!(" nxt_mod ={}", self.nxt_mod);
debug!(" expected={}", self.expected_progress);
Ok(())
}
/// Reduce size of bundle.
fn compress_bundle(&mut self) {
for i in 0..self.problem.num_subproblems() {
let n = self.master.num_minorants(i);
if n >= self.params.max_bundle_size {
self.master.aggregate(0, &(self.params.max_bundle_size-2..n).collect::<Vec<_>>());
}
}
}
/// Perform a descent step.
fn descent_step(&mut self) {
let new_weight = self.weighter.weight(¤t_state!(self, Step::Descent), &self.params);
self.master.set_weight(new_weight);
self.cnt_descent += 1;
|
|
|
>
>
>
|
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
|
debug!(" nxt_mod ={}", self.nxt_mod);
debug!(" expected={}", self.expected_progress);
Ok(())
}
/// Reduce size of bundle.
fn compress_bundle(&mut self) -> Result<()> {
for i in 0..self.problem.num_subproblems() {
let n = self.master.num_minorants(i);
if n >= self.params.max_bundle_size {
let mut remove = self.minorants[i].split_off(self.params.max_bundle_size-2);
swap(&mut remove, &mut self.minorants[i]);
self.minorants[i].push(try!(self.master.aggregate(i, &remove)));
}
}
Ok(())
}
/// Perform a descent step.
fn descent_step(&mut self) {
let new_weight = self.weighter.weight(¤t_state!(self, Step::Descent), &self.params);
self.master.set_weight(new_weight);
self.cnt_descent += 1;
|
| ︙ | | | ︙ | |
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
|
}
let m = self.problem.num_subproblems();
let descent_bnd = self.get_descent_bound();
let nullstep_bnd = if m == 1 { self.get_nullstep_bound() } else { INFINITY };
let relprec = if m == 1 { self.get_relative_precision() } else { 0.0 };
self.compress_bundle();
let mut nxt_lb = 0.0;
let mut nxt_ub = 0.0;
for fidx in 0..self.problem.num_subproblems() {
let result = match self.problem.evaluate(fidx, &self.nxt_y, nullstep_bnd, relprec) {
Ok(r) => r,
Err(err) => return Err(Error::Eval(Box::new(err))),
|
|
|
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
|
}
let m = self.problem.num_subproblems();
let descent_bnd = self.get_descent_bound();
let nullstep_bnd = if m == 1 { self.get_nullstep_bound() } else { INFINITY };
let relprec = if m == 1 { self.get_relative_precision() } else { 0.0 };
try!(self.compress_bundle());
let mut nxt_lb = 0.0;
let mut nxt_ub = 0.0;
for fidx in 0..self.problem.num_subproblems() {
let result = match self.problem.evaluate(fidx, &self.nxt_y, nullstep_bnd, relprec) {
Ok(r) => r,
Err(err) => return Err(Error::Eval(Box::new(err))),
|
| ︙ | | | ︙ | |
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
|
nxt_lb += fun_lb;
nxt_ub += fun_ub;
self.nxt_vals[fidx] = fun_ub;
// move center of minorant to cur_y
nxt_minorant.move_center(-1.0, &self.nxt_d);
self.new_cutval += nxt_minorant.constant;
try!(self.master.add_minorant(fidx, nxt_minorant));
}
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;
}
|
|
|
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
|
nxt_lb += fun_lb;
nxt_ub += fun_ub;
self.nxt_vals[fidx] = fun_ub;
// move center of minorant to cur_y
nxt_minorant.move_center(-1.0, &self.nxt_d);
self.new_cutval += nxt_minorant.constant;
self.minorants[fidx].push(try!(self.master.add_minorant(fidx, nxt_minorant)));
}
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;
}
|
| ︙ | | | ︙ | |