| 3 */ |
3 */ |
| 4 |
4 |
| 5 use numeric_literals::replace_float_literals; |
5 use numeric_literals::replace_float_literals; |
| 6 use serde::{Serialize, Deserialize}; |
6 use serde::{Serialize, Deserialize}; |
| 7 use alg_tools::norms::Norm; |
7 use alg_tools::norms::Norm; |
| 8 use alg_tools::linops::Apply; |
8 use alg_tools::linops::Mapping; |
| |
9 use alg_tools::instance::Instance; |
| 9 use alg_tools::loc::Loc; |
10 use alg_tools::loc::Loc; |
| 10 use crate::types::*; |
11 use crate::types::*; |
| 11 use crate::measures::{ |
12 use crate::measures::{ |
| 12 DiscreteMeasure, |
13 RNDM, |
| 13 DeltaMeasure, |
14 DeltaMeasure, |
| 14 Radon |
15 Radon, |
| 15 }; |
16 }; |
| 16 use crate::fb::FBGenericConfig; |
17 use crate::fb::FBGenericConfig; |
| 17 #[allow(unused_imports)] // Used by documentation. |
18 #[allow(unused_imports)] // Used by documentation. |
| 18 use crate::fb::pointsource_fb_reg; |
19 use crate::fb::pointsource_fb_reg; |
| 19 #[allow(unused_imports)] // Used by documentation. |
20 #[allow(unused_imports)] // Used by documentation. |
| 20 use crate::sliding_fb::pointsource_sliding_fb_reg; |
21 use crate::sliding_fb::pointsource_sliding_fb_reg; |
| 21 |
22 |
| 22 use nalgebra::{DVector, DMatrix}; |
23 use nalgebra::{DVector, DMatrix}; |
| 23 use alg_tools::nalgebra_support::ToNalgebraRealField; |
24 use alg_tools::nalgebra_support::ToNalgebraRealField; |
| 24 use alg_tools::mapping::Mapping; |
|
| 25 use alg_tools::bisection_tree::{ |
25 use alg_tools::bisection_tree::{ |
| 26 BTFN, |
26 BTFN, |
| 27 Bounds, |
27 Bounds, |
| 28 BTSearch, |
28 BTSearch, |
| 29 P2Minimise, |
29 P2Minimise, |
| 97 Radon(F), |
99 Radon(F), |
| 98 /// $α\\|μ\\|\_{ℳ(Ω)} + δ_{≥ 0}(μ)$ |
100 /// $α\\|μ\\|\_{ℳ(Ω)} + δ_{≥ 0}(μ)$ |
| 99 NonnegRadon(F), |
101 NonnegRadon(F), |
| 100 } |
102 } |
| 101 |
103 |
| 102 impl<'a, F : Float, const N : usize> Apply<&'a DiscreteMeasure<Loc<F, N>, F>> |
104 impl<'a, F : Float, const N : usize> Mapping<RNDM<F, N>> |
| 103 for Regularisation<F> { |
105 for Regularisation<F> { |
| 104 type Output = F; |
106 type Codomain = F; |
| 105 |
107 |
| 106 fn apply(&self, μ : &'a DiscreteMeasure<Loc<F, N>, F>) -> F { |
108 fn apply<I>(&self, μ : I) -> F |
| |
109 where I : Instance<RNDM<F, N>> { |
| 107 match *self { |
110 match *self { |
| 108 Self::Radon(α) => RadonRegTerm(α).apply(μ), |
111 Self::Radon(α) => RadonRegTerm(α).apply(μ), |
| 109 Self::NonnegRadon(α) => NonnegRadonRegTerm(α).apply(μ), |
112 Self::NonnegRadon(α) => NonnegRadonRegTerm(α).apply(μ), |
| 110 } |
113 } |
| 111 } |
114 } |
| 112 } |
115 } |
| 113 |
116 |
| 114 /// Abstraction of regularisation terms for [`generic_pointsource_fb_reg`]. |
117 /// Abstraction of regularisation terms. |
| 115 pub trait RegTerm<F : Float + ToNalgebraRealField, const N : usize> |
118 pub trait RegTerm<F : Float + ToNalgebraRealField, const N : usize> |
| 116 : for<'a> Apply<&'a DiscreteMeasure<Loc<F, N>, F>, Output = F> { |
119 : Mapping<RNDM<F, N>, Codomain = F> { |
| 117 /// Approximately solve the problem |
120 /// Approximately solve the problem |
| 118 /// <div>$$ |
121 /// <div>$$ |
| 119 /// \min_{x ∈ ℝ^n} \frac{1}{2} x^⊤Ax - g^⊤ x + τ G(x) |
122 /// \min_{x ∈ ℝ^n} \frac{1}{2} x^⊤Ax - g^⊤ x + τ G(x) |
| 120 /// $$</div> |
123 /// $$</div> |
| 121 /// for $G$ depending on the trait implementation. |
124 /// for $G$ depending on the trait implementation. |
| 169 skip_by_rough_check : bool, |
172 skip_by_rough_check : bool, |
| 170 config : &FBGenericConfig<F>, |
173 config : &FBGenericConfig<F>, |
| 171 ) -> Option<(Loc<F, N>, F, bool)> |
174 ) -> Option<(Loc<F, N>, F, bool)> |
| 172 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
175 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 173 G : SupportGenerator<F, N, Id=BT::Data>, |
176 G : SupportGenerator<F, N, Id=BT::Data>, |
| 174 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
177 G::SupportType : Mapping<Loc<F, N>, Codomain=F> + LocalAnalysis<F, Bounds<F>, N> { |
| 175 + LocalAnalysis<F, Bounds<F>, N> { |
|
| 176 self.find_tolerance_violation_slack(d, τ, ε, skip_by_rough_check, config, F::ZERO) |
178 self.find_tolerance_violation_slack(d, τ, ε, skip_by_rough_check, config, F::ZERO) |
| 177 } |
179 } |
| 178 |
180 |
| 179 /// Find a point where `d` may violate the tolerance `ε`. |
181 /// Find a point where `d` may violate the tolerance `ε`. |
| 180 /// |
182 /// |
| 197 config : &FBGenericConfig<F>, |
199 config : &FBGenericConfig<F>, |
| 198 slack : F, |
200 slack : F, |
| 199 ) -> Option<(Loc<F, N>, F, bool)> |
201 ) -> Option<(Loc<F, N>, F, bool)> |
| 200 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
202 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 201 G : SupportGenerator<F, N, Id=BT::Data>, |
203 G : SupportGenerator<F, N, Id=BT::Data>, |
| 202 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
204 G::SupportType : Mapping<Loc<F, N>, Codomain=F> + LocalAnalysis<F, Bounds<F>, N>; |
| 203 + LocalAnalysis<F, Bounds<F>, N>; |
|
| 204 |
205 |
| 205 |
206 |
| 206 /// Verify that `d` is in bounds `ε` for a merge candidate `μ` |
207 /// Verify that `d` is in bounds `ε` for a merge candidate `μ` |
| 207 /// |
208 /// |
| 208 /// `ε` is the current main tolerance and `τ` a scaling factor for the regulariser. |
209 /// `ε` is the current main tolerance and `τ` a scaling factor for the regulariser. |
| 209 fn verify_merge_candidate<G, BT>( |
210 fn verify_merge_candidate<G, BT>( |
| 210 &self, |
211 &self, |
| 211 d : &mut BTFN<F, G, BT, N>, |
212 d : &mut BTFN<F, G, BT, N>, |
| 212 μ : &DiscreteMeasure<Loc<F, N>, F>, |
213 μ : &RNDM<F, N>, |
| 213 τ : F, |
214 τ : F, |
| 214 ε : F, |
215 ε : F, |
| 215 config : &FBGenericConfig<F>, |
216 config : &FBGenericConfig<F>, |
| 216 ) -> bool |
217 ) -> bool |
| 217 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
218 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 218 G : SupportGenerator<F, N, Id=BT::Data>, |
219 G : SupportGenerator<F, N, Id=BT::Data>, |
| 219 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
220 G::SupportType : Mapping<Loc<F, N>, Codomain=F> + LocalAnalysis<F, Bounds<F>, N>; |
| 220 + LocalAnalysis<F, Bounds<F>, N>; |
|
| 221 |
221 |
| 222 /// Verify that `d` is in bounds `ε` for a merge candidate `μ` |
222 /// Verify that `d` is in bounds `ε` for a merge candidate `μ` |
| 223 /// |
223 /// |
| 224 /// This version is s used for Radon-norm squared proximal term in [`crate::radon_fb`]. |
224 /// This version is s used for Radon-norm squared proximal term in [`crate::radon_fb`]. |
| 225 /// The [`DiscreteMeasure`]s `μ` and `radon_μ` are supposed to have same coordinates at |
225 /// The [measures][crate::measures::DiscreteMeasure] `μ` and `radon_μ` are supposed to have |
| 226 /// same agreeing indices. |
226 /// same coordinates at same agreeing indices. |
| 227 /// |
227 /// |
| 228 /// `ε` is the current main tolerance and `τ` a scaling factor for the regulariser. |
228 /// `ε` is the current main tolerance and `τ` a scaling factor for the regulariser. |
| 229 fn verify_merge_candidate_radonsq<G, BT>( |
229 fn verify_merge_candidate_radonsq<G, BT>( |
| 230 &self, |
230 &self, |
| 231 d : &mut BTFN<F, G, BT, N>, |
231 d : &mut BTFN<F, G, BT, N>, |
| 232 μ : &DiscreteMeasure<Loc<F, N>, F>, |
232 μ : &RNDM<F, N>, |
| 233 τ : F, |
233 τ : F, |
| 234 ε : F, |
234 ε : F, |
| 235 config : &FBGenericConfig<F>, |
235 config : &FBGenericConfig<F>, |
| 236 radon_μ :&DiscreteMeasure<Loc<F, N>, F>, |
236 radon_μ :&RNDM<F, N>, |
| 237 ) -> bool |
237 ) -> bool |
| 238 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
238 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 239 G : SupportGenerator<F, N, Id=BT::Data>, |
239 G : SupportGenerator<F, N, Id=BT::Data>, |
| 240 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
240 G::SupportType : Mapping<Loc<F, N>, Codomain=F> + LocalAnalysis<F, Bounds<F>, N>; |
| 241 + LocalAnalysis<F, Bounds<F>, N>; |
|
| 242 |
241 |
| 243 |
242 |
| 244 /// TODO: document this |
243 /// TODO: document this |
| 245 fn target_bounds(&self, τ : F, ε : F) -> Option<Bounds<F>>; |
244 fn target_bounds(&self, τ : F, ε : F) -> Option<Bounds<F>>; |
| 246 |
245 |
| 256 /// Calculate $τ[w(z) - w(y)]$ for some w in the subdifferential of the regularisation |
255 /// Calculate $τ[w(z) - w(y)]$ for some w in the subdifferential of the regularisation |
| 257 /// term, such that $-ε ≤ τw - d ≤ ε$. |
256 /// term, such that $-ε ≤ τw - d ≤ ε$. |
| 258 fn goodness<G, BT>( |
257 fn goodness<G, BT>( |
| 259 &self, |
258 &self, |
| 260 d : &mut BTFN<F, G, BT, N>, |
259 d : &mut BTFN<F, G, BT, N>, |
| 261 μ : &DiscreteMeasure<Loc<F, N>, F>, |
260 μ : &RNDM<F, N>, |
| 262 y : &Loc<F, N>, |
261 y : &Loc<F, N>, |
| 263 z : &Loc<F, N>, |
262 z : &Loc<F, N>, |
| 264 τ : F, |
263 τ : F, |
| 265 ε : F, |
264 ε : F, |
| 266 config : &FBGenericConfig<F>, |
265 config : &FBGenericConfig<F>, |
| 267 ) -> F |
266 ) -> F |
| 268 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
267 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 269 G : SupportGenerator<F, N, Id=BT::Data>, |
268 G : SupportGenerator<F, N, Id=BT::Data>, |
| 270 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
269 G::SupportType : Mapping<Loc<F, N>, Codomain=F> + LocalAnalysis<F, Bounds<F>, N>; |
| 271 + LocalAnalysis<F, Bounds<F>, N>; |
|
| 272 |
270 |
| 273 /// Convert bound on the regulariser to a bond on the Radon norm |
271 /// Convert bound on the regulariser to a bond on the Radon norm |
| 274 fn radon_norm_bound(&self, b : F) -> F; |
272 fn radon_norm_bound(&self, b : F) -> F; |
| 275 } |
273 } |
| 276 |
274 |
| 321 config : &FBGenericConfig<F>, |
319 config : &FBGenericConfig<F>, |
| 322 slack : F |
320 slack : F |
| 323 ) -> Option<(Loc<F, N>, F, bool)> |
321 ) -> Option<(Loc<F, N>, F, bool)> |
| 324 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
322 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 325 G : SupportGenerator<F, N, Id=BT::Data>, |
323 G : SupportGenerator<F, N, Id=BT::Data>, |
| 326 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
324 G::SupportType : Mapping<Loc<F, N>, Codomain=F> + LocalAnalysis<F, Bounds<F>, N> { |
| 327 + LocalAnalysis<F, Bounds<F>, N> { |
325 let τα = τ * self.α(); |
| 328 let τα = τ * self.α(); |
326 let keep_above = -τα - slack - ε; |
| 329 let keep_below = τα + slack + ε; |
327 let minimise_below = -τα - slack - ε * config.insertion_cutoff_factor; |
| 330 let maximise_above = τα + slack + ε * config.insertion_cutoff_factor; |
|
| 331 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
328 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
| 332 |
329 |
| 333 // If preliminary check indicates that we are in bounds, and if it otherwise matches |
330 // If preliminary check indicates that we are in bounds, and if it otherwise matches |
| 334 // the insertion strategy, skip insertion. |
331 // the insertion strategy, skip insertion. |
| 335 if skip_by_rough_check && d.bounds().upper() <= keep_below { |
332 if skip_by_rough_check && d.bounds().lower() >= keep_above { |
| 336 None |
333 None |
| 337 } else { |
334 } else { |
| 338 // If the rough check didn't indicate no insertion needed, find maximising point. |
335 // If the rough check didn't indicate no insertion needed, find minimising point. |
| 339 d.maximise_above(maximise_above, refinement_tolerance, config.refinement.max_steps) |
336 d.minimise_below(minimise_below, refinement_tolerance, config.refinement.max_steps) |
| 340 .map(|(ξ, v_ξ)| (ξ, v_ξ, v_ξ <= keep_below)) |
337 .map(|(ξ, v_ξ)| (ξ, v_ξ, v_ξ >= keep_above)) |
| 341 } |
338 } |
| 342 } |
339 } |
| 343 |
340 |
| 344 fn verify_merge_candidate<G, BT>( |
341 fn verify_merge_candidate<G, BT>( |
| 345 &self, |
342 &self, |
| 346 d : &mut BTFN<F, G, BT, N>, |
343 d : &mut BTFN<F, G, BT, N>, |
| 347 μ : &DiscreteMeasure<Loc<F, N>, F>, |
344 μ : &RNDM<F, N>, |
| 348 τ : F, |
345 τ : F, |
| 349 ε : F, |
346 ε : F, |
| 350 config : &FBGenericConfig<F>, |
347 config : &FBGenericConfig<F>, |
| 351 ) -> bool |
348 ) -> bool |
| 352 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
349 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 353 G : SupportGenerator<F, N, Id=BT::Data>, |
350 G : SupportGenerator<F, N, Id=BT::Data>, |
| 354 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
351 G::SupportType : Mapping<Loc<F, N>, Codomain=F> + LocalAnalysis<F, Bounds<F>, N> { |
| 355 + LocalAnalysis<F, Bounds<F>, N> { |
|
| 356 let τα = τ * self.α(); |
352 let τα = τ * self.α(); |
| 357 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
353 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
| 358 let merge_tolerance = config.merge_tolerance_mult * ε; |
354 let merge_tolerance = config.merge_tolerance_mult * ε; |
| 359 let keep_below = τα + merge_tolerance; |
355 let keep_above = -τα - merge_tolerance; |
| 360 let keep_supp_above = τα - merge_tolerance; |
356 let keep_supp_below = -τα + merge_tolerance; |
| 361 let bnd = d.bounds(); |
357 let bnd = d.bounds(); |
| 362 |
358 |
| 363 return ( |
359 return ( |
| 364 bnd.lower() >= keep_supp_above |
360 bnd.upper() <= keep_supp_below |
| 365 || |
361 || |
| 366 μ.iter_spikes().all(|&DeltaMeasure{ α, ref x }| { |
362 μ.iter_spikes().all(|&DeltaMeasure{ α, ref x }| { |
| 367 (α == 0.0) || d.apply(x) >= keep_supp_above |
363 (α == 0.0) || d.apply(x) <= keep_supp_below |
| 368 }) |
364 }) |
| 369 ) && ( |
365 ) && ( |
| 370 bnd.upper() <= keep_below |
366 bnd.lower() >= keep_above |
| 371 || |
367 || |
| 372 d.has_upper_bound(keep_below, refinement_tolerance, config.refinement.max_steps) |
368 d.has_lower_bound(keep_above, refinement_tolerance, config.refinement.max_steps) |
| 373 ) |
369 ) |
| 374 } |
370 } |
| 375 |
371 |
| 376 fn verify_merge_candidate_radonsq<G, BT>( |
372 fn verify_merge_candidate_radonsq<G, BT>( |
| 377 &self, |
373 &self, |
| 378 d : &mut BTFN<F, G, BT, N>, |
374 d : &mut BTFN<F, G, BT, N>, |
| 379 μ : &DiscreteMeasure<Loc<F, N>, F>, |
375 μ : &RNDM<F, N>, |
| 380 τ : F, |
376 τ : F, |
| 381 ε : F, |
377 ε : F, |
| 382 config : &FBGenericConfig<F>, |
378 config : &FBGenericConfig<F>, |
| 383 radon_μ :&DiscreteMeasure<Loc<F, N>, F>, |
379 radon_μ :&RNDM<F, N>, |
| 384 ) -> bool |
380 ) -> bool |
| 385 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
381 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 386 G : SupportGenerator<F, N, Id=BT::Data>, |
382 G : SupportGenerator<F, N, Id=BT::Data>, |
| 387 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
383 G::SupportType : Mapping<Loc<F, N>, Codomain=F> + LocalAnalysis<F, Bounds<F>, N> { |
| 388 + LocalAnalysis<F, Bounds<F>, N> { |
|
| 389 let τα = τ * self.α(); |
384 let τα = τ * self.α(); |
| 390 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
385 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
| 391 let merge_tolerance = config.merge_tolerance_mult * ε; |
386 let merge_tolerance = config.merge_tolerance_mult * ε; |
| 392 let slack = radon_μ.norm(Radon); |
387 let slack = radon_μ.norm(Radon); |
| 393 let bnd = d.bounds(); |
388 let bnd = d.bounds(); |
| 394 |
389 |
| 395 return { |
390 return { |
| 396 μ.both_matching(radon_μ) |
391 μ.both_matching(radon_μ) |
| 397 .all(|(α, rα, x)| { |
392 .all(|(α, rα, x)| { |
| 398 let v = d.apply(x); |
393 let v = -d.apply(x); // TODO: observe ad hoc negation here, after minus_τv |
| |
394 // switch to τv. |
| 399 let (l1, u1) = match α.partial_cmp(&0.0).unwrap_or(Equal) { |
395 let (l1, u1) = match α.partial_cmp(&0.0).unwrap_or(Equal) { |
| 400 Greater => (τα, τα), |
396 Greater => (τα, τα), |
| 401 _ => (F::NEG_INFINITY, τα), |
397 _ => (F::NEG_INFINITY, τα), |
| 402 // Less should not happen; treated as Equal |
398 // Less should not happen; treated as Equal |
| 403 }; |
399 }; |
| 433 where Cube<F, N> : P2Minimise<Loc<F, N>, F> { |
429 where Cube<F, N> : P2Minimise<Loc<F, N>, F> { |
| 434 |
430 |
| 435 fn goodness<G, BT>( |
431 fn goodness<G, BT>( |
| 436 &self, |
432 &self, |
| 437 d : &mut BTFN<F, G, BT, N>, |
433 d : &mut BTFN<F, G, BT, N>, |
| 438 _μ : &DiscreteMeasure<Loc<F, N>, F>, |
434 _μ : &RNDM<F, N>, |
| 439 y : &Loc<F, N>, |
435 y : &Loc<F, N>, |
| 440 z : &Loc<F, N>, |
436 z : &Loc<F, N>, |
| 441 τ : F, |
437 τ : F, |
| 442 ε : F, |
438 ε : F, |
| 443 _config : &FBGenericConfig<F>, |
439 _config : &FBGenericConfig<F>, |
| 444 ) -> F |
440 ) -> F |
| 445 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
441 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 446 G : SupportGenerator<F, N, Id=BT::Data>, |
442 G : SupportGenerator<F, N, Id=BT::Data>, |
| 447 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
443 G::SupportType : Mapping<Loc<F, N>, Codomain=F> + LocalAnalysis<F, Bounds<F>, N> { |
| 448 + LocalAnalysis<F, Bounds<F>, N> { |
|
| 449 let w = |x| 1.0.min((ε + d.apply(x))/(τ * self.α())); |
444 let w = |x| 1.0.min((ε + d.apply(x))/(τ * self.α())); |
| 450 w(z) - w(y) |
445 w(z) - w(y) |
| 451 } |
446 } |
| 452 |
447 |
| 453 fn radon_norm_bound(&self, b : F) -> F { |
448 fn radon_norm_bound(&self, b : F) -> F { |
| 498 config : &FBGenericConfig<F>, |
493 config : &FBGenericConfig<F>, |
| 499 slack : F, |
494 slack : F, |
| 500 ) -> Option<(Loc<F, N>, F, bool)> |
495 ) -> Option<(Loc<F, N>, F, bool)> |
| 501 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
496 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 502 G : SupportGenerator<F, N, Id=BT::Data>, |
497 G : SupportGenerator<F, N, Id=BT::Data>, |
| 503 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
498 G::SupportType : Mapping<Loc<F, N>, Codomain=F> + LocalAnalysis<F, Bounds<F>, N> { |
| 504 + LocalAnalysis<F, Bounds<F>, N> { |
|
| 505 let τα = τ * self.α(); |
499 let τα = τ * self.α(); |
| 506 let keep_below = τα + slack + ε; |
500 let keep_below = τα + slack + ε; |
| 507 let keep_above = -(τα + slack) - ε; |
501 let keep_above = -(τα + slack) - ε; |
| 508 let maximise_above = τα + slack + ε * config.insertion_cutoff_factor; |
502 let maximise_above = τα + slack + ε * config.insertion_cutoff_factor; |
| 509 let minimise_below = -(τα + slack) - ε * config.insertion_cutoff_factor; |
503 let minimise_below = -(τα + slack) - ε * config.insertion_cutoff_factor; |
| 536 } |
530 } |
| 537 |
531 |
| 538 fn verify_merge_candidate<G, BT>( |
532 fn verify_merge_candidate<G, BT>( |
| 539 &self, |
533 &self, |
| 540 d : &mut BTFN<F, G, BT, N>, |
534 d : &mut BTFN<F, G, BT, N>, |
| 541 μ : &DiscreteMeasure<Loc<F, N>, F>, |
535 μ : &RNDM<F, N>, |
| 542 τ : F, |
536 τ : F, |
| 543 ε : F, |
537 ε : F, |
| 544 config : &FBGenericConfig<F>, |
538 config : &FBGenericConfig<F>, |
| 545 ) -> bool |
539 ) -> bool |
| 546 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
540 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 547 G : SupportGenerator<F, N, Id=BT::Data>, |
541 G : SupportGenerator<F, N, Id=BT::Data>, |
| 548 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
542 G::SupportType : Mapping<Loc<F, N>,Codomain=F> + LocalAnalysis<F, Bounds<F>, N> { |
| 549 + LocalAnalysis<F, Bounds<F>, N> { |
|
| 550 let τα = τ * self.α(); |
543 let τα = τ * self.α(); |
| 551 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
544 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
| 552 let merge_tolerance = config.merge_tolerance_mult * ε; |
545 let merge_tolerance = config.merge_tolerance_mult * ε; |
| 553 let keep_below = τα + merge_tolerance; |
546 let keep_below = τα + merge_tolerance; |
| 554 let keep_above = -τα - merge_tolerance; |
547 let keep_above = -τα - merge_tolerance; |
| 580 } |
573 } |
| 581 |
574 |
| 582 fn verify_merge_candidate_radonsq<G, BT>( |
575 fn verify_merge_candidate_radonsq<G, BT>( |
| 583 &self, |
576 &self, |
| 584 d : &mut BTFN<F, G, BT, N>, |
577 d : &mut BTFN<F, G, BT, N>, |
| 585 μ : &DiscreteMeasure<Loc<F, N>, F>, |
578 μ : &RNDM<F, N>, |
| 586 τ : F, |
579 τ : F, |
| 587 ε : F, |
580 ε : F, |
| 588 config : &FBGenericConfig<F>, |
581 config : &FBGenericConfig<F>, |
| 589 radon_μ : &DiscreteMeasure<Loc<F, N>, F>, |
582 radon_μ : &RNDM<F, N>, |
| 590 ) -> bool |
583 ) -> bool |
| 591 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
584 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
| 592 G : SupportGenerator<F, N, Id=BT::Data>, |
585 G : SupportGenerator<F, N, Id=BT::Data>, |
| 593 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
586 G::SupportType : Mapping<Loc<F, N>,Codomain=F> + LocalAnalysis<F, Bounds<F>, N> { |
| 594 + LocalAnalysis<F, Bounds<F>, N> { |
|
| 595 let τα = τ * self.α(); |
587 let τα = τ * self.α(); |
| 596 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
588 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
| 597 let merge_tolerance = config.merge_tolerance_mult * ε; |
589 let merge_tolerance = config.merge_tolerance_mult * ε; |
| 598 let slack = radon_μ.norm(Radon); |
590 let slack = radon_μ.norm(Radon); |
| 599 let bnd = d.bounds(); |
591 let bnd = d.bounds(); |