1 |
1 |
2 //! Implementation of the standard mollifier |
2 //! Implementation of the standard mollifier |
3 |
3 |
4 use rgsl::hypergeometric::hyperg_U; |
4 use rgsl::hypergeometric::hyperg_U; |
5 use float_extras::f64::{tgamma as gamma}; |
5 use float_extras::f64::tgamma as gamma; |
6 use numeric_literals::replace_float_literals; |
6 use numeric_literals::replace_float_literals; |
7 use serde::Serialize; |
7 use serde::Serialize; |
8 use alg_tools::types::*; |
8 use alg_tools::types::*; |
9 use alg_tools::euclidean::Euclidean; |
9 use alg_tools::euclidean::Euclidean; |
10 use alg_tools::norms::*; |
10 use alg_tools::norms::*; |
15 Constant, |
15 Constant, |
16 Bounds, |
16 Bounds, |
17 LocalAnalysis, |
17 LocalAnalysis, |
18 GlobalAnalysis |
18 GlobalAnalysis |
19 }; |
19 }; |
20 use alg_tools::mapping::Apply; |
20 use alg_tools::mapping::{Mapping, Instance}; |
21 use alg_tools::maputil::array_init; |
21 use alg_tools::maputil::array_init; |
22 |
22 |
23 /// Reresentation of the (unnormalised) standard mollifier. |
23 /// Reresentation of the (unnormalised) standard mollifier. |
24 /// |
24 /// |
25 /// For the `width` parameter $ε>0$, this is |
25 /// For the `width` parameter $ε>0$, this is |
34 /// The parameter $ε$ of the mollifier. |
34 /// The parameter $ε$ of the mollifier. |
35 pub width : C, |
35 pub width : C, |
36 } |
36 } |
37 |
37 |
38 #[replace_float_literals(C::Type::cast_from(literal))] |
38 #[replace_float_literals(C::Type::cast_from(literal))] |
39 impl<'a, C : Constant, const N : usize> Apply<&'a Loc<C::Type, N>> for Mollifier<C, N> { |
39 impl<C : Constant, const N : usize> Mapping<Loc<C::Type, N>> for Mollifier<C, N> { |
40 type Output = C::Type; |
40 type Codomain = C::Type; |
|
41 |
41 #[inline] |
42 #[inline] |
42 fn apply(&self, x : &'a Loc<C::Type, N>) -> Self::Output { |
43 fn apply<I : Instance<Loc<C::Type, N>>>(&self, x : I) -> Self::Codomain { |
43 let ε = self.width.value(); |
44 let ε = self.width.value(); |
44 let ε2 = ε*ε; |
45 let ε2 = ε*ε; |
45 let n2 = x.norm2_squared(); |
46 let n2 = x.eval(|x| x.norm2_squared()); |
46 if n2 < ε2 { |
47 if n2 < ε2 { |
47 (n2 / (n2 - ε2)).exp() |
48 (n2 / (n2 - ε2)).exp() |
48 } else { |
49 } else { |
49 0.0 |
50 0.0 |
50 } |
51 } |
51 } |
52 } |
52 } |
53 } |
53 |
54 |
54 impl<C : Constant, const N : usize> Apply<Loc<C::Type, N>> for Mollifier<C, N> { |
|
55 type Output = C::Type; |
|
56 #[inline] |
|
57 fn apply(&self, x : Loc<C::Type, N>) -> Self::Output { |
|
58 self.apply(&x) |
|
59 } |
|
60 } |
|
61 |
55 |
62 impl<'a, C : Constant, const N : usize> Support<C::Type, N> for Mollifier<C, N> { |
56 impl<'a, C : Constant, const N : usize> Support<C::Type, N> for Mollifier<C, N> { |
63 #[inline] |
57 #[inline] |
64 fn support_hint(&self) -> Cube<C::Type,N> { |
58 fn support_hint(&self) -> Cube<C::Type,N> { |
65 let ε = self.width.value(); |
59 let ε = self.width.value(); |