RsBundle  Check-in [5221a3331a]

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

Overview
Comment:Change parameters of `FirstOrderProblem::aggregate_primals`. Now the primals and coefficients are passed as (coeff, primal) pairs. This ensures that the number of coefficients always equals the number of primals by design.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5221a3331a119dc6f567e2f01bbf4a476eef406e
User & Date: fifr 2016-10-13 17:47:02.156
Context
2016-10-13
18:37
Update to 0.2.0. check-in: cdf3cd36ad user: fifr tags: trunk, v0.2.0
17:47
Change parameters of `FirstOrderProblem::aggregate_primals`. check-in: 5221a3331a user: fifr tags: trunk
17:45
Implement `IntoIterator` for `DVector`. check-in: b491a4796b user: fifr tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to examples/mmcf.rs.
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
        }).unwrap();
        solver.terminator = Box::new(StandardTerminator{
            termination_precision: 1e-6
        });
        solver.solve().unwrap();

        let costs : f64 = (0..solver.problem().num_subproblems()).map(|i| {
            let (coeffs, primals) : (Vec<_>, Vec<_>) = solver.aggregated_primals(i).into_iter().unzip();
            let aggr_primals = solver.problem().aggregate_primals_ref(&coeffs, &primals);
            solver.problem().get_primal_costs(i, &aggr_primals)
        }).sum();
        info!("Primal costs: {}", costs);
    } else {
        panic!("Usage: {} FILENAME", program);
    }
}







|
|







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
        }).unwrap();
        solver.terminator = Box::new(StandardTerminator{
            termination_precision: 1e-6
        });
        solver.solve().unwrap();

        let costs : f64 = (0..solver.problem().num_subproblems()).map(|i| {
            let primals = solver.aggregated_primals(i);
            let aggr_primals = solver.problem().aggregate_primals_ref(&primals);
            solver.problem().get_primal_costs(i, &aggr_primals)
        }).sum();
        info!("Primal costs: {}", costs);
    } else {
        panic!("Usage: {} FILENAME", program);
    }
}
Changes to src/firstorderproblem.rs.
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

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

    /// - `coeffs` are the coefficient for the convex combination
    /// - `primals` are the corresponding primals to be aggregated
    ///
    /// 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, coeffs: &[Real], primals: Vec<Self::Primal>) -> Self::Primal {
        let mut primals = primals;
        primals.pop().unwrap()
    }

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







>
|
<







|

|







145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

    /// 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::Error> {
        Ok(vec![])
Changes to src/mcf/problem.rs.
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
                }
            }
            sum
        }
    }

    /// Aggregate primal vectors.
    pub fn aggregate_primals_ref(&self, coeffs: &[Real], primals: &[&Vec<DVector>]) -> Vec<DVector> {
        let mut aggr = primals[0].iter().map(|x| {
            let mut r = dvec![];
            r.scal(coeffs[0], x);
            r
        }).collect::<Vec<_>>();

        for i in 1..primals.len() {
            for (j,x) in primals[i].iter().enumerate() {
                aggr[j].add_scaled(coeffs[i], x);
            }
        }

        aggr
    }
}








|
|

|



|
|
|







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
                }
            }
            sum
        }
    }

    /// Aggregate primal vectors.
    pub fn aggregate_primals_ref(&self, primals: &[(Real, &Vec<DVector>)]) -> Vec<DVector> {
        let mut aggr = primals[0].1.iter().map(|x| {
            let mut r = dvec![];
            r.scal(primals[0].0, x);
            r
        }).collect::<Vec<_>>();

        for &(alpha, primal) in &primals[1..] {
            for (j,x) in primal.iter().enumerate() {
                aggr[j].add_scaled(alpha, x);
            }
        }

        aggr
    }
}

303
304
305
306
307
308
309
310
311
312
313
            Ok(SimpleEvaluation {
                objective: objective,
                minorants: vec![(Minorant { constant: objective, linear: subg }, sols)],
            })
        }
    }

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







|
|


303
304
305
306
307
308
309
310
311
312
313
            Ok(SimpleEvaluation {
                objective: objective,
                minorants: vec![(Minorant { constant: objective, 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<_>>())
    }
}
Changes to src/solver.rs.
764
765
766
767
768
769
770
771
772
773
774
775

776
777
778
779
780
781
782
                let aggr = self.minorants[i].split_off(self.params.max_bundle_size-2);
                let aggr_sum = aggr.iter().map(|m| m.multiplier).sum();
                let (aggr_mins, aggr_primals) : (Vec<_>, Vec<_>) = aggr.into_iter().map(|m| {
                    (m.index, m.primal.unwrap())
                }).unzip();
                let (aggr_min, aggr_coeffs) = try!(self.master.aggregate(i, &aggr_mins));
                // append aggregated minorant
                debug_assert_eq!(aggr_coeffs.len(), aggr_primals.len());
                self.minorants[i].push(MinorantInfo{
                    index: aggr_min,
                    multiplier: aggr_sum,
                    primal: Some(self.problem.aggregate_primals(&aggr_coeffs, aggr_primals)),

                });
            }
        }
        Ok(())
    }

    /// Perform a descent step.







<
|


|
>







764
765
766
767
768
769
770

771
772
773
774
775
776
777
778
779
780
781
782
                let aggr = self.minorants[i].split_off(self.params.max_bundle_size-2);
                let aggr_sum = aggr.iter().map(|m| m.multiplier).sum();
                let (aggr_mins, aggr_primals) : (Vec<_>, Vec<_>) = aggr.into_iter().map(|m| {
                    (m.index, m.primal.unwrap())
                }).unzip();
                let (aggr_min, aggr_coeffs) = try!(self.master.aggregate(i, &aggr_mins));
                // 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.