| 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 /// |