src/bisection_tree/btfn.rs

changeset 90
b3c35d16affe
parent 63
f7b87d84864d
child 80
f802ddbabcfc
child 86
d5b0e496b72f
equal deleted inserted replaced
25:d14c877e14b7 90:b3c35d16affe
2 use numeric_literals::replace_float_literals; 2 use numeric_literals::replace_float_literals;
3 use std::iter::Sum; 3 use std::iter::Sum;
4 use std::marker::PhantomData; 4 use std::marker::PhantomData;
5 use std::sync::Arc; 5 use std::sync::Arc;
6 use crate::types::Float; 6 use crate::types::Float;
7 use crate::mapping::{Apply, Mapping}; 7 use crate::mapping::{
8 Instance, Mapping, DifferentiableImpl, DifferentiableMapping, Space,
9 BasicDecomposition,
10 };
8 //use crate::linops::{Apply, Linear}; 11 //use crate::linops::{Apply, Linear};
9 use crate::sets::Set; 12 use crate::sets::Set;
10 use crate::sets::Cube; 13 use crate::sets::Cube;
11 use crate::loc::Loc; 14 use crate::loc::Loc;
12 use super::support::*; 15 use super::support::*;
38 generator : Arc<G>, 41 generator : Arc<G>,
39 _phantoms : PhantomData<F>, 42 _phantoms : PhantomData<F>,
40 } 43 }
41 44
42 impl<F : Float, G, BT, const N : usize> 45 impl<F : Float, G, BT, const N : usize>
46 Space for BTFN<F, G, BT, N>
47 where
48 G : SupportGenerator<F, N, Id=BT::Data>,
49 G::SupportType : LocalAnalysis<F, BT::Agg, N>,
50 BT : BTImpl<F, N>
51 {
52 type Decomp = BasicDecomposition;
53 }
54
55 impl<F : Float, G, BT, const N : usize>
43 BTFN<F, G, BT, N> 56 BTFN<F, G, BT, N>
44 where G : SupportGenerator<F, N, Id=BT::Data>, 57 where
45 G::SupportType : LocalAnalysis<F, BT::Agg, N>, 58 G : SupportGenerator<F, N, Id=BT::Data>,
46 BT : BTImpl<F, N> { 59 G::SupportType : LocalAnalysis<F, BT::Agg, N>,
60 BT : BTImpl<F, N>
61 {
47 62
48 /// Create a new BTFN from a support generator and a pre-initialised bisection tree. 63 /// Create a new BTFN from a support generator and a pre-initialised bisection tree.
49 /// 64 ///
50 /// The bisection tree `bt` should be pre-initialised to correspond to the `generator`. 65 /// The bisection tree `bt` should be pre-initialised to correspond to the `generator`.
51 /// Use [`Self::construct`] if no preinitialised tree is available. Use [`Self::new_refresh`] 66 /// Use [`Self::construct`] if no preinitialised tree is available. Use [`Self::new_refresh`]
384 } 399 }
385 } 400 }
386 401
387 make_btfn_unaryop!(Neg, neg); 402 make_btfn_unaryop!(Neg, neg);
388 403
389
390
391 // 404 //
392 // Mapping 405 // Apply, Mapping, Differentiate
393 // 406 //
394 407
395 impl<'a, F : Float, G, BT, V, const N : usize> Apply<&'a Loc<F, N>> 408 impl<F : Float, G, BT, V, const N : usize> Mapping<Loc<F, N>>
396 for BTFN<F, G, BT, N> 409 for BTFN<F, G, BT, N>
397 where BT : BTImpl<F, N>, 410 where
398 G : SupportGenerator<F, N, Id=BT::Data>, 411 BT : BTImpl<F, N>,
399 G::SupportType : LocalAnalysis<F, BT::Agg, N> + Apply<&'a Loc<F, N>, Output = V>, 412 G : SupportGenerator<F, N, Id=BT::Data>,
400 V : Sum { 413 G::SupportType : LocalAnalysis<F, BT::Agg, N> + Mapping<Loc<F, N>, Codomain = V>,
401 414 V : Sum + Space,
402 type Output = V; 415 {
403 416
404 fn apply(&self, x : &'a Loc<F, N>) -> Self::Output { 417 type Codomain = V;
405 self.bt.iter_at(x) 418
406 .map(|&d| self.generator.support_for(d).apply(x)).sum() 419 fn apply<I : Instance<Loc<F,N>>>(&self, x : I) -> Self::Codomain {
407 } 420 let xc = x.cow();
408 } 421 self.bt.iter_at(&*xc)
409 422 .map(|&d| self.generator.support_for(d).apply(&*xc)).sum()
410 impl<F : Float, G, BT, V, const N : usize> Apply<Loc<F, N>> 423 }
424 }
425
426 impl<F : Float, G, BT, V, const N : usize> DifferentiableImpl<Loc<F, N>>
411 for BTFN<F, G, BT, N> 427 for BTFN<F, G, BT, N>
412 where BT : BTImpl<F, N>, 428 where
413 G : SupportGenerator<F, N, Id=BT::Data>, 429 BT : BTImpl<F, N>,
414 G::SupportType : LocalAnalysis<F, BT::Agg, N> + Apply<Loc<F, N>, Output = V>, 430 G : SupportGenerator<F, N, Id=BT::Data>,
415 V : Sum { 431 G::SupportType : LocalAnalysis<F, BT::Agg, N>
416 432 + DifferentiableMapping<Loc<F, N>, DerivativeDomain = V>,
417 type Output = V; 433 V : Sum + Space,
418 434 {
419 fn apply(&self, x : Loc<F, N>) -> Self::Output { 435
420 self.bt.iter_at(&x) 436 type Derivative = V;
421 .map(|&d| self.generator.support_for(d).apply(x)).sum() 437
422 } 438 fn differential_impl<I : Instance<Loc<F, N>>>(&self, x :I) -> Self::Derivative {
423 } 439 let xc = x.cow();
440 self.bt.iter_at(&*xc)
441 .map(|&d| self.generator.support_for(d).differential(&*xc))
442 .sum()
443 }
444 }
445
446 //
447 // GlobalAnalysis
448 //
424 449
425 impl<F : Float, G, BT, const N : usize> GlobalAnalysis<F, BT::Agg> 450 impl<F : Float, G, BT, const N : usize> GlobalAnalysis<F, BT::Agg>
426 for BTFN<F, G, BT, N> 451 for BTFN<F, G, BT, N>
427 where BT : BTImpl<F, N>, 452 where BT : BTImpl<F, N>,
428 G : SupportGenerator<F, N, Id=BT::Data>, 453 G : SupportGenerator<F, N, Id=BT::Data>,
478 503
479 /// Helper trait for performing approximate minimisation using P2 elements. 504 /// Helper trait for performing approximate minimisation using P2 elements.
480 /// 505 ///
481 /// `U` is the domain, generally [`Loc`]`<F, N>`, and `F` the type of floating point numbers. 506 /// `U` is the domain, generally [`Loc`]`<F, N>`, and `F` the type of floating point numbers.
482 /// `Self` is generally a set of `U`, for example, [`Cube`]`<F, N>`. 507 /// `Self` is generally a set of `U`, for example, [`Cube`]`<F, N>`.
483 pub trait P2Minimise<U, F : Float> : Set<U> { 508 pub trait P2Minimise<U : Space, F : Float> : Set<U> {
484 /// Minimise `g` over the set presented by `Self`. 509 /// Minimise `g` over the set presented by `Self`.
485 /// 510 ///
486 /// The function returns `(x, v)` where `x` is the minimiser `v` an approximation of `g(x)`. 511 /// The function returns `(x, v)` where `x` is the minimiser `v` an approximation of `g(x)`.
487 fn p2_minimise<G : Fn(&U) -> F>(&self, g : G) -> (U, F); 512 fn p2_minimise<G : Fn(&U) -> F>(&self, g : G) -> (U, F);
488 513
804 // threads can also continue processing. If, however, numerical inaccuracy destroyes the `glb`, 829 // threads can also continue processing. If, however, numerical inaccuracy destroyes the `glb`,
805 // the queue may run out, and we get “Refiner failure”. 830 // the queue may run out, and we get “Refiner failure”.
806 impl<F : Float, G, BT, const N : usize> BTFN<F, G, BT, N> 831 impl<F : Float, G, BT, const N : usize> BTFN<F, G, BT, N>
807 where BT : BTSearch<F, N, Agg=Bounds<F>>, 832 where BT : BTSearch<F, N, Agg=Bounds<F>>,
808 G : SupportGenerator<F, N, Id=BT::Data>, 833 G : SupportGenerator<F, N, Id=BT::Data>,
809 G::SupportType : Mapping<Loc<F, N>,Codomain=F> 834 G::SupportType : Mapping<Loc<F, N>, Codomain=F>
810 + LocalAnalysis<F, Bounds<F>, N>, 835 + LocalAnalysis<F, Bounds<F>, N>,
811 Cube<F, N> : P2Minimise<Loc<F, N>, F> { 836 Cube<F, N> : P2Minimise<Loc<F, N>, F> {
812 837
813 /// Maximise the `BTFN` within stated value `tolerance`. 838 /// Maximise the `BTFN` within stated value `tolerance`.
814 /// 839 ///

mercurial