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`] |
388 |
403 |
389 // |
404 // |
390 // Apply, Mapping, Differentiate |
405 // Apply, Mapping, Differentiate |
391 // |
406 // |
392 |
407 |
393 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>> |
394 for BTFN<F, G, BT, N> |
409 for BTFN<F, G, BT, N> |
395 where BT : BTImpl<F, N>, |
410 where |
396 G : SupportGenerator<F, N, Id=BT::Data>, |
411 BT : BTImpl<F, N>, |
397 G::SupportType : LocalAnalysis<F, BT::Agg, N> + Apply<&'a Loc<F, N>, Output = V>, |
412 G : SupportGenerator<F, N, Id=BT::Data>, |
398 V : Sum { |
413 G::SupportType : LocalAnalysis<F, BT::Agg, N> + Mapping<Loc<F, N>, Codomain = V>, |
399 |
414 V : Sum + Space, |
400 type Output = V; |
415 { |
401 |
416 |
402 fn apply(&self, x : &'a Loc<F, N>) -> Self::Output { |
417 type Codomain = V; |
403 self.bt.iter_at(x) |
418 |
404 .map(|&d| self.generator.support_for(d).apply(x)).sum() |
419 fn apply<I : Instance<Loc<F,N>>>(&self, x : I) -> Self::Codomain { |
405 } |
420 let xc = x.cow(); |
406 } |
421 self.bt.iter_at(&*xc) |
407 |
422 .map(|&d| self.generator.support_for(d).apply(&*xc)).sum() |
408 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>> |
409 for BTFN<F, G, BT, N> |
427 for BTFN<F, G, BT, N> |
410 where BT : BTImpl<F, N>, |
428 where |
411 G : SupportGenerator<F, N, Id=BT::Data>, |
429 BT : BTImpl<F, N>, |
412 G::SupportType : LocalAnalysis<F, BT::Agg, N> + Apply<Loc<F, N>, Output = V>, |
430 G : SupportGenerator<F, N, Id=BT::Data>, |
413 V : Sum { |
431 G::SupportType : LocalAnalysis<F, BT::Agg, N> |
414 |
432 + DifferentiableMapping<Loc<F, N>, DerivativeDomain = V>, |
415 type Output = V; |
433 V : Sum + Space, |
416 |
434 { |
417 fn apply(&self, x : Loc<F, N>) -> Self::Output { |
|
418 self.bt.iter_at(&x) |
|
419 .map(|&d| self.generator.support_for(d).apply(x)).sum() |
|
420 } |
|
421 } |
|
422 |
|
423 impl<'a, F : Float, G, BT, V, const N : usize> Differentiable<&'a Loc<F, N>> |
|
424 for BTFN<F, G, BT, N> |
|
425 where BT : BTImpl<F, N>, |
|
426 G : SupportGenerator<F, N, Id=BT::Data>, |
|
427 G::SupportType : LocalAnalysis<F, BT::Agg, N> + Differentiable<&'a Loc<F, N>, Derivative = V>, |
|
428 V : Sum { |
|
429 |
435 |
430 type Derivative = V; |
436 type Derivative = V; |
431 |
437 |
432 fn differential(&self, x : &'a Loc<F, N>) -> Self::Derivative { |
438 fn differential_impl<I : Instance<Loc<F, N>>>(&self, x :I) -> Self::Derivative { |
433 self.bt.iter_at(x) |
439 let xc = x.cow(); |
434 .map(|&d| self.generator.support_for(d).differential(x)) |
440 self.bt.iter_at(&*xc) |
435 .sum() |
441 .map(|&d| self.generator.support_for(d).differential(&*xc)) |
436 } |
|
437 } |
|
438 |
|
439 impl<F : Float, G, BT, V, const N : usize> Differentiable<Loc<F, N>> |
|
440 for BTFN<F, G, BT, N> |
|
441 where BT : BTImpl<F, N>, |
|
442 G : SupportGenerator<F, N, Id=BT::Data>, |
|
443 G::SupportType : LocalAnalysis<F, BT::Agg, N> + Differentiable<Loc<F, N>, Derivative = V>, |
|
444 V : Sum { |
|
445 |
|
446 type Derivative = V; |
|
447 |
|
448 fn differential(&self, x : Loc<F, N>) -> Self::Derivative { |
|
449 self.bt.iter_at(&x) |
|
450 .map(|&d| self.generator.support_for(d).differential(x)) |
|
451 .sum() |
442 .sum() |
452 } |
443 } |
453 } |
444 } |
454 |
445 |
455 // |
446 // |
838 // 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`, |
839 // the queue may run out, and we get “Refiner failure”. |
830 // the queue may run out, and we get “Refiner failure”. |
840 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> |
841 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
832 where BT : BTSearch<F, N, Agg=Bounds<F>>, |
842 G : SupportGenerator<F, N, Id=BT::Data>, |
833 G : SupportGenerator<F, N, Id=BT::Data>, |
843 G::SupportType : Mapping<Loc<F, N>,Codomain=F> |
834 G::SupportType : Mapping<Loc<F, N>, Codomain=F> |
844 + LocalAnalysis<F, Bounds<F>, N>, |
835 + LocalAnalysis<F, Bounds<F>, N>, |
845 Cube<F, N> : P2Minimise<Loc<F, N>, F> { |
836 Cube<F, N> : P2Minimise<Loc<F, N>, F> { |
846 |
837 |
847 /// Maximise the `BTFN` within stated value `tolerance`. |
838 /// Maximise the `BTFN` within stated value `tolerance`. |
848 /// |
839 /// |