78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
}
/// The value of a variable is outside its bounds.
ViolatedBounds(lower: Real, upper: Real, value: Real) {
description("violated bounds")
display("Violated bounds, lower:{} upper:{} value:{}", lower, upper, value)
}
}
}
/// Result type for solvers.
pub type Result<T> = result::Result<T, Error>;
|
>
>
>
>
>
>
|
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
}
/// The value of a variable is outside its bounds.
ViolatedBounds(lower: Real, upper: Real, value: Real) {
description("violated bounds")
display("Violated bounds, lower:{} upper:{} value:{}", lower, upper, value)
}
/// The variable index is out of bounds.
InvalidVariable(index: usize, nvars: usize) {
description("invalid variable")
display("Variable index out of bounds, got:{} must be < {}", index, nvars)
}
}
}
/// Result type for solvers.
pub type Result<T> = result::Result<T, Error>;
|
362
363
364
365
366
367
368
369
370
371
372
373
374
375
|
pub params: SolverParams,
/// Termination predicate.
pub terminator: Box<Terminator>,
/// Weighter heuristic.
pub weighter: Box<Weighter>,
/// Current center of stability.
cur_y: DVector,
/// Function value in current point.
cur_val: Real,
|
>
>
>
|
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
|
pub params: SolverParams,
/// Termination predicate.
pub terminator: Box<Terminator>,
/// Weighter heuristic.
pub weighter: Box<Weighter>,
/// Lower and upper bounds of all variables.
bounds: Vec<(Real, Real)>,
/// Current center of stability.
cur_y: DVector,
/// Function value in current point.
cur_val: Real,
|
455
456
457
458
459
460
461
462
463
464
465
466
467
468
|
*/
pub fn new_params(problem: P, params: SolverParams) -> Result<Solver<P, Pr, E>> {
Ok(Solver {
problem: problem,
params: params,
terminator: Box::new(StandardTerminator { termination_precision: 1e-3 }),
weighter: Box::new(HKWeighter::new()),
cur_y: dvec![],
cur_val: 0.0,
cur_mod: 0.0,
cur_vals: dvec![],
cur_mods: dvec![],
cur_valid: false,
nxt_d: dvec![],
|
>
|
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
|
*/
pub fn new_params(problem: P, params: SolverParams) -> Result<Solver<P, Pr, E>> {
Ok(Solver {
problem: problem,
params: params,
terminator: Box::new(StandardTerminator { termination_precision: 1e-3 }),
weighter: Box::new(HKWeighter::new()),
bounds: vec![],
cur_y: dvec![],
cur_val: 0.0,
cur_mod: 0.0,
cur_vals: dvec![],
cur_mods: dvec![],
cur_valid: false,
nxt_d: dvec![],
|
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
|
if self.cur_y.len() != self.problem.num_variables() {
self.cur_valid = false;
self.cur_y.init0(self.problem.num_variables());
}
let lb = self.problem.lower_bounds();
let ub = self.problem.upper_bounds();
for i in 0..self.cur_y.len() {
let lb_i = lb.as_ref().map(|x| x[i]).unwrap_or(NEG_INFINITY);
let ub_i = ub.as_ref().map(|x| x[i]).unwrap_or(INFINITY);
if lb_i > ub_i {
return Err(Error::InvalidBounds(lb_i, ub_i));
}
if self.cur_y[i] < lb_i {
self.cur_valid = false;
self.cur_y[i] = lb_i;
} else if self.cur_y[i] > ub_i {
self.cur_valid = false;
self.cur_y[i] = ub_i;
}
}
let m = self.problem.num_subproblems();
self.cur_vals.init0(m);
self.cur_mods.init0(m);
self.nxt_vals.init0(m);
self.nxt_mods.init0(m);
|
>
>
>
|
525
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
554
|
if self.cur_y.len() != self.problem.num_variables() {
self.cur_valid = false;
self.cur_y.init0(self.problem.num_variables());
}
let lb = self.problem.lower_bounds();
let ub = self.problem.upper_bounds();
self.bounds.clear();
self.bounds.reserve(self.cur_y.len());
for i in 0..self.cur_y.len() {
let lb_i = lb.as_ref().map(|x| x[i]).unwrap_or(NEG_INFINITY);
let ub_i = ub.as_ref().map(|x| x[i]).unwrap_or(INFINITY);
if lb_i > ub_i {
return Err(Error::InvalidBounds(lb_i, ub_i));
}
if self.cur_y[i] < lb_i {
self.cur_valid = false;
self.cur_y[i] = lb_i;
} else if self.cur_y[i] > ub_i {
self.cur_valid = false;
self.cur_y[i] = ub_i;
}
self.bounds.push((lb_i, ub_i));
}
let m = self.problem.num_subproblems();
self.cur_vals.init0(m);
self.cur_mods.init0(m);
self.nxt_vals.init0(m);
self.nxt_mods.init0(m);
|
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
|
let value = if lower > 0.0 {
lower
} else if upper < 0.0 {
upper
} else {
0.0
};
newvars.push((lower - value, upper - value, value));
}
Update::AddVariableValue { lower, upper, value } => {
if lower > upper {
return Err(Error::InvalidBounds(lower, upper));
}
if value < lower || value > upper {
return Err(Error::ViolatedBounds(lower, upper, value));
}
newvars.push((lower - value, upper - value, value));
}
}
}
if !newvars.is_empty() {
let mut problem = &mut self.problem;
let minorants = &self.minorants;
self.master.add_vars(&newvars.iter().map(|v| (v.0, v.1)).collect::<Vec<_>>(),
&mut move |fidx, minidx, vars| {
problem.extend_subgradient(minorants[fidx][minidx].primal.as_ref().unwrap(), vars)
.map(DVector)
.unwrap()
});
let newn = self.cur_y.len() + newvars.len();
self.cur_y.extend(newvars.iter().map(|v| v.2));
self.nxt_d.resize(newn, 0.0);
self.nxt_y.extend(newvars.iter().map(|v| v.2));
Ok(true)
} else {
Ok(false)
}
}
/// Return the current aggregated primal information for a subproblem.
|
|
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
|
<
|
>
|
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
|
let value = if lower > 0.0 {
lower
} else if upper < 0.0 {
upper
} else {
0.0
};
newvars.push((None, lower - value, upper - value, value));
}
Update::AddVariableValue { lower, upper, value } => {
if lower > upper {
return Err(Error::InvalidBounds(lower, upper));
}
if value < lower || value > upper {
return Err(Error::ViolatedBounds(lower, upper, value));
}
newvars.push((None, lower - value, upper - value, value));
}
Update::MoveVariable { index, value } => {
if index >= self.bounds.len() {
return Err(Error::InvalidVariable(index, self.bounds.len()));
}
let (lower, upper) = self.bounds[index];
if value < lower || value > upper {
return Err(Error::ViolatedBounds(lower, upper, value));
}
newvars.push((Some(index), lower - value, upper - value, value));
unimplemented!()
}
}
}
if !newvars.is_empty() {
let mut problem = &mut self.problem;
let minorants = &self.minorants;
self.master.add_vars(&newvars.iter().map(|v| (v.1, v.2)).collect::<Vec<_>>(),
&mut move |fidx, minidx, vars| {
problem.extend_subgradient(minorants[fidx][minidx].primal.as_ref().unwrap(), vars)
.map(DVector)
.unwrap()
});
// modify moved variables
for (index, val) in newvars.iter().filter_map(|v| v.0.map(|i| (i, v.3))) {
self.cur_y[index] = val;
self.nxt_y[index] = val;
self.nxt_d[index] = 0.0;
}
// add new variables
self.cur_y.extend(newvars.iter().filter(|v| v.0.is_none()).map(|v| v.3));
self.nxt_y.extend(newvars.iter().filter(|v| v.0.is_none()).map(|v| v.3));
self.nxt_d.resize(self.nxt_y.len(), 0.0);
Ok(true)
} else {
Ok(false)
}
}
/// Return the current aggregated primal information for a subproblem.
|