src/sliding_fb.rs

Wed, 22 Apr 2026 23:43:00 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 22 Apr 2026 23:43:00 -0500
branch
dev
changeset 69
3ad8879ee6e1
parent 68
00d0881f89a6
permissions
-rw-r--r--

Bump versions

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;
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
7 use serde::{Deserialize, Serialize};
32
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;
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
12 use std::ops::MulAssign;
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
14 use crate::fb::*;
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
15 use crate::forward_model::{BoundedCurvature, BoundedCurvatureGuess};
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
16 use crate::measures::merging::SpikeMerging;
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
17 use crate::measures::{DeltaMeasure, DiscreteMeasure, Radon, RNDM};
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
18 use crate::plot::Plotter;
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
19 use crate::prox_penalty::{ProxPenalty, StepLengthBound};
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
20 use crate::regularisation::SlidingRegTerm;
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
21 use crate::types::*;
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
22 use alg_tools::error::DynResult;
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
23 use alg_tools::euclidean::Euclidean;
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
24 use alg_tools::iterate::AlgIteratorFactory;
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
25 use alg_tools::mapping::{DifferentiableMapping, DifferentiableRealMapping};
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
26 use alg_tools::nalgebra_support::ToNalgebraRealField;
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
27 use alg_tools::norms::Norm;
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
28 use anyhow::ensure;
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
29 use std::ops::ControlFlow;
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
30
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
31 /// Transport settings for [`pointsource_sliding_fb_reg`].
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
32 #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
33 #[serde(default)]
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
34 pub struct TransportConfig<F: Float> {
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
35 /// Transport step length $θ$ normalised to $(0, 1)$.
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
36 pub θ0: F,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
37 /// Factor in $(0, 1)$ for decreasing transport to adapt to tolerance.
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
38 pub adaptation: F,
39
6316d68b58af Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
39 /// A posteriori transport tolerance multiplier (C_pos)
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
40 pub tolerance_mult_con: F,
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
41 /// maximum number of adaptation iterations, until cancelling transport.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
42 pub max_attempts: usize,
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
43 /// Maximum number of failed transportations for a single source point
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
44 pub max_fail: usize,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
45 }
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
46
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
47 #[replace_float_literals(F::cast_from(literal))]
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
48 impl<F: Float> TransportConfig<F> {
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
49 /// Check that the parameters are ok. Panics if not.
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
50 pub fn check(&self) -> DynResult<()> {
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
51 ensure!(self.θ0 > 0.0);
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
52 ensure!(0.0 < self.adaptation && self.adaptation < 1.0);
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
53 ensure!(self.tolerance_mult_con > 0.0);
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
54 Ok(())
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
55 }
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
56 }
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
57
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
58 #[replace_float_literals(F::cast_from(literal))]
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
59 impl<F: Float> Default for TransportConfig<F> {
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
60 fn default() -> Self {
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
61 TransportConfig {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
62 θ0: 0.9,
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
63 adaptation: 0.9,
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
64 tolerance_mult_con: 100.0,
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
65 max_attempts: 2,
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
66 max_fail: usize::MAX,
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
67 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
68 }
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
69 }
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 /// Settings for [`pointsource_sliding_fb_reg`].
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 #[serde(default)]
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
74 pub struct SlidingFBConfig<F: Float> {
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 /// Step length scaling
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
76 pub τ0: F,
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
77 // Auxiliary variable step length scaling for [`crate::sliding_pdps::pointsource_sliding_fb_pair`]
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
78 pub σp0: F,
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
79 /// Transport parameters
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
80 pub transport: TransportConfig<F>,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 /// Generic parameters
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
82 pub insertion: InsertionConfig<F>,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
83 /// Guess for curvature bound calculations.
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
84 pub guess: BoundedCurvatureGuess,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
86
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 #[replace_float_literals(F::cast_from(literal))]
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
88 impl<F: Float> Default for SlidingFBConfig<F> {
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89 fn default() -> Self {
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 SlidingFBConfig {
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
91 τ0: 0.99,
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
92 σp0: 0.99,
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
93 transport: Default::default(),
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
94 insertion: Default::default(),
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
95 guess: BoundedCurvatureGuess::BetterThanZero,
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
100 /// Internal type of adaptive transport step length calculation
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
101 pub(crate) enum TransportStepLength<F: Float, G: Fn(F, F) -> F> {
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
102 /// Fixed, known step length
44
03251c546744 curvature controls
Tuomo Valkonen <tuomov@iki.fi>
parents: 41
diff changeset
103 #[allow(dead_code)]
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
104 Fixed(F),
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
105 /// Adaptive step length, only wrt. maximum transport.
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
106 /// Content of `l` depends on use case, while `g` calculates the step length from `l`.
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
107 AdaptiveMax { l: F, max_transport: F, g: G },
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
108 /// Adaptive step length.
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
109 /// Content of `l` depends on use case, while `g` calculates the step length from `l`.
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
110 FullyAdaptive { l: F, max_transport: F, g: G },
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
111 }
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
112
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
113 #[derive(Clone, Debug, Serialize)]
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
114 pub struct SingleTransport<const N: usize, F: Float> {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
115 /// Source point
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
116 x: Loc<N, F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
117 /// Target point
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
118 y: Loc<N, F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
119 /// Original mass
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
120 α_μ_orig: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
121 /// Transported mass
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
122 α_γ: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
123 /// Helper for pruning
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
124 prune: bool,
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
125 /// Fail count
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
126 fail_count: usize,
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
127 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
128
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
129 #[derive(Clone, Debug, Serialize)]
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
130 pub struct Transport<const N: usize, F: Float> {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
131 vec: Vec<SingleTransport<N, F>>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
132 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
133
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
134 /// Whether partiall transported points are allowed.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
135 ///
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
136 /// Partial transport can cause spike count explosion, so full or zero
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
137 /// transport is generally preferred. If this is set to `true`, different
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
138 /// transport adaptation heuristics will be used.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
139 const ALLOW_PARTIAL_TRANSPORT: bool = true;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
140 const MINIMAL_PARTIAL_TRANSPORT: bool = true;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
141
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
142 impl<const N: usize, F: Float> Transport<N, F> {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
143 pub(crate) fn new() -> Self {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
144 Transport { vec: Vec::new() }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
145 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
146
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
147 pub(crate) fn iter(&self) -> impl Iterator<Item = &'_ SingleTransport<N, F>> {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
148 self.vec.iter()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
149 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
150
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
151 pub(crate) fn iter_mut(&mut self) -> impl Iterator<Item = &'_ mut SingleTransport<N, F>> {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
152 self.vec.iter_mut()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
153 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
154
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
155 pub(crate) fn extend<I>(&mut self, it: I)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
156 where
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
157 I: IntoIterator<Item = SingleTransport<N, F>>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
158 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
159 self.vec.extend(it)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
160 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
161
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
162 pub(crate) fn len(&self) -> usize {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
163 self.vec.len()
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
164 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
165
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
166 // pub(crate) fn dist_matching(&self, μ: &RNDM<N, F>) -> F {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
167 // self.iter()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
168 // .zip(μ.iter_spikes())
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
169 // .map(|(ρ, δ)| (ρ.α_γ - δ.α).abs())
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
170 // .sum()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
171 // }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
172
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
173 /// Construct `μ̆`, replacing the contents of `μ`.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
174 #[replace_float_literals(F::cast_from(literal))]
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
175 pub(crate) fn μ̆_into(&self, μ: &mut RNDM<N, F>) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
176 assert!(self.len() <= μ.len());
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
177
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
178 // First transported points
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
179 for (δ, ρ) in izip!(μ.iter_spikes_mut(), self.iter()) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
180 if ρ.α_γ.abs() > 0.0 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
181 // Transport – transported point
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
182 δ.α = ρ.α_γ;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
183 δ.x = ρ.y;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
184 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
185 // No transport – original point
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
186 δ.α = ρ.α_μ_orig;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
187 δ.x = ρ.x;
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
188 }
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
189 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
190
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
191 // Then source points with partial transport
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
192 let mut i = self.len();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
193 if ALLOW_PARTIAL_TRANSPORT {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
194 // This can cause the number of points to explode, so cannot have partial transport.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
195 for ρ in self.iter() {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
196 let α = ρ.α_μ_orig - ρ.α_γ;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
197 if ρ.α_γ.abs() > F::EPSILON && α != 0.0 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
198 let δ = DeltaMeasure { α, x: ρ.x };
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
199 if i < μ.len() {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
200 μ[i] = δ;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
201 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
202 μ.push(δ)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
203 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
204 i += 1;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
205 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
206 }
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
207 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
208 μ.truncate(i);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
209 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
210
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
211 /// Constrution of initial transport `γ1` from initial measure `μ` and `v=F'(μ)`
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
212 /// with step lengh τ and transport step length `θ_or_adaptive`.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
213 #[replace_float_literals(F::cast_from(literal))]
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
214 pub(crate) fn initial_transport<G, D>(
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
215 &mut self,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
216 μ: &RNDM<N, F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
217 _τ: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
218 τθ_or_adaptive: &mut TransportStepLength<F, G>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
219 v: D,
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
220 tconfig: &TransportConfig<F>,
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
221 ) where
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
222 G: Fn(F, F) -> F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
223 D: DifferentiableRealMapping<N, F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
224 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
225 use TransportStepLength::*;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
226
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
227 // Initialise transport structure weights
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
228 for (δ, ρ) in izip!(μ.iter_spikes(), self.iter_mut()) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
229 ρ.α_μ_orig = δ.α;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
230 ρ.x = δ.x;
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
231 if ρ.fail_count > tconfig.max_fail {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
232 ρ.α_γ = 0.0
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
233 } else {
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
234 // If old transport has opposing sign, the new transport will be none.
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
235 ρ.α_γ = if (ρ.α_γ > 0.0 && δ.α < 0.0) || (ρ.α_γ < 0.0 && δ.α > 0.0) {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
236 0.0
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
237 } else {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
238 δ.α
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
239 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
240 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
241 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
242
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
243 let γ_prev_len = self.len();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
244 assert!(μ.len() >= γ_prev_len);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
245 self.extend(μ[γ_prev_len..].iter().map(|δ| SingleTransport {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
246 x: δ.x,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
247 y: δ.x, // Just something, will be filled properly in the next phase
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
248 α_μ_orig: δ.α,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
249 α_γ: δ.α,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
250 prune: false,
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
251 fail_count: 0,
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
252 }));
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
253
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
254 // Calculate transport rays.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
255 match *τθ_or_adaptive {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
256 Fixed(θ) => {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
257 for ρ in self.iter_mut() {
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
258 if ρ.fail_count <= tconfig.max_fail {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
259 ρ.y = ρ.x - v.differential(&ρ.x) * (ρ.α_γ.signum() * θ);
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
260 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
261 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
262 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
263 AdaptiveMax { l: ℓ_F, ref mut max_transport, g: ref calculate_θτ } => {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
264 *max_transport = max_transport.max(self.norm(Radon));
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
265 let θτ = calculate_θτ(ℓ_F, *max_transport);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
266 for ρ in self.iter_mut() {
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
267 if ρ.fail_count <= tconfig.max_fail {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
268 ρ.y = ρ.x - v.differential(&ρ.x) * (ρ.α_γ.signum() * θτ);
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
269 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
270 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
271 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
272 FullyAdaptive {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
273 l: ref mut adaptive_ℓ_F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
274 ref mut max_transport,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
275 g: ref calculate_θτ,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
276 } => {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
277 *max_transport = max_transport.max(self.norm(Radon));
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
278 let mut θτ = calculate_θτ(*adaptive_ℓ_F, *max_transport);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
279 // Do two runs through the spikes to update θ, breaking if first run did not cause
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
280 // a change.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
281 for _i in 0..=1 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
282 let mut changes = false;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
283 for ρ in self.iter_mut() {
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
284 if ρ.fail_count < tconfig.max_fail {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
285 let dv_x = v.differential(&ρ.x);
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
286 let g = &dv_x * (ρ.α_γ.signum() * θτ);
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
287 ρ.y = ρ.x - g;
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
288 let n = g.norm2();
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
289 if n >= F::EPSILON {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
290 // Estimate Lipschitz factor of ∇v
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
291 let this_ℓ_F = (dv_x - v.differential(&ρ.y)).norm2() / n;
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
292 *adaptive_ℓ_F = adaptive_ℓ_F.max(this_ℓ_F);
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
293 θτ = calculate_θτ(*adaptive_ℓ_F, *max_transport);
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
294 changes = true
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
295 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
296 }
39
6316d68b58af Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
297 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
298 if !changes {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
299 break;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
300 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
301 }
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
302 }
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
303 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
304 }
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
305
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
306 /// A posteriori transport adaptation.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
307 #[replace_float_literals(F::cast_from(literal))]
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
308 pub(crate) fn aposteriori_transport<D>(
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
309 &mut self,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
310 μ: &RNDM<N, F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
311 μ̆: &RNDM<N, F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
312 _v: &mut D,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
313 extra: Option<F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
314 ε: F,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
315 tconfig: &TransportConfig<F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
316 attempts: &mut usize,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
317 ) -> bool
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
318 where
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
319 D: DifferentiableRealMapping<N, F>,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
320 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
321 *attempts += 1;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
322
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
323 // 1. If π_♯^1γ^{k+1} = γ1 has non-zero mass at some point y, but μ = μ^{k+1} does not,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
324 // then the ansatz ∇w̃_x(y) = w^{k+1}(y) may not be satisfied. So set the mass of γ1
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
325 // at that point to zero, and retry.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
326 let mut all_ok = true;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
327 for (δ, ρ) in izip!(μ.iter_spikes(), self.iter_mut()) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
328 if δ.α == 0.0 && ρ.α_γ != 0.0 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
329 all_ok = false;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
330 ρ.α_γ = 0.0;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
331 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
332 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
333
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
334 // 2. Through bounding ∫ B_ω(y, z) dλ(x, y, z).
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
335 // through the estimate ≤ C ‖Δ‖‖γ^{k+1}‖ for Δ := μ^{k+1}-μ̆^k
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
336 // which holds for some some C if the convolution kernel in 𝒟 has Lipschitz gradient.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
337 let nγ = self.norm(Radon);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
338 let nΔ = μ.dist_matching(&μ̆) + extra.unwrap_or(0.0);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
339 let t = ε * tconfig.tolerance_mult_con;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
340 if nγ * nΔ > t && *attempts >= tconfig.max_attempts {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
341 all_ok = false;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
342 } else if nγ * nΔ > t {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
343 // Since t/(nγ*nΔ)<1, and the constant tconfig.adaptation < 1,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
344 // this will guarantee that eventually ‖γ‖ decreases sufficiently that we
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
345 // will not enter here.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
346 //*self *= tconfig.adaptation * t / (nγ * nΔ);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
347
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
348 // We want a consistent behaviour that has the potential to set many weights to zero.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
349 // Therefore, we find the smallest uniform reduction `chg_one`, subtracted
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
350 // from all weights, that achieves total `adapt` adaptation.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
351 let adapt_to = tconfig.adaptation * t / nΔ;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
352 let reduction_target = nγ - adapt_to;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
353 assert!(reduction_target > 0.0);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
354 if ALLOW_PARTIAL_TRANSPORT {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
355 if MINIMAL_PARTIAL_TRANSPORT {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
356 // This reduces weights of transport, starting from … until `adapt` is
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
357 // exhausted. It will, therefore, only ever cause one extrap point insertion
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
358 // at the sources, unlike “full” partial transport.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
359 //let refs = self.vec.iter_mut().collect::<Vec<_>>();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
360 //refs.sort_by(|ρ1, ρ2| ρ1.α_γ.abs().partial_cmp(&ρ2.α_γ.abs()).unwrap());
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
361 // let mut it = refs.into_iter();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
362 //
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
363 // Maybe sort by differential norm
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
364 // let mut refs = self
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
365 // .vec
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
366 // .iter_mut()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
367 // .map(|ρ| {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
368 // let val = v.differential(&ρ.x).norm2_squared();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
369 // (ρ, val)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
370 // })
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
371 // .collect::<Vec<_>>();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
372 // refs.sort_by(|(_, v1), (_, v2)| v2.partial_cmp(&v1).unwrap());
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
373 // let mut it = refs.into_iter().map(|(ρ, _)| ρ);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
374 let mut it = self.vec.iter_mut().rev();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
375 let _unused = it.try_fold(reduction_target, |left, ρ| {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
376 let w = ρ.α_γ.abs();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
377 if left <= w {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
378 ρ.α_γ = ρ.α_γ.signum() * (w - left);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
379 ControlFlow::Break(())
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
380 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
381 ρ.α_γ = 0.0;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
382 ControlFlow::Continue(left - w)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
383 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
384 });
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
385 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
386 // This version equally reduces all weights. It causes partial transport, which
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
387 // has the problem that that we need to then adapt weights in both start and
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
388 // end points, in insert_and_reweigh, somtimes causing the number of spikes μ
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
389 // to explode.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
390 let mut abs_weights = self
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
391 .vec
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
392 .iter()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
393 .map(|ρ| ρ.α_γ.abs())
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
394 .filter(|t| *t > F::EPSILON)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
395 .collect::<Vec<F>>();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
396 abs_weights.sort_by(|a, b| a.partial_cmp(b).unwrap());
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
397 let n = abs_weights.len();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
398 // Cannot have partial transport; can cause spike count explosion
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
399 let chg = abs_weights.into_iter().zip((1..=n).rev()).try_fold(
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
400 0.0,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
401 |smaller_total, (w, m)| {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
402 let mf = F::cast_from(m);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
403 let reduction = w * mf + smaller_total;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
404 if reduction >= reduction_target {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
405 ControlFlow::Break((reduction_target - smaller_total) / mf)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
406 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
407 ControlFlow::Continue(smaller_total + w)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
408 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
409 },
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
410 );
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
411 match chg {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
412 ControlFlow::Continue(_) => self.vec.iter_mut().for_each(|δ| δ.α_γ = 0.0),
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
413 ControlFlow::Break(chg_one) => self.vec.iter_mut().for_each(|ρ| {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
414 let t = ρ.α_γ.abs();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
415 if t > 0.0 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
416 if ALLOW_PARTIAL_TRANSPORT {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
417 let new = (t - chg_one).max(0.0);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
418 ρ.α_γ = ρ.α_γ.signum() * new;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
419 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
420 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
421 }),
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
422 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
423 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
424 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
425 // This version zeroes smallest weights, avoiding partial transport.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
426 let mut abs_weights_idx = self
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
427 .vec
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
428 .iter()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
429 .map(|ρ| ρ.α_γ.abs())
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
430 .zip(0..)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
431 .filter(|(w, _)| *w >= 0.0)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
432 .collect::<Vec<(F, usize)>>();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
433 abs_weights_idx.sort_by(|(a, _), (b, _)| a.partial_cmp(b).unwrap());
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
434
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
435 let mut left = reduction_target;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
436
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
437 for (w, i) in abs_weights_idx {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
438 left -= w;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
439 let ρ = &mut self.vec[i];
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
440 ρ.α_γ = 0.0;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
441 if left < 0.0 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
442 break;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
443 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
444 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
445 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
446
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
447 all_ok = false
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
448 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
449
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
450 if !all_ok && *attempts >= tconfig.max_attempts {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
451 for ρ in self.iter_mut() {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
452 ρ.α_γ = 0.0;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
453 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
454 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
455
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
456 for ρ in self.iter_mut() {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
457 if ρ.α_γ == 0.0 {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
458 ρ.fail_count += 1;
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
459 } else if all_ok {
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
460 ρ.fail_count = 0;
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
461 }
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
462 }
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
463
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
464 all_ok
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
465 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
466
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
467 /// Returns $‖μ\^k - π\_♯\^0γ\^{k+1}‖$
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
468 pub(crate) fn μ0_minus_γ0_radon(&self) -> F {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
469 self.vec.iter().map(|ρ| (ρ.α_μ_orig - ρ.α_γ).abs()).sum()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
470 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
471
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
472 /// Returns $∫ c_2 d|γ|$
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
473 #[replace_float_literals(F::cast_from(literal))]
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
474 pub(crate) fn c2integral(&self) -> F {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
475 self.vec
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
476 .iter()
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
477 .map(|ρ| ρ.y.dist2_squared(&ρ.x) / 2.0 * ρ.α_γ.abs())
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
478 .sum()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
479 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
480
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
481 #[replace_float_literals(F::cast_from(literal))]
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
482 pub(crate) fn get_transport_stats(&self, stats: &mut IterInfo<F>, μ: &RNDM<N, F>) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
483 // TODO: This doesn't take into account μ[i].α becoming zero in the latest tranport
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
484 // attempt, for i < self.len(), when a corresponding source term also exists with index
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
485 // j ≥ self.len(). For now, we let that be reflected in the prune count.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
486 stats.inserted += μ.len() - self.len();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
487
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
488 let transp = stats.get_transport_mut();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
489
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
490 transp.dist = {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
491 let (a, b) = transp.dist;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
492 (a + self.c2integral(), b + self.norm(Radon))
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
493 };
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
494 transp.untransported_fraction = {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
495 let (a, b) = transp.untransported_fraction;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
496 let source = self.iter().map(|ρ| ρ.α_μ_orig.abs()).sum();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
497 (a + self.μ0_minus_γ0_radon(), b + source)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
498 };
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
499 transp.transport_error = {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
500 let (a, b) = transp.transport_error;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
501 //(a + self.dist_matching(&μ), b + self.norm(Radon))
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
502
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
503 // This ignores points that have been not transported at all, to only calculate
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
504 // destnation error; untransported_fraction accounts for not being able to transport
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
505 // at all.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
506 self.iter()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
507 .zip(μ.iter_spikes())
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
508 .fold((a, b), |(a, b), (ρ, δ)| {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
509 let transported = ρ.α_γ.abs();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
510 if transported > F::EPSILON {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
511 (a + (ρ.α_γ - δ.α).abs(), b + transported)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
512 } else {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
513 (a, b)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
514 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
515 })
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
516 };
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
517 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
518
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
519 /// Prune spikes with zero weight. To maintain correct ordering between μ and γ, also the
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
520 /// latter needs to be pruned when μ is.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
521 pub(crate) fn prune_compat(&mut self, μ: &mut RNDM<N, F>, stats: &mut IterInfo<F>) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
522 assert!(self.vec.len() <= μ.len());
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
523 let old_len = μ.len();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
524 for (ρ, δ) in self.vec.iter_mut().zip(μ.iter_spikes()) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
525 ρ.prune = !(δ.α.abs() > F::EPSILON);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
526 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
527 μ.prune_by(|δ| δ.α.abs() > F::EPSILON);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
528 stats.pruned += old_len - μ.len();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
529 self.vec.retain(|ρ| !ρ.prune);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
530 assert!(self.vec.len() <= μ.len());
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
531 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
532 }
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
533
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
534 impl<const N: usize, F: Float> Norm<Radon, F> for Transport<N, F> {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
535 fn norm(&self, _: Radon) -> F {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
536 self.iter().map(|ρ| ρ.α_γ.abs()).sum()
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
537 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
538 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
539
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
540 impl<const N: usize, F: Float> MulAssign<F> for Transport<N, F> {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
541 fn mul_assign(&mut self, factor: F) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
542 for ρ in self.iter_mut() {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
543 ρ.α_γ *= factor;
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
544 }
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
545 }
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
546 }
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
547
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
548 /// Iteratively solve the pointsource localisation problem using sliding forward-backward
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
549 /// splitting
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
550 ///
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
551 /// The parametrisation is as for [`pointsource_fb_reg`].
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
552 /// Inertia is currently not supported.
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
553 #[replace_float_literals(F::cast_from(literal))]
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
554 pub fn pointsource_sliding_fb_reg<F, I, Dat, Reg, Plot, P, const N: usize>(
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
555 f: &Dat,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
556 reg: &Reg,
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
557 prox_penalty: &P,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
558 config: &SlidingFBConfig<F>,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
559 iterator: I,
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
560 mut plotter: Plot,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
561 μ0: Option<RNDM<N, F>>,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
562 ) -> DynResult<RNDM<N, F>>
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
563 where
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
564 F: Float + ToNalgebraRealField,
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
565 I: AlgIteratorFactory<IterInfo<F>>,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
566 Dat: DifferentiableMapping<RNDM<N, F>, Codomain = F> + BoundedCurvature<F>,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
567 Dat::DerivativeDomain: DifferentiableRealMapping<N, F> + ClosedMul<F>,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
568 //for<'a> Dat::Differential<'a>: Lipschitz<&'a P, FloatType = F>,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
569 RNDM<N, F>: SpikeMerging<F>,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
570 Reg: SlidingRegTerm<Loc<N, F>, F>,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
571 P: ProxPenalty<Loc<N, F>, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>,
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
572 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, RNDM<N, F>>,
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
573 {
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
574 // Check parameters
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
575 ensure!(config.τ0 > 0.0, "Invalid step length parameter");
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
576 config.transport.check()?;
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
577
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
578 // Initialise iterates
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
579 let mut μ = μ0.unwrap_or_else(|| DiscreteMeasure::new());
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
580 let mut γ = Transport::new();
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
581
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
582 // Set up parameters
41
b6bdb6cb4d44 Remove initial transport adaptation—it is not needed, after all
Tuomo Valkonen <tuomov@iki.fi>
parents: 39
diff changeset
583 // let opAnorm = opA.opnorm_bound(Radon, L2);
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
584 //let max_transport = config.max_transport.scale
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
585 // * reg.radon_norm_bound(b.norm2_squared() / 2.0);
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
586 //let ℓ = opA.transport.lipschitz_factor(L2Squared) * max_transport;
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
587 let ℓ = 0.0;
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
588 let τ = config.τ0 / prox_penalty.step_length_bound(&f)?;
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
589
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
590 let mut θ_or_adaptive = match f.curvature_bound_components(config.guess) {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
591 (_, Err(_)) => TransportStepLength::Fixed(config.transport.θ0),
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
592 (maybe_ℓ_F, Ok(transport_lip)) => {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
593 let calculate_θτ = move |ℓ_F, max_transport| {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
594 let ℓ_r = transport_lip * max_transport;
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
595 config.transport.θ0 / (ℓ + ℓ_F + ℓ_r)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
596 };
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
597 match maybe_ℓ_F {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
598 Ok(ℓ_F) => TransportStepLength::AdaptiveMax {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
599 l: ℓ_F, // TODO: could estimate computing the real reesidual
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
600 max_transport: 0.0,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
601 g: calculate_θτ,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
602 },
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
603 Err(_) => TransportStepLength::FullyAdaptive {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
604 l: 10.0 * F::EPSILON, // Start with something very small to estimate differentials
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
605 max_transport: 0.0,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
606 g: calculate_θτ,
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
607 },
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
608 }
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
609 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
610 };
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
611 // We multiply tolerance by τ for FB since our subproblems depending on tolerances are scaled
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
612 // by τ compared to the conditional gradient approach.
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
613 let tolerance = config.insertion.tolerance * τ * reg.tolerance_scaling();
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
614 let mut ε = tolerance.initial();
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
615
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
616 // Statistics
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
617 let full_stats = |μ: &RNDM<N, F>, ε, stats| IterInfo {
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
618 value: f.apply(μ) + reg.apply(μ),
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
619 n_spikes: μ.len(),
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
620 ε,
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
621 // postprocessing: config.insertion.postprocessing.then(|| μ.clone()),
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
622 ..stats
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
623 };
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
624 let mut stats = IterInfo::new();
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
625
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
626 // Run the algorithm
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
627 for state in iterator.iter_init(|| full_stats(&μ, ε, stats.clone())) {
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
628 // Calculate initial transport
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
629 let v = f.differential(&μ);
68
00d0881f89a6 Automatic transport disabling after sufficient failures, for efficiency
Tuomo Valkonen <tuomov@iki.fi>
parents: 63
diff changeset
630 γ.initial_transport(&μ, τ, &mut θ_or_adaptive, v, &config.transport);
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
631
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
632 let mut attempts = 0;
34
efa60bc4f743 Radon FB + sliding improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 32
diff changeset
633
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
634 // Solve finite-dimensional subproblem several times until the dual variable for the
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
635 // regularisation term conforms to the assumptions made for the transport above.
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
636 let (maybe_d, _within_tolerances, mut τv̆, μ̆) = 'adapt_transport: loop {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
637 // Set initial guess for μ=μ^{k+1}.
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
638 γ.μ̆_into(&mut μ);
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
639 let μ̆ = μ.clone();
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
640
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
641 // Calculate τv̆ = τA_*(A[μ_transported + μ_transported_base]-b)
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
642 //let residual_μ̆ = calculate_residual2(&γ1, &μ0_minus_γ0, opA, b);
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
643 // TODO: this could be optimised by doing the differential like the
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
644 // old residual2.
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
645 // NOTE: This assumes that μ = γ1
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
646 let mut τv̆ = f.differential(&μ̆) * τ;
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
647
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
648 // Construct μ^{k+1} by solving finite-dimensional subproblems and insert new spikes.
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
649 let (maybe_d, within_tolerances) = prox_penalty.insert_and_reweigh(
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
650 &mut μ,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
651 &mut τv̆,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
652 τ,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
653 ε,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
654 &config.insertion,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
655 &reg,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
656 &state,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
657 &mut stats,
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
658 )?;
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
659
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
660 // A posteriori transport adaptation.
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
661 if γ.aposteriori_transport(&μ, &μ̆, &mut τv̆, None, ε, &config.transport, &mut attempts)
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
662 {
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
663 break 'adapt_transport (maybe_d, within_tolerances, τv̆, μ̆);
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
664 }
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
665
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
666 stats.get_transport_mut().readjustment_iters += 1;
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
667 };
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
668
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
669 γ.get_transport_stats(&mut stats, &μ);
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
670
39
6316d68b58af Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
671 // Merge spikes.
6316d68b58af Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
672 // This crucially expects the merge routine to be stable with respect to spike locations,
6316d68b58af Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
673 // and not to performing any pruning. That is be to done below simultaneously for γ.
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
674 if config.insertion.merge_now(&state) {
39
6316d68b58af Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
675 stats.merged += prox_penalty.merge_spikes(
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
676 &mut μ,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
677 &mut τv̆,
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
678 &μ̆,
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
679 τ,
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
680 ε,
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
681 &config.insertion,
49
6b0db7251ebe Some documentation and factor changes related to ℓ_F and ℓ_r.
Tuomo Valkonen <tuomov@iki.fi>
parents: 46
diff changeset
682 &reg,
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
683 Some(|μ̃: &RNDM<N, F>| f.apply(μ̃)),
39
6316d68b58af Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
684 );
6316d68b58af Merging adjustments, parameter tuning, etc.
Tuomo Valkonen <tuomov@iki.fi>
parents: 37
diff changeset
685 }
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
686
63
7a8a55fd41c0 Subproblem solver and sliding adjustments/improvements
Tuomo Valkonen <tuomov@iki.fi>
parents: 61
diff changeset
687 γ.prune_compat(&mut μ, &mut stats);
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
688
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
689 let iter = state.iteration();
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
690 stats.this_iters += 1;
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
691
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
692 // Give statistics if requested
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
693 state.if_verbose(|| {
37
c5d8bd1a7728 Generic proximal penalty support
Tuomo Valkonen <tuomov@iki.fi>
parents: 35
diff changeset
694 plotter.plot_spikes(iter, maybe_d.as_ref(), Some(&τv̆), &μ);
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
695 full_stats(&μ, ε, std::mem::replace(&mut stats, IterInfo::new()))
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
696 });
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
697
35
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
698 // Update main tolerance for next iteration
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
699 ε = tolerance.update(ε, iter);
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
700 }
b087e3eab191 New version of sliding.
Tuomo Valkonen <tuomov@iki.fi>
parents: 34
diff changeset
701
61
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
702 //postprocess(μ, &config.insertion, f)
4f468d35fa29 General forward operators, separation of measures into own crate, and other architecture improvements to support the pointsource_pde crate.
Tuomo Valkonen <tuomov@iki.fi>
parents: 49
diff changeset
703 postprocess(μ, &config.insertion, |μ̃| f.apply(μ̃))
32
56c8adc32b09 Early transport sketches
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
704 }

mercurial