src/sliding_fb.rs

Thu, 29 Aug 2024 00:00:00 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Thu, 29 Aug 2024 00:00:00 -0500
branch
dev
changeset 34
efa60bc4f743
parent 32
56c8adc32b09
child 35
b087e3eab191
permissions
-rw-r--r--

Radon FB + sliding improvements

32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 /*!
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 Solver for the point source localisation problem using a sliding
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3 forward-backward splitting method.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4 */
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6 use numeric_literals::replace_float_literals;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 use serde::{Serialize, Deserialize};
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 //use colored::Colorize;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9 //use nalgebra::{DVector, DMatrix};
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10 use itertools::izip;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
11 use std::iter::Iterator;
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 use alg_tools::iterate::{
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14 AlgIteratorFactory,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 AlgIteratorState
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16 };
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
17 use alg_tools::euclidean::Euclidean;
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18 use alg_tools::sets::Cube;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 use alg_tools::loc::Loc;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20 use alg_tools::mapping::{Apply, Differentiable};
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
21 use alg_tools::norms::{Norm, L2};
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22 use alg_tools::bisection_tree::{
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 BTFN,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 PreBTFN,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25 Bounds,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 BTNodeLookup,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 BTNode,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 BTSearch,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29 P2Minimise,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30 SupportGenerator,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 LocalAnalysis,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32 //Bounded,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 };
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34 use alg_tools::mapping::RealMapping;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35 use alg_tools::nalgebra_support::ToNalgebraRealField;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 use crate::types::*;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
38 use crate::measures::{DeltaMeasure, DiscreteMeasure, Radon};
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 use crate::measures::merging::{
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 //SpikeMergingMethod,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 SpikeMerging,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
42 };
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 use crate::forward_model::ForwardModel;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 use crate::seminorms::DiscreteMeasureOp;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 //use crate::tolerance::Tolerance;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 use crate::plot::{
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 SeqPlotter,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 Plotting,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 PlotLookup
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 };
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 use crate::fb::*;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 use crate::regularisation::SlidingRegTerm;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 use crate::dataterm::{
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54 L2Squared,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 //DataTerm,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 calculate_residual,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 calculate_residual2,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 };
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59 use crate::transport::TransportLipschitz;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 /// Settings for [`pointsource_sliding_fb_reg`].
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62 #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 #[serde(default)]
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 pub struct SlidingFBConfig<F : Float> {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 /// Step length scaling
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 pub τ0 : F,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
67 /// Transport step length $θ$ normalised to $(0, 1)$.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
68 pub θ0 : F,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
69 /// Maximum transport mass scaling.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
70 // /// The maximum transported mass is this factor times $\norm{b}^2/(2α)$.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
71 // pub max_transport_scale : F,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
72 /// Transport tolerance wrt. ω
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
73 pub transport_tolerance_ω : F,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
74 /// Transport tolerance wrt. ∇v
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
75 pub transport_tolerance_dv : F,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 /// Generic parameters
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 pub insertion : FBGenericConfig<F>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 #[replace_float_literals(F::cast_from(literal))]
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 impl<F : Float> Default for SlidingFBConfig<F> {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82 fn default() -> Self {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83 SlidingFBConfig {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84 τ0 : 0.99,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
85 θ0 : 0.99,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
86 //max_transport_scale : 10.0,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
87 transport_tolerance_ω : 1.0, // TODO: no idea what this should be
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
88 transport_tolerance_dv : 1.0, // TODO: no idea what this should be
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89 insertion : Default::default()
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
94 /// Scale each |γ|_i ≠ 0 by q_i=q̄/g(γ_i)
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95 #[replace_float_literals(F::cast_from(literal))]
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
96 fn scale_down<'a, I, F, G, const N : usize>(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
97 iter : I,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
98 q̄ : F,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
99 mut g : G
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
100 ) where F : Float,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
101 I : Iterator<Item = &'a mut DeltaMeasure<Loc<F,N>, F>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
102 G : FnMut(&DeltaMeasure<Loc<F,N>, F>) -> F {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
103 iter.for_each(|δ| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
104 if δ.α != 0.0 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
105 let b = g(δ);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
106 if b * δ.α > 0.0 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
107 δ.α *= q̄/b;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
108 }
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
109 }
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
110 });
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
111 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
113 /// Iteratively solve the pointsource localisation problem using sliding forward-backward
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114 /// splitting
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
115 ///
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
116 /// The parametrisatio is as for [`pointsource_fb_reg`].
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117 /// Inertia is currently not supported.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
118 #[replace_float_literals(F::cast_from(literal))]
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
119 pub fn pointsource_sliding_fb_reg<'a, F, I, A, GA, 𝒟, BTA, BT𝒟, G𝒟, S, K, Reg, const N : usize>(
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
120 opA : &'a A,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121 b : &A::Observable,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
122 reg : Reg,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123 op𝒟 : &'a 𝒟,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124 sfbconfig : &SlidingFBConfig<F>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
125 iterator : I,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126 mut plotter : SeqPlotter<F, N>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 ) -> DiscreteMeasure<Loc<F, N>, F>
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128 where F : Float + ToNalgebraRealField,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129 I : AlgIteratorFactory<IterInfo<F, N>>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 for<'b> &'b A::Observable : std::ops::Neg<Output=A::Observable>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131 //+ std::ops::Mul<F, Output=A::Observable>, <-- FIXME: compiler overflow
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132 A::Observable : std::ops::MulAssign<F>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
133 A::PreadjointCodomain : for<'b> Differentiable<&'b Loc<F, N>, Output=Loc<F, N>>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135 A : ForwardModel<Loc<F, N>, F, PreadjointCodomain = BTFN<F, GA, BTA, N>>
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136 + Lipschitz<&'a 𝒟, FloatType=F> + TransportLipschitz<L2Squared, FloatType=F>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
137 BTA : BTSearch<F, N, Data=usize, Agg=Bounds<F>>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 G𝒟 : SupportGenerator<F, N, SupportType = K, Id = usize> + Clone,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
139 𝒟 : DiscreteMeasureOp<Loc<F, N>, F, PreCodomain = PreBTFN<F, G𝒟, N>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
140 Codomain = BTFN<F, G𝒟, BT𝒟, N>>,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
141 BT𝒟 : BTSearch<F, N, Data=usize, Agg=Bounds<F>>,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142 S: RealMapping<F, N> + LocalAnalysis<F, Bounds<F>, N>
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143 + Differentiable<Loc<F, N>, Output=Loc<F,N>>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
144 K: RealMapping<F, N> + LocalAnalysis<F, Bounds<F>, N>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
145 //+ Differentiable<Loc<F, N>, Output=Loc<F,N>>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
146 BTNodeLookup: BTNode<F, usize, Bounds<F>, N>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
147 Cube<F, N>: P2Minimise<Loc<F, N>, F>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
148 PlotLookup : Plotting<N>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
149 DiscreteMeasure<Loc<F, N>, F> : SpikeMerging<F>,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
150 Reg : SlidingRegTerm<F, N> {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
151
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
152 assert!(sfbconfig.τ0 > 0.0 &&
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
153 sfbconfig.θ0 > 0.0);
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
154
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
155 // Set up parameters
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
156 let config = &sfbconfig.insertion;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
157 let op𝒟norm = op𝒟.opnorm_bound();
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
158 //let max_transport = sfbconfig.max_transport_scale
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
159 // * reg.radon_norm_bound(b.norm2_squared() / 2.0);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
160 //let tlip = opA.transport_lipschitz_factor(L2Squared) * max_transport;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
161 //let ℓ = 0.0;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
162 let θ = sfbconfig.θ0; // (ℓ + tlip);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
163 let τ = sfbconfig.τ0/opA.lipschitz_factor(&op𝒟).unwrap();
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
164 // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
165 // by τ compared to the conditional gradient approach.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
166 let tolerance = config.tolerance * τ * reg.tolerance_scaling();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
167 let mut ε = tolerance.initial();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
168
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
169 // Initialise iterates
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
170 let mut μ = DiscreteMeasure::new();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
171 let mut γ1 = DiscreteMeasure::new();
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
172 let mut residual = -b;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
173 let mut stats = IterInfo::new();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
174
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
175 // Run the algorithm
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
176 iterator.iterate(|state| {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
177 // Calculate smooth part of surrogate model.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
178 // Using `std::mem::replace` here is not ideal, and expects that `empty_observable`
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
179 // has no significant overhead. For some reosn Rust doesn't allow us simply moving
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
180 // the residual and replacing it below before the end of this closure.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
181 let r = std::mem::replace(&mut residual, opA.empty_observable());
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
182 let v = opA.preadjoint().apply(r);
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
183
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
184 // Save current base point and shift μ to new positions. Idea is that
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
185 // μ_base(_masses) = μ^k (vector of masses)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
186 // μ_base_minus_γ0 = μ^k - π_♯^0γ^{k+1}
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
187 // γ1 = π_♯^1γ^{k+1}
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
188 // μ = μ^{k+1}
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
189 let μ_base_masses : Vec<F> = μ.iter_masses().collect();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
190 let mut μ_base_minus_γ0 = μ.clone(); // Weights will be set in the loop below.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
191 // Construct μ^{k+1} and π_♯^1γ^{k+1} initial candidates
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
192 let mut sum_norm_dv_times_γinit = 0.0;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
193 let mut sum_abs_γinit = 0.0;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
194 //let mut sum_norm_dv = 0.0;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
195 let γ_prev_len = γ1.len();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
196 assert!(μ.len() >= γ_prev_len);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
197 γ1.extend(μ[γ_prev_len..].iter().cloned());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
198 for (δ, ρ) in izip!(μ.iter_spikes_mut(), γ1.iter_spikes_mut()) {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
199 let d_v_x = v.differential(&δ.x);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
200 // If old transport has opposing sign, the new transport will be none.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
201 ρ.α = if (ρ.α > 0.0 && δ.α < 0.0) || (ρ.α < 0.0 && δ.α > 0.0) {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
202 0.0
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
203 } else {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
204 δ.α
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
205 };
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
206 δ.x -= d_v_x * (θ * δ.α.signum()); // This is δ.α.signum() when δ.α ≠ 0.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
207 ρ.x = δ.x;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
208 let nrm = d_v_x.norm(L2);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
209 let a = ρ.α.abs();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
210 let v = nrm * a;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
211 if v > 0.0 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
212 sum_norm_dv_times_γinit += v;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
213 sum_abs_γinit += a;
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
214 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
215 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
216
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
217 // A priori transport adaptation based on bounding ∫ ⟨∇v(x), z-y⟩ dλ(x, y, z).
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
218 // This is just one option, there are many.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
219 let t = ε * sfbconfig.transport_tolerance_dv;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
220 if sum_norm_dv_times_γinit > t {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
221 // Scale each |γ|_i by q_i=q̄/‖vx‖_i such that ∑_i |γ|_i q_i ‖vx‖_i = t
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
222 // TODO: store the closure values above?
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
223 scale_down(γ1.iter_spikes_mut(),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
224 t / sum_abs_γinit,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
225 |δ| v.differential(&δ.x).norm(L2));
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
226 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
227 //println!("|γ| = {}, |μ| = {}", γ1.norm(crate::measures::Radon), μ.norm(crate::measures::Radon));
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
228
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
229 // Solve finite-dimensional subproblem several times until the dual variable for the
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
230 // regularisation term conforms to the assumptions made for the transport above.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
231 let (d, within_tolerances) = 'adapt_transport: loop {
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
232 // Update weights for μ_base_minus_γ0 = μ^k - π_♯^0γ^{k+1}
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
233 for (δ_γ1, δ_μ_base_minus_γ0, &α_μ_base) in izip!(γ1.iter_spikes(),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
234 μ_base_minus_γ0.iter_spikes_mut(),
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
235 μ_base_masses.iter()) {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
236 δ_μ_base_minus_γ0.set_mass(α_μ_base - δ_γ1.get_mass());
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
237 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
238
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
239 // Calculate transported_minus_τv = -τA_*(A[μ_transported + μ_transported_base]-b)
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
240 let residual_μ̆ = calculate_residual2(&γ1, &μ_base_minus_γ0, opA, b);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
241 let transported_minus_τv̆ = opA.preadjoint().apply(residual_μ̆ * (-τ));
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
242
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
243 // Construct μ^{k+1} by solving finite-dimensional subproblems and insert new spikes.
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
244 let (d, within_tolerances) = insert_and_reweigh(
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
245 &mut μ, &transported_minus_τv̆, &γ1, Some(&μ_base_minus_γ0),
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
246 op𝒟, op𝒟norm,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
247 τ, ε,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
248 config,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
249 &reg, state, &mut stats,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
250 );
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
251
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
252 // A posteriori transport adaptation based on bounding (1/τ)∫ ω(z) - ω(y) dλ(x, y, z).
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
253 let all_ok = if false { // Basic check
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
254 // If π_♯^1γ^{k+1} = γ1 has non-zero mass at some point y, but μ = μ^{k+1} does not,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
255 // then the ansatz ∇w̃_x(y) = w^{k+1}(y) may not be satisfied. So set the mass of γ1
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
256 // at that point to zero, and retry.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
257 let mut all_ok = true;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
258 for (α_μ, α_γ1) in izip!(μ.iter_masses(), γ1.iter_masses_mut()) {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
259 if α_μ == 0.0 && *α_γ1 != 0.0 {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
260 all_ok = false;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
261 *α_γ1 = 0.0;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
262 }
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
263 }
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
264 all_ok
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
265 } else {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
266 // TODO: Could maybe optimise, as this is also formed in insert_and_reweigh above.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
267 let mut minus_ω = op𝒟.apply(γ1.sub_matching(&μ) + &μ_base_minus_γ0);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
268
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
269 // let vpos = γ1.iter_spikes()
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
270 // .filter(|δ| δ.α > 0.0)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
271 // .map(|δ| minus_ω.apply(&δ.x))
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
272 // .reduce(F::max)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
273 // .and_then(|threshold| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
274 // minus_ω.minimise_below(threshold,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
275 // ε * config.refinement.tolerance_mult,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
276 // config.refinement.max_steps)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
277 // .map(|(_z, minus_ω_z)| minus_ω_z)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
278 // });
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
279
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
280 // let vneg = γ1.iter_spikes()
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
281 // .filter(|δ| δ.α < 0.0)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
282 // .map(|δ| minus_ω.apply(&δ.x))
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
283 // .reduce(F::min)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
284 // .and_then(|threshold| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
285 // minus_ω.maximise_above(threshold,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
286 // ε * config.refinement.tolerance_mult,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
287 // config.refinement.max_steps)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
288 // .map(|(_z, minus_ω_z)| minus_ω_z)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
289 // });
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
290 let (_, vpos) = minus_ω.minimise(ε * config.refinement.tolerance_mult,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
291 config.refinement.max_steps);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
292 let (_, vneg) = minus_ω.maximise(ε * config.refinement.tolerance_mult,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
293 config.refinement.max_steps);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
294
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
295 let t = τ * ε * sfbconfig.transport_tolerance_ω;
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
296 let val = |δ : &DeltaMeasure<Loc<F, N>, F>| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
297 δ.α * (minus_ω.apply(&δ.x) - if δ.α >= 0.0 { vpos } else { vneg })
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
298 // match if δ.α >= 0.0 { vpos } else { vneg } {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
299 // None => 0.0,
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
300 // Some(v) => δ.α * (minus_ω.apply(&δ.x) - v)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
301 // }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
302 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
303 // Calculate positive/bad (rp) values under the integral.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
304 // Also store sum of masses for the positive entries.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
305 let (rp, w) = γ1.iter_spikes().fold((0.0, 0.0), |(p, w), δ| {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
306 let v = val(δ);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
307 if v <= 0.0 { (p, w) } else { (p + v, w + δ.α.abs()) }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
308 });
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
309
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
310 if rp > t {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
311 // TODO: store v above?
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
312 scale_down(γ1.iter_spikes_mut(), t / w, val);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
313 false
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
314 } else {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
315 true
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
316 }
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
317 };
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
318
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
319 if all_ok {
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
320 break 'adapt_transport (d, within_tolerances)
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
321 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
322 };
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
323
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
324 stats.untransported_fraction = Some({
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
325 assert_eq!(μ_base_masses.len(), γ1.len());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
326 let (a, b) = stats.untransported_fraction.unwrap_or((0.0, 0.0));
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
327 let source = μ_base_masses.iter().map(|v| v.abs()).sum();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
328 (a + μ_base_minus_γ0.norm(Radon), b + source)
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
329 });
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
330 stats.transport_error = Some({
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
331 assert_eq!(μ_base_masses.len(), γ1.len());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
332 let (a, b) = stats.transport_error.unwrap_or((0.0, 0.0));
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
333 let err = izip!(μ.iter_masses(), γ1.iter_masses()).map(|(v,w)| (v-w).abs()).sum();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
334 (a + err, b + γ1.norm(Radon))
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
335 });
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
336
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
337 // Prune spikes with zero weight. To maintain correct ordering between μ and γ1, also the
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
338 // latter needs to be pruned when μ is.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
339 // TODO: This could do with a two-vector Vec::retain to avoid copies.
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
340 let μ_new = DiscreteMeasure::from_iter(μ.iter_spikes().filter(|δ| δ.α != F::ZERO).cloned());
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
341 if μ_new.len() != μ.len() {
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
342 let mut μ_iter = μ.iter_spikes();
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
343 γ1.prune_by(|_| μ_iter.next().unwrap().α != F::ZERO);
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
344 μ = μ_new;
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
345 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
346
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
347 // TODO: how to merge?
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
348
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
349 // Update residual
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
350 residual = calculate_residual(&μ, opA, b);
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
351
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
352 // Update main tolerance for next iteration
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
353 let ε_prev = ε;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
354 ε = tolerance.update(ε, state.iteration());
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
355 stats.this_iters += 1;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
356
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
357 // Give function value if needed
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
358 state.if_verbose(|| {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
359 // Plot if so requested
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
360 plotter.plot_spikes(
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
361 format!("iter {} end; {}", state.iteration(), within_tolerances), &d,
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
362 "start".to_string(), None::<&A::PreadjointCodomain>, // TODO: Should be Some(&((-τ) * v)), but not implemented
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
363 reg.target_bounds(τ, ε_prev), &μ,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
364 );
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
365 // Calculate mean inner iterations and reset relevant counters.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
366 // Return the statistics
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
367 let res = IterInfo {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
368 value : residual.norm2_squared_div2() + reg.apply(&μ),
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
369 n_spikes : μ.len(),
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
370 ε : ε_prev,
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
371 postprocessing: config.postprocessing.then(|| μ.clone()),
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
372 .. stats
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
373 };
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
374 stats = IterInfo::new();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
375 res
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
376 })
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
377 });
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
378
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
379 postprocess(μ, config, L2Squared, opA, b)
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
380 }

mercurial