RsBundle  Diff

Differences From Artifact [6402964398]:

  • File src/solver.rs — part of check-in [29f93aefac] at 2016-09-28 15:52:38 on branch trunk — Add `MinorantIndex` as reference to minorants to master problem. (user: fifr size: 23723)

To Artifact [28a03735c5]:

  • File src/solver.rs — part of check-in [e671068275] at 2016-09-28 16:31:19 on branch trunk — solver: Handle minorants correctly. (user: fifr size: 24108)

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(&current_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(&current_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;
        }