soco/algorithms/offline/multi_dimensional/
convex_optimization.rs1use crate::algorithms::offline::{OfflineOptions, PureOfflineResult};
2use crate::config::Config;
3use crate::model::{ModelOutputFailure, ModelOutputSuccess};
4use crate::numerics::convex_optimization::{minimize, WrappedObjective};
5use crate::problem::{FractionalSmoothedConvexOptimization, Problem};
6use crate::result::{Failure, Result};
7use crate::schedule::Schedule;
8use crate::utils::assert;
9use noisy_float::prelude::*;
10
11#[derive(Clone)]
12struct ObjectiveData<'a, C, D> {
13 p: FractionalSmoothedConvexOptimization<'a, C, D>,
14 alpha: f64,
15}
16
17#[derive(Clone)]
18struct ConstraintData<'a, C, D> {
19 p: FractionalSmoothedConvexOptimization<'a, C, D>,
20 l: f64,
21}
22
23pub fn co<C, D>(
25 p: FractionalSmoothedConvexOptimization<'_, C, D>,
26 _: (),
27 OfflineOptions { inverted, alpha, l }: OfflineOptions,
28) -> Result<PureOfflineResult<f64>>
29where
30 C: ModelOutputSuccess,
31 D: ModelOutputFailure,
32{
33 assert(!inverted, Failure::UnsupportedInvertedCost)?;
34
35 let d = p.d;
36 let t_end = p.t_end;
37
38 let (lower, upper): (Vec<_>, Vec<_>) = p.bounds.iter().cloned().unzip();
39 let extended_lower = Schedule::build_raw(p.t_end, &Config::new(lower));
40 let extended_upper = Schedule::build_raw(p.t_end, &Config::new(upper));
41 let bounds = extended_lower
42 .into_iter()
43 .zip(extended_upper.into_iter())
44 .collect();
45
46 let objective = WrappedObjective::new(
47 ObjectiveData {
48 p: p.clone(),
49 alpha,
50 },
51 |raw_xs, data| {
52 let xs = Schedule::from_raw(data.p.d, data.p.t_end, raw_xs);
53 data.p
54 .alpha_unfair_objective_function(&xs, data.alpha)
55 .unwrap()
56 .cost
57 },
58 );
59
60 let constraints = match l {
62 Some(l) => {
63 vec![WrappedObjective::new(
64 ConstraintData { p, l },
65 |raw_xs, data| {
66 let xs = Schedule::from_raw(data.p.d, data.p.t_end, raw_xs);
67 data.p.total_movement(&xs, false).unwrap() - n64(data.l)
68 },
69 )]
70 }
71 None => vec![],
72 };
73
74 let (raw_xs, _) = minimize(objective, bounds, None, constraints);
75 let xs = Schedule::from_raw(d, t_end, &raw_xs);
76 Ok(PureOfflineResult { xs })
77}