Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Move additional requirements to basic traits. This includes bounds on `Send` and `'static` so that master problems and function oracles can always be used in threads. The requirements have always been there as additional bounds for the solvers, but it is easier (and more descriptive) to state them in the basic traits. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | async |
| Files: | files | file ages | folders |
| SHA1: |
2c9472f892c2c7183e2854812dddcad6 |
| User & Date: | fifr 2019-07-22 11:50:12.258 |
Context
|
2019-07-22
| ||
| 11:52 | Add explicit `dyn` where appropriate check-in: 2cb2bf4cbc user: fifr tags: async | |
| 11:50 | Move additional requirements to basic traits. check-in: 2c9472f892 user: fifr tags: async | |
| 09:48 | parallel: require `Primal` to be sendable check-in: b6db39804c user: fifr tags: async | |
Changes
Changes to src/master/base.rs.
| ︙ | ︙ | |||
19 20 21 22 23 24 25 |
use std::error::Error;
use std::result;
/// Callback for subgradient extensions.
pub type SubgradientExtension<'a, I> =
FnMut(usize, I, &[usize]) -> result::Result<DVector, Box<dyn Error + Send + Sync + 'static>> + 'a;
| > > > > > > | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
use std::error::Error;
use std::result;
/// Callback for subgradient extensions.
pub type SubgradientExtension<'a, I> =
FnMut(usize, I, &[usize]) -> result::Result<DVector, Box<dyn Error + Send + Sync + 'static>> + 'a;
/// Trait for master problems of a proximal bundle methods.
///
/// Note that solvers are allowed to create multiple master problems potentially
/// running them in different threads. Because of this they must implement `Send
/// + 'static`, i.e. they must be quite self-contained and independent from
/// everything else.
pub trait MasterProblem: Send + 'static {
/// Unique index for a minorant.
type MinorantIndex: Copy + Eq;
/// The error returned by the master problem.
type Err: Error + Send + Sync;
/// Create a new master problem.
fn new() -> Result<Self, Self::Err>
where
Self: Sized;
/// Set the number of subproblems.
|
| ︙ | ︙ | |||
115 116 117 118 119 120 121 |
}
/// A builder for creating a master problem solvers.
pub trait Builder {
/// The master problem to be build.
type MasterProblem: MasterProblem;
| < < < | | 121 122 123 124 125 126 127 128 129 130 |
}
/// A builder for creating a master problem solvers.
pub trait Builder {
/// The master problem to be build.
type MasterProblem: MasterProblem;
/// Create a new master problem.
fn build(&mut self) -> Result<Self::MasterProblem, <Self::MasterProblem as MasterProblem>::Err>;
}
|
Changes to src/master/boxed.rs.
| ︙ | ︙ | |||
370 371 372 373 374 375 376 |
impl<B> master::Builder for Builder<B>
where
B: master::unconstrained::Builder,
B::MasterProblem: UnconstrainedMasterProblem,
{
type MasterProblem = BoxedMasterProblem<B::MasterProblem>;
| < < | | 370 371 372 373 374 375 376 377 378 379 380 |
impl<B> master::Builder for Builder<B>
where
B: master::unconstrained::Builder,
B::MasterProblem: UnconstrainedMasterProblem,
{
type MasterProblem = BoxedMasterProblem<B::MasterProblem>;
fn build(&mut self) -> Result<Self::MasterProblem, <Self::MasterProblem as MasterProblem>::Err> {
self.0.build().map(BoxedMasterProblem::with_master)
}
}
|
Changes to src/master/cpx.rs.
| ︙ | ︙ | |||
548 549 550 551 552 553 554 |
#[derive(Default)]
pub struct Builder;
impl unconstrained::Builder for Builder {
type MasterProblem = CplexMaster;
| < < | 548 549 550 551 552 553 554 555 556 557 558 |
#[derive(Default)]
pub struct Builder;
impl unconstrained::Builder for Builder {
type MasterProblem = CplexMaster;
fn build(&mut self) -> Result<CplexMaster> {
CplexMaster::new()
}
}
|
Changes to src/master/minimal.rs.
| ︙ | ︙ | |||
245 246 247 248 249 250 251 |
}
pub struct Builder;
impl unconstrained::Builder for Builder {
type MasterProblem = MinimalMaster;
| < < | | 245 246 247 248 249 250 251 252 253 254 255 |
}
pub struct Builder;
impl unconstrained::Builder for Builder {
type MasterProblem = MinimalMaster;
fn build(&mut self) -> Result<MinimalMaster, MinimalMasterError> {
MinimalMaster::new()
}
}
|
Changes to src/master/unconstrained.rs.
| ︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// along with this program. If not, see <http://www.gnu.org/licenses/>
//
use crate::{DVector, Minorant, Real};
use super::SubgradientExtension;
/**
* Trait for master problems without box constraints.
*
* Implementors of this trait are supposed to solve quadratic
* optimization problems of the form
*
* \\[ \min \left\\{ \hat{f}(d) + \frac{u}{2} \\| d \\|\^2 \colon
| > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// along with this program. If not, see <http://www.gnu.org/licenses/>
//
use crate::{DVector, Minorant, Real};
use super::SubgradientExtension;
use std::error::Error;
/**
* Trait for master problems without box constraints.
*
* Implementors of this trait are supposed to solve quadratic
* optimization problems of the form
*
* \\[ \min \left\\{ \hat{f}(d) + \frac{u}{2} \\| d \\|\^2 \colon
|
| ︙ | ︙ | |||
38 39 40 41 42 43 44 |
* \alpha_i = 1 \right\\}$. Note, the unconstrained solver is expected
* to compute *dual* optimal solutions, i.e. the solver must compute
* optimal coefficients $\bar{\alpha}$ for the dual problem
*
* \\[ \max_{\alpha \in \Delta} \min_{d \in \mathbb{R}\^n}
* \sum_{i=1}\^k \alpha_i \ell_i(d) + \frac{u}{2} \\| d \\|\^2. \\]
*/
| | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
* \alpha_i = 1 \right\\}$. Note, the unconstrained solver is expected
* to compute *dual* optimal solutions, i.e. the solver must compute
* optimal coefficients $\bar{\alpha}$ for the dual problem
*
* \\[ \max_{\alpha \in \Delta} \min_{d \in \mathbb{R}\^n}
* \sum_{i=1}\^k \alpha_i \ell_i(d) + \frac{u}{2} \\| d \\|\^2. \\]
*/
pub trait UnconstrainedMasterProblem: Send + 'static {
/// Unique index for a minorant.
type MinorantIndex: Copy + Eq;
/// Error type for this master problem.
type Err: Error + Send + Sync;
/// Return a new instance of the unconstrained master problem.
fn new() -> Result<Self, Self::Err>
where
Self: Sized;
/// Return the number of subproblems.
|
| ︙ | ︙ | |||
116 117 118 119 120 121 122 |
}
/// A builder for creating unconstrained master problem solvers.
pub trait Builder {
/// The master problem to be build.
type MasterProblem: UnconstrainedMasterProblem;
| < < < | | 118 119 120 121 122 123 124 125 126 127 |
}
/// A builder for creating unconstrained master problem solvers.
pub trait Builder {
/// The master problem to be build.
type MasterProblem: UnconstrainedMasterProblem;
/// Create a new master problem.
fn build(&mut self) -> Result<Self::MasterProblem, <Self::MasterProblem as UnconstrainedMasterProblem>::Err>;
}
|
Changes to src/parallel/problem.rs.
| ︙ | ︙ | |||
42 43 44 45 46 47 48 |
/// Trait for implementing a first-order problem description.
///
/// All computations made by an implementation are supposed to
/// be asynchronous. Hence, the interface is slightly different
/// compared with [`crate::FirstOrderProblem`].
pub trait FirstOrderProblem {
/// Error raised by this oracle.
| | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
/// Trait for implementing a first-order problem description.
///
/// All computations made by an implementation are supposed to
/// be asynchronous. Hence, the interface is slightly different
/// compared with [`crate::FirstOrderProblem`].
pub trait FirstOrderProblem {
/// Error raised by this oracle.
type Err;
/// The primal information associated with a minorant.
type Primal: Aggregatable + Send + 'static;
/// Return the number of variables.
fn num_variables(&self) -> usize;
|
| ︙ | ︙ |
Changes to src/parallel/solver.rs.
| ︙ | ︙ | |||
217 218 219 220 221 222 223 |
/// This is actually the time of the last call to `Solver::init`.
start_time: Instant,
}
impl<P, T, W, M> Solver<P, T, W, M>
where
P: FirstOrderProblem,
| < < | < | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
/// This is actually the time of the last call to `Solver::init`.
start_time: Instant,
}
impl<P, T, W, M> Solver<P, T, W, M>
where
P: FirstOrderProblem,
T: Terminator<SolverData> + Default,
W: Weighter<SolverData> + Default,
M: master::Builder + Default,
M::MasterProblem: MasterProblem<MinorantIndex = usize>,
{
/// Create a new parallel bundle solver.
pub fn new(problem: P) -> Self {
Solver {
params: Parameters::default(),
terminator: Default::default(),
weighter: Default::default(),
|
| ︙ | ︙ |
Changes to src/solver.rs.
| ︙ | ︙ | |||
452 453 454 455 456 457 458 |
T,
SolverError<<P as FirstOrderProblem>::Err, <<M as master::Builder>::MasterProblem as MasterProblem>::Err>,
>;
impl<P, T, W, M> Solver<P, T, W, M>
where
P: FirstOrderProblem,
| | < < | 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
T,
SolverError<<P as FirstOrderProblem>::Err, <<M as master::Builder>::MasterProblem as MasterProblem>::Err>,
>;
impl<P, T, W, M> Solver<P, T, W, M>
where
P: FirstOrderProblem,
P::Err: Into<Box<dyn std::error::Error + Sync + Send>>,
T: for<'a> Terminator<BundleState<'a>> + Default,
W: for<'a> Weighter<BundleState<'a>> + Default,
M: master::Builder + Default,
M::MasterProblem: 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
|
| ︙ | ︙ |