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
 * 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 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>
where
    I: Clone,
{
    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>>> {
        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>>> {
        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>>> {
        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.







|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
|

|

<
|
|
|
|
<
<
<
<
|
|
|
<
<
<
<
<
|
|
|
<
<







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::Sender;
use std::sync::Arc;

















/// Channel to send evaluation results to.







pub trait ResultSender<P>: Send
where
    P: FirstOrderProblem,
{

    type Err: std::error::Error + Send;

    /// Send a new objective `value`.
    fn objective(&self, value: Real) -> Result<(), Self::Err>;





    /// Send a new `minorant` with associated `primal`.
    fn minorant(&self, minorant: Minorant, primal: P::Primal) -> Result<(), Self::Err>;






    /// Send an error message.
    fn error(&self, err: P::Err) -> Result<(), Self::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

    /// 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>
    where
        I: Send + 'static;


    /// 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.







<
<
<
<
<
|

|
>







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<S>(&mut self, i: usize, y: Arc<DVector>, tx: S) -> Result<(), Self::Err>
    where
        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.