| ︙ | | |
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
-
+
|
#[derive(Debug)]
pub enum SolverError<E> {
/// An error occurred during oracle evaluation.
Evaluation(E),
/// An error occurred during oracle update.
Update(E),
/// An error has been raised by the master problem.
Master(MasterProblemError<E>),
Master(MasterProblemError),
/// The oracle did not return a minorant.
NoMinorant,
/// The dimension of some data is wrong.
Dimension,
/// Some parameter has an invalid value.
Parameter(ParameterError),
/// The lower bound of a variable is larger than the upper bound.
|
| ︙ | | |
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
-
+
-
-
-
-
+
-
-
+
+
|
write!(fmt, "Variable index out of bounds, got:{} must be < {}", index, nvars)
}
IterationLimit { limit } => write!(fmt, "The iteration limit of {} has been reached.", limit),
}
}
}
impl<E: Error> Error for SolverError<E>
impl<E: Error + 'static> Error for SolverError<E> {
where
E: 'static,
{
fn cause(&self) -> Option<&Error> {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
SolverError::Evaluation(err) => Some(err),
SolverError::Update(err) => Some(err),
SolverError::Master(err) => Some(err),
_ => None,
}
}
}
impl<E> From<ParameterError> for SolverError<E> {
fn from(err: ParameterError) -> SolverError<E> {
SolverError::Parameter(err)
}
}
impl<E> From<MasterProblemError<E>> for SolverError<E> {
fn from(err: MasterProblemError<E>) -> SolverError<E> {
impl<E> From<MasterProblemError> for SolverError<E> {
fn from(err: MasterProblemError) -> SolverError<E> {
SolverError::Master(err)
}
}
/**
* The current state of the bundle method.
*
|
| ︙ | | |
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
|
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
|
-
+
-
+
-
+
|
/// This is the last primal generated by the oracle.
pub fn last_primal(&self, fidx: usize) -> Option<&Pr> {
self.minorants[fidx].last().and_then(|m| m.primal.as_ref())
}
}
/// The default bundle solver with general master problem.
pub type DefaultSolver<P> = Solver<P, BoxedMasterProblem<CplexMaster<<P as FirstOrderProblem>::Err>>>;
pub type DefaultSolver<P> = Solver<P, BoxedMasterProblem<CplexMaster>>;
/// A bundle solver with a minimal cutting plane model.
pub type NoBundleSolver<P> = Solver<P, BoxedMasterProblem<MinimalMaster<<P as FirstOrderProblem>::Err>>>;
pub type NoBundleSolver<P> = Solver<P, BoxedMasterProblem<MinimalMaster>>;
/**
* Implementation of a bundle method.
*/
pub struct Solver<P, M = BoxedMasterProblem<CplexMaster<<P as FirstOrderProblem>::Err>>>
pub struct Solver<P, M = BoxedMasterProblem<CplexMaster>>
where
P: FirstOrderProblem,
{
/// The first order problem description.
problem: P,
/// The solver parameter.
|
| ︙ | | |
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
|
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
|
-
-
+
+
|
/// Accumulated information about the last iteration.
iterinfos: Vec<IterationInfo>,
}
impl<P, M> Solver<P, M>
where
P: FirstOrderProblem,
P::Err: Into<Box<dyn Error + Send + Sync>> + 'static,
M: MasterProblem<MinorantIndex = usize, SubgradientExtensionErr = P::Err>,
P::Err: Into<Box<std::error::Error + Send + Sync + 'static>>,
M: MasterProblem<MinorantIndex = usize>,
{
/**
* Create a new solver for the given problem.
*
* Note that the solver owns the problem, so you cannot use the
* same problem description elsewhere as long as it is assigned to
* the solver. However, it is possible to get a reference to the
|
| ︙ | | |
719
720
721
722
723
724
725
726
727
728
729
730
731
732
|
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
|
+
|
let minorants = &self.minorants;
self.master.add_vars(
&newvars.iter().map(|v| (v.0, v.1, v.2)).collect::<Vec<_>>(),
&mut |fidx, minidx, vars| {
problem
.extend_subgradient(minorants[fidx][minidx].primal.as_ref().unwrap(), vars)
.map(DVector)
.map_err(|e| e.into())
},
)?;
// 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;
|
| ︙ | | |