RsBundle  Check-in [3d746e5739]

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

Overview
Comment:master: allow moving of existing variables. This changes the master problem API, but the implementation of `boxed` does not yet implement this feature.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3d746e573975a1b879e67b9319750e957b439e05
User & Date: fifr 2017-03-06 16:58:42.572
Context
2017-03-07
07:36
unconstrained: allow moving of existing variables. check-in: e4f0dce522 user: fifr tags: trunk
2017-03-06
16:58
master: allow moving of existing variables. check-in: 3d746e5739 user: fifr tags: trunk
16:50
Add `MoveVariable` update. check-in: ce9ab8ec19 user: fifr tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/master/base.rs.
1
2
3
4
5
6
7
8
// Copyright (c) 2016 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
|







1
2
3
4
5
6
7
8
// 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
56
57
58
59
60
61
62
63





64

65
66
67
68
69
70
71

    /// Set the maximal number of inner iterations.
    fn set_max_updates(&mut self, max_updates: usize);

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

    /// Add some variables with bounds.





    fn add_vars(&mut self, bounds: &[(Real, Real)], extend_subgradient: &mut FnMut(usize, Self::MinorantIndex, &[usize]) -> DVector);


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







|
>
>
>
>
>
|
>







56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

    /// Set the maximal number of inner iterations.
    fn set_max_updates(&mut self, max_updates: usize);

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

    /// Add or movesome 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 FnMut(usize, Self::MinorantIndex, &[usize]) -> DVector);


    /// 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>;
Changes to src/master/boxed.rs.
198
199
200
201
202
203
204


205

206





207
208
209
210
211
212
213
214
215
        self.master.weight()
    }

    fn set_weight(&mut self, weight: Real) {
        self.master.set_weight(weight);
    }



    fn add_vars(&mut self, bounds: &[(Real, Real)], extend_subgradient: &mut FnMut(usize, Self::MinorantIndex, &[usize]) -> DVector) {

        if !bounds.is_empty() {





            self.lb.extend(bounds.iter().map(|x| x.0));
            self.ub.extend(bounds.iter().map(|x| x.1));
            self.eta.resize(self.lb.len(), 0.0);
            self.need_new_candidate = true;
            self.master.add_vars(bounds.len(), extend_subgradient)
        }
    }

    #[cfg_attr(feature="cargo-clippy", allow(cyclomatic_complexity))]







>
>
|
>

>
>
>
>
>
|
|







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
        self.master.weight()
    }

    fn set_weight(&mut self, weight: Real) {
        self.master.set_weight(weight);
    }

    fn add_vars(&mut self,
                bounds: &[(Option<usize>, Real, Real)],
                extend_subgradient: &mut FnMut(usize, Self::MinorantIndex, &[usize]) -> DVector)
    {
        if !bounds.is_empty() {
            for (index, l, u) in bounds.iter().filter_map(|v| v.0.map(|i| (i, v.1, v.2))) {
                self.lb[index] = l;
                self.ub[index] = u;
                unimplemented!();
            }
            self.lb.extend(bounds.iter().filter(|v| v.0.is_none()).map(|x| x.1));
            self.ub.extend(bounds.iter().filter(|v| v.0.is_none()).map(|x| x.2));
            self.eta.resize(self.lb.len(), 0.0);
            self.need_new_candidate = true;
            self.master.add_vars(bounds.len(), extend_subgradient)
        }
    }

    #[cfg_attr(feature="cargo-clippy", allow(cyclomatic_complexity))]
Changes to src/solver.rs.
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
                        return Err(Error::InvalidVariable(index, self.bounds.len()));
                    }
                    let (lower, upper) = self.bounds[index];
                    if value < lower || value > upper {
                        return Err(Error::ViolatedBounds(lower, upper, value));
                    }
                    newvars.push((Some(index), lower - value, upper - value, value));
                    unimplemented!()
                }
            }
        }

        if !newvars.is_empty() {
            let mut problem = &mut self.problem;
            let minorants = &self.minorants;
            self.master.add_vars(&newvars.iter().map(|v| (v.1, v.2)).collect::<Vec<_>>(),
                                 &mut move |fidx, minidx, vars| {
                                     problem.extend_subgradient(minorants[fidx][minidx].primal.as_ref().unwrap(), vars)
                                         .map(DVector)
                                         .unwrap()
                                 });
            // modify moved variables
            for (index, val) in newvars.iter().filter_map(|v| v.0.map(|i| (i, v.3))) {







<







|







636
637
638
639
640
641
642

643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
                        return Err(Error::InvalidVariable(index, self.bounds.len()));
                    }
                    let (lower, upper) = self.bounds[index];
                    if value < lower || value > upper {
                        return Err(Error::ViolatedBounds(lower, upper, value));
                    }
                    newvars.push((Some(index), lower - value, upper - value, value));

                }
            }
        }

        if !newvars.is_empty() {
            let mut problem = &mut self.problem;
            let minorants = &self.minorants;
            self.master.add_vars(&newvars.iter().map(|v| (v.0, v.1, v.2)).collect::<Vec<_>>(),
                                 &mut move |fidx, minidx, vars| {
                                     problem.extend_subgradient(minorants[fidx][minidx].primal.as_ref().unwrap(), vars)
                                         .map(DVector)
                                         .unwrap()
                                 });
            // modify moved variables
            for (index, val) in newvars.iter().filter_map(|v| v.0.map(|i| (i, v.3))) {