| 186 SupportProductFirst(ref cut, |
186 SupportProductFirst(ref cut, |
| 187 ref gaussian)) = self; |
187 ref gaussian)) = self; |
| 188 let a = cut.r.value(); |
188 let a = cut.r.value(); |
| 189 let b = ind.r.value(); |
189 let b = ind.r.value(); |
| 190 let σ = gaussian.variance.value().sqrt(); |
190 let σ = gaussian.variance.value().sqrt(); |
| 191 let π = F::PI; |
|
| 192 let t = F::SQRT_2 * σ; |
191 let t = F::SQRT_2 * σ; |
| 193 let c = σ * (8.0/π).sqrt(); |
192 let c = 0.5; // 1/(σ√(2π) * σ√(π/2) = 1/2 |
| 194 |
193 |
| 195 // This is just a product of one-dimensional versions |
194 // This is just a product of one-dimensional versions |
| 196 let unscaled = y.product_map(|x| { |
195 y.product_map(|x| { |
| 197 let c1 = -(a.min(b + x)); //(-a).max(-x-b); |
196 let c1 = -(a.min(b + x)); //(-a).max(-x-b); |
| 198 let c2 = a.min(b - x); |
197 let c2 = a.min(b - x); |
| 199 if c1 >= c2 { |
198 if c1 >= c2 { |
| 200 0.0 |
199 0.0 |
| 201 } else { |
200 } else { |
| 202 let e1 = F::cast_from(erf((c1 / t).as_())); |
201 let e1 = F::cast_from(erf((c1 / t).as_())); |
| 203 let e2 = F::cast_from(erf((c2 / t).as_())); |
202 let e2 = F::cast_from(erf((c2 / t).as_())); |
| 204 debug_assert!(e2 >= e1); |
203 debug_assert!(e2 >= e1); |
| 205 c * (e2 - e1) |
204 c * (e2 - e1) |
| 206 } |
205 } |
| 207 }); |
206 }) |
| 208 |
|
| 209 unscaled / gaussian.scale() |
|
| 210 } |
207 } |
| 211 } |
208 } |
| 212 |
209 |
| 213 impl<F : Float, R, C, S, const N : usize> Apply<Loc<F, N>> |
210 impl<F : Float, R, C, S, const N : usize> Apply<Loc<F, N>> |
| 214 for Convolution<CubeIndicator<R, N>, BasicCutGaussian<C, S, N>> |
211 for Convolution<CubeIndicator<R, N>, BasicCutGaussian<C, S, N>> |