RsBundle  Diff

Differences From Artifact [bdfc03be14]:

  • File src/master/base.rs — part of check-in [1e94fdd305] at 2019-07-17 11:23:44 on branch async — Make all errors Send + Sync (user: fifr size: 5459)

To Artifact [9f71c5e699]:

  • File src/master/base.rs — part of check-in [f6352834ce] at 2019-07-17 14:14:41 on branch async — master: add error type parameter for subgradient extension callback (user: fifr size: 6000)

18
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
45
46
47
48
49





50
51

52

53
54
55
56
57
58
59

60
61
62

63
64
65
66
67
68



69
70

71
72



73



74
75
76
77
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
114
115
116
117
118
119
120




121

122
123
124
125
126
127
128
18
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
45
46
47
48
49
50


51
52
53
54
55
56
57
58

59
60
61
62
63
64
65

66
67
68

69

70
71
72
73
74
75
76
77
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
114
115
116
117
118

119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150







-
+

-
+








-
+
+
+
+











-
-
+
+
+
+
+


+
-
+






-
+


-
+
-





+
+
+

-
+


+
+
+
-
+
+
+








-
+


-
+











-
-
+
+






-
+
+
+
+
+


-
+












+
+
+
+
-
+








use std::error::Error;
use std::fmt;
use std::result;

/// Error type for master problems.
#[derive(Debug)]
pub enum MasterProblemError {
pub enum MasterProblemError<E> {
    /// Extension of the subgradient failed with some user error.
    SubgradientExtension(Box<dyn Error + Send + Sync>),
    SubgradientExtension(E),
    /// No minorants available when solving the master problem
    NoMinorants,
    /// An error in the solver backend occurred.
    Solver(Box<dyn Error + Send + Sync>),
    /// A custom error (specific to the master problem solver) occurred.
    Custom(Box<dyn Error + Send + Sync>),
}

impl fmt::Display for MasterProblemError {
impl<E> fmt::Display for MasterProblemError<E>
where
    E: fmt::Display,
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
        use self::MasterProblemError::*;
        match self {
            SubgradientExtension(err) => write!(fmt, "Subgradient extension failed: {}", err),
            NoMinorants => write!(fmt, "No minorants when solving the master problem"),
            Solver(err) => write!(fmt, "Solver error: {}", err),
            Custom(err) => err.fmt(fmt),
        }
    }
}

impl Error for MasterProblemError {
    fn cause(&self) -> Option<&Error> {
impl<E> Error for MasterProblemError<E>
where
    E: Error + 'static,
{
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        use self::MasterProblemError::*;
        match self {
            SubgradientExtension(err) => Some(err),
            SubgradientExtension(err) | Solver(err) | Custom(err) => Some(err.as_ref()),
            Solver(err) | Custom(err) => Some(err.as_ref()),
            NoMinorants => None,
        }
    }
}

/// Result type of master problems.
pub type Result<T> = result::Result<T, MasterProblemError>;
pub type Result<T, E> = result::Result<T, MasterProblemError<E>>;

/// Callback for subgradient extensions.
pub type SubgradientExtension<'a, I> =
pub type SubgradientExtension<'a, I, E> = FnMut(usize, I, &[usize]) -> result::Result<DVector, E> + 'a;
    FnMut(usize, I, &[usize]) -> result::Result<DVector, Box<dyn Error + Send + Sync>> + 'a;

pub trait MasterProblem {
    /// Unique index for a minorant.
    type MinorantIndex: Copy + Eq;

    /// Error returned by the subgradient-extension callback.
    type SubgradientExtensionErr;

    /// Set the number of subproblems.
    fn set_num_subproblems(&mut self, n: usize) -> Result<()>;
    fn set_num_subproblems(&mut self, n: usize) -> Result<(), Self::SubgradientExtensionErr>;

    /// Set the lower and upper bounds of the variables.
    fn set_vars(
        &mut self,
        nvars: usize,
    fn set_vars(&mut self, nvars: usize, lb: Option<DVector>, ub: Option<DVector>) -> Result<()>;
        lb: Option<DVector>,
        ub: Option<DVector>,
    ) -> Result<(), Self::SubgradientExtensionErr>;

    /// Return the current number of minorants of subproblem `fidx`.
    fn num_minorants(&self, fidx: usize) -> usize;

    /// Return the current weight of the quadratic term.
    fn weight(&self) -> Real;

    /// Set the weight of the quadratic term, must be > 0.
    fn set_weight(&mut self, weight: Real) -> Result<()>;
    fn set_weight(&mut self, weight: Real) -> Result<(), Self::SubgradientExtensionErr>;

    /// Set the maximal number of inner iterations.
    fn set_max_updates(&mut self, max_updates: usize) -> Result<()>;
    fn set_max_updates(&mut self, max_updates: usize) -> Result<(), Self::SubgradientExtensionErr>;

    /// Return the current number of inner iterations.
    fn cnt_updates(&self) -> usize;

    /// Add or move some variables with bounds.
    ///
    /// If an index is specified, existing variables are moved,
    /// otherwise new variables are generated.
    fn add_vars(
        &mut self,
        bounds: &[(Option<usize>, Real, Real)],
        extend_subgradient: &mut SubgradientExtension<Self::MinorantIndex>,
    ) -> Result<()>;
        extend_subgradient: &mut SubgradientExtension<Self::MinorantIndex, Self::SubgradientExtensionErr>,
    ) -> Result<(), Self::SubgradientExtensionErr>;

    /// Add a new minorant to the model.
    ///
    /// The function returns a unique (among all minorants of all
    /// subproblems) index of the minorant. This index must remain
    /// valid until the minorant is aggregated.
    fn add_minorant(&mut self, fidx: usize, minorant: Minorant) -> Result<Self::MinorantIndex>;
    fn add_minorant(
        &mut self,
        fidx: usize,
        minorant: Minorant,
    ) -> Result<Self::MinorantIndex, Self::SubgradientExtensionErr>;

    /// Solve the master problem.
    fn solve(&mut self, cur_value: Real) -> Result<()>;
    fn solve(&mut self, cur_value: Real) -> Result<(), Self::SubgradientExtensionErr>;

    /// Aggregate the given minorants according to the current
    /// solution.
    ///
    /// The (indices of the) minorants to be aggregated get invalid
    /// after this operation. The function returns the index of the
    /// aggregated minorant along with the coefficients of the convex
    /// combination. The index of the new aggregated minorant might or
    /// might not be one of indices of the original minorants.
    ///
    /// # Error The indices of the minorants `mins` must belong to
    /// subproblem `fidx`.
    fn aggregate(
        &mut self,
        fidx: usize,
        mins: &[usize],
    fn aggregate(&mut self, fidx: usize, mins: &[usize]) -> Result<(Self::MinorantIndex, DVector)>;
    ) -> Result<(Self::MinorantIndex, DVector), Self::SubgradientExtensionErr>;

    /// Return the (primal) optimal solution $\\|d\^*\\|$.
    fn get_primopt(&self) -> DVector;

    /// Return the value of the linear model in the optimal solution.
    ///
    /// This is the term $\langle g\^*, d\^* \rangle$ where $g^\*$ is