RsBundle  Check-in [a98dc9db36]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:FirstOrderProblem: require `Primal` to be aggregatable. This allows to remove the `aggregate_primals` methods.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | aggregatable
Files: files | file ages | folders
SHA1: a98dc9db3673add3cb69a9430bcddb77f9d596a4
User & Date: fifr 2019-07-15 10:58:51.668
Context
2019-07-15
10:59
Update version to 0.6.0-dev check-in: b77f03d616 user: fifr tags: aggregatable
10:58
FirstOrderProblem: require `Primal` to be aggregatable. check-in: a98dc9db36 user: fifr tags: aggregatable
10:57
Implement `Aggregatable` for empty tuples check-in: a189e5fbfb user: fifr tags: aggregatable
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/firstorderproblem.rs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Copyright (c) 2016, 2017 Frank Fischer <frank-fischer@shadow-soft.de>
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see  <http://www.gnu.org/licenses/>
//

//! Problem description of a first-order convex optimization problem.

use crate::solver::UpdateState;
use crate::{Minorant, Real};

use std::result::Result;
use std::vec::IntoIter;

/**
 * Trait for results of an evaluation.
 *
|


















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Copyright (c) 2016, 2017, 2019 Frank Fischer <frank-fischer@shadow-soft.de>
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see  <http://www.gnu.org/licenses/>
//

//! Problem description of a first-order convex optimization problem.

use crate::solver::UpdateState;
use crate::{Aggregatable, Minorant, Real};

use std::result::Result;
use std::vec::IntoIter;

/**
 * Trait for results of an evaluation.
 *
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
 *
 */
pub trait FirstOrderProblem {
    /// Error raised by this oracle.
    type Err;

    /// The primal information associated with a minorant.
    type Primal;

    /// Custom evaluation result value.
    type EvalResult: Evaluation<Self::Primal>;

    /// Return the number of variables.
    fn num_variables(&self) -> usize;








|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
 *
 */
pub trait FirstOrderProblem {
    /// Error raised by this oracle.
    type Err;

    /// The primal information associated with a minorant.
    type Primal: Aggregatable;

    /// Custom evaluation result value.
    type EvalResult: Evaluation<Self::Primal>;

    /// Return the number of variables.
    fn num_variables(&self) -> usize;

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
        &mut self,
        i: usize,
        y: &[Real],
        nullstep_bound: Real,
        relprec: Real,
    ) -> Result<Self::EvalResult, Self::Err>;

    /// Aggregate primal information.
    ///
    /// This function is called from the solver when minorants are
    /// aggregated. The problem can use this information to aggregate
    /// the corresponding primal information.
    ///
    /// The `primals` parameters lists each minorant to be aggregated
    /// along with its coefficient.
    ///
    /// The function must return the new aggregated primal.
    ///
    /// The default implementation does nothing and simply returns the
    /// last primal. This should work if the implementing problem does
    /// not provide primal information, e.g. if `Self::Primal = ()`.
    #[allow(unused_variables)]
    fn aggregate_primals(&mut self, primals: Vec<(Real, Self::Primal)>) -> Self::Primal {
        let mut primals = primals;
        primals.pop().unwrap().1
    }

    /// Return updates of the problem.
    ///
    /// The default implementation returns no updates.
    fn update(&mut self, _state: &UpdateState<Self::Primal>) -> Result<Vec<Update>, Self::Err> {
        Ok(vec![])
    }








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







150
151
152
153
154
155
156




















157
158
159
160
161
162
163
        &mut self,
        i: usize,
        y: &[Real],
        nullstep_bound: Real,
        relprec: Real,
    ) -> Result<Self::EvalResult, Self::Err>;





















    /// Return updates of the problem.
    ///
    /// The default implementation returns no updates.
    fn update(&mut self, _state: &UpdateState<Self::Primal>) -> Result<Vec<Update>, Self::Err> {
        Ok(vec![])
    }

Changes to src/mcf/problem.rs.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Copyright (c) 2016, 2017 Frank Fischer <frank-fischer@shadow-soft.de>
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see  <http://www.gnu.org/licenses/>
//

use crate::mcf;
use crate::{DVector, FirstOrderProblem, Minorant, Real, SimpleEvaluation};

use log::debug;

use std::error::Error;
use std::f64::INFINITY;
use std::fmt;
use std::fs::File;
|
















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Copyright (c) 2016, 2017, 2019 Frank Fischer <frank-fischer@shadow-soft.de>
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see  <http://www.gnu.org/licenses/>
//

use crate::mcf;
use crate::{Aggregatable, DVector, FirstOrderProblem, Minorant, Real, SimpleEvaluation};

use log::debug;

use std::error::Error;
use std::f64::INFINITY;
use std::fmt;
use std::fs::File;
219
220
221
222
223
224
225
























226
227
228
229
230
231
232
                aggr[j].add_scaled(alpha, x);
            }
        }

        aggr
    }
}

























impl FirstOrderProblem for MMCFProblem {
    type Err = Box<dyn Error>;

    type Primal = Vec<DVector>;

    type EvalResult = SimpleEvaluation<Vec<DVector>>;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
                aggr[j].add_scaled(alpha, x);
            }
        }

        aggr
    }
}

impl Aggregatable for Vec<DVector> {
    fn combine<'a, I>(aggregates: I) -> Vec<DVector>
    where
        Self: 'a,
        I: IntoIterator<Item = (Real, &'a Vec<DVector>)>,
    {
        let mut x: Vec<DVector>;
        let mut it = aggregates.into_iter();
        if let Some((alpha, y)) = it.next() {
            x = y.into_iter().map(|yi| yi.scaled(alpha)).collect();
        } else {
            return vec![];
        }

        for (alpha, y) in it {
            for i in 0..x.len() {
                x[i].add_scaled(alpha, &y[i]);
            }
        }

        x
    }
}

impl FirstOrderProblem for MMCFProblem {
    type Err = Box<dyn Error>;

    type Primal = Vec<DVector>;

    type EvalResult = SimpleEvaluation<Vec<DVector>>;
331
332
333
334
335
336
337
338
339
340
341
342
                        linear: subg,
                    },
                    sols,
                )],
            })
        }
    }

    fn aggregate_primals(&mut self, primals: Vec<(Real, Vec<DVector>)>) -> Vec<DVector> {
        self.aggregate_primals_ref(&primals.iter().map(|&(alpha, ref x)| (alpha, x)).collect::<Vec<_>>())
    }
}







|
<
<
<
<
355
356
357
358
359
360
361
362




                        linear: subg,
                    },
                    sols,
                )],
            })
        }
    }
}




Changes to src/solver.rs.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see  <http://www.gnu.org/licenses/>
//

//! The main bundle method solver.

use crate::{DVector, Real};
use crate::{Evaluation, FirstOrderProblem, HKWeighter, Update};

use crate::master::{BoxedMasterProblem, Error as MasterProblemError, MasterProblem, UnconstrainedMasterProblem};
use crate::master::{CplexMaster, MinimalMaster};

use log::{debug, info, warn};








|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see  <http://www.gnu.org/licenses/>
//

//! The main bundle method solver.

use crate::{Aggregatable, DVector, Real};
use crate::{Evaluation, FirstOrderProblem, HKWeighter, Update};

use crate::master::{BoxedMasterProblem, Error as MasterProblemError, MasterProblem, UnconstrainedMasterProblem};
use crate::master::{CplexMaster, MinimalMaster};

use log::{debug, info, warn};

894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
                let (aggr_mins, aggr_primals): (Vec<_>, Vec<_>) =
                    aggr.into_iter().map(|m| (m.index, m.primal.unwrap())).unzip();
                let (aggr_min, aggr_coeffs) = self.master.aggregate(i, &aggr_mins).map_err(SolverError::Master)?;
                // append aggregated minorant
                self.minorants[i].push(MinorantInfo {
                    index: aggr_min,
                    multiplier: aggr_sum,
                    primal: Some(
                        self.problem
                            .aggregate_primals(aggr_coeffs.into_iter().zip(aggr_primals.into_iter()).collect()),
                    ),
                });
            }
        }
        Ok(())
    }

    /// Perform a descent step.







|
<
<
<







894
895
896
897
898
899
900
901



902
903
904
905
906
907
908
                let (aggr_mins, aggr_primals): (Vec<_>, Vec<_>) =
                    aggr.into_iter().map(|m| (m.index, m.primal.unwrap())).unzip();
                let (aggr_min, aggr_coeffs) = self.master.aggregate(i, &aggr_mins).map_err(SolverError::Master)?;
                // append aggregated minorant
                self.minorants[i].push(MinorantInfo {
                    index: aggr_min,
                    multiplier: aggr_sum,
                    primal: Some(Aggregatable::combine(aggr_coeffs.into_iter().zip(&aggr_primals))),



                });
            }
        }
        Ok(())
    }

    /// Perform a descent step.