RsBundle  Diff

Differences From Artifact [fcf199cd05]:

  • File src/problem.rs — part of check-in [4d0fdfb346] at 2019-11-22 09:01:41 on branch result-sender — problem: hide result channel in opaque type `ResultSender` (user: fifr size: 7322)

To Artifact [f4ff9c7ee4]:

  • File src/problem.rs — part of check-in [43abfc4c67] at 2019-11-22 09:24:06 on branch result-sender — problem: make `ResultSender` a trait with implementation `ChannelSender` (user: fifr size: 6177)

14
15
16
17
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
14
15
16
17
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







-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
+

-
+

-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
-
-







 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see  <http://www.gnu.org/licenses/>
 */

//! An asynchronous first-order oracle.

use crate::{Aggregatable, DVector, Minorant, Real};
use crossbeam::channel::{SendError, Sender};
use crossbeam::channel::Sender;
use std::sync::Arc;

/// Evaluation result.
///
/// The result of an evaluation is new information to be made
/// available to the solver and the master problem. There are
/// essentially two types of information:
///
///    1. The (exact) function value of a sub-function at some point.
///    2. A minorant of some sub-function.
#[derive(Debug)]
pub enum EvalResult<I, P> {
    /// The objective value at some point.
    ObjectiveValue { index: I, value: Real },
    /// A minorant with an associated primal.
    Minorant { index: I, minorant: Minorant, primal: P },
}

/// Channel to send evaluation results to.
//pub type ResultSender<I, P, E> = Sender<Result<EvalResult<I, P>, E>>;

pub struct ResultSender<I, P, E> {
    index: I,
    tx: Sender<Result<EvalResult<I, P>, E>>,
}

impl<I, P, E> ResultSender<I, P, E>
pub trait ResultSender<P>: Send
where
    I: Clone,
    P: FirstOrderProblem,
{
    pub fn new(index: I, tx: Sender<Result<EvalResult<I, P>, E>>) -> Self {
        ResultSender { index, tx }
    }

    pub fn objective(&self, value: Real) -> Result<(), SendError<Result<EvalResult<I, P>, E>>> {
    type Err: std::error::Error + Send;

    /// Send a new objective `value`.
    fn objective(&self, value: Real) -> Result<(), Self::Err>;
        self.tx.send(Ok(EvalResult::ObjectiveValue {
            index: self.index.clone(),
            value,
        }))
    }

    pub fn minorant(&self, minorant: Minorant, primal: P) -> Result<(), SendError<Result<EvalResult<I, P>, E>>> {

    /// Send a new `minorant` with associated `primal`.
    fn minorant(&self, minorant: Minorant, primal: P::Primal) -> Result<(), Self::Err>;
        self.tx.send(Ok(EvalResult::Minorant {
            index: self.index.clone(),
            minorant,
            primal,
        }))
    }

    pub fn error(&self, err: E) -> Result<(), SendError<Result<EvalResult<I, P>, E>>> {

    /// Send an error message.
    fn error(&self, err: P::Err) -> Result<(), Self::Err>;
        self.tx.send(Err(err))
    }
}

/// Problem update information.
///
/// The solver calls the `update` method of the problem regularly.
/// This method can modify the problem by adding (or moving)
/// variables. The possible updates are encoded in this type.
189
190
191
192
193
194
195
196
197
198
199
200
201

202
203


204
205
206
207
208
209
210
154
155
156
157
158
159
160






161
162

163
164
165
166
167
168
169
170
171







-
-
-
-
-
-
+

-
+
+








    /// Start the evaluation of the i^th subproblem at the given point.
    ///
    /// The results of the evaluation should be passed to the provided channel.
    /// In order to work correctly, the results must contain (an upper bound on)
    /// the objective value at $y$ as well as at least one subgradient centered
    /// at $y$ eventually.
    fn evaluate<I: Send + Copy + 'static>(
        &mut self,
        i: usize,
        y: Arc<DVector>,
        tx: ResultSender<I, Self::Primal, Self::Err>,
    ) -> Result<(), Self::Err>
    fn evaluate<S>(&mut self, i: usize, y: Arc<DVector>, tx: S) -> Result<(), Self::Err>
    where
        I: Send + 'static;
        S: ResultSender<Self> + 'static,
        Self: Sized;

    /// Called to update the problem.
    ///
    /// This method is called regularly by the solver. The problem should send problem update
    /// information (e.g. adding new variables) to the provided channel.
    ///
    /// The updates might be generated asynchronously.