|    218                         SupportProductFirst(ref cut, | 
   218                         SupportProductFirst(ref cut, | 
|    219                                             ref gaussian)) = self; | 
   219                                             ref gaussian)) = self; | 
|    220         let a = cut.r.value(); | 
   220         let a = cut.r.value(); | 
|    221         let b = ind.r.value(); | 
   221         let b = ind.r.value(); | 
|    222         let σ = gaussian.variance.value().sqrt(); | 
   222         let σ = gaussian.variance.value().sqrt(); | 
|    223         let π = F::PI; | 
        | 
|    224         let t = F::SQRT_2 * σ; | 
   223         let t = F::SQRT_2 * σ; | 
|    225         let c = σ * (8.0/π).sqrt(); | 
   224         let c = 0.5; // 1/(σ√(2π) * σ√(π/2) = 1/2 | 
|    226          | 
   225          | 
|    227         // This is just a product of one-dimensional versions | 
   226         // This is just a product of one-dimensional versions | 
|    228         let unscaled = y.product_map(|x| { | 
   227         y.product_map(|x| { | 
|    229             let c1 = -(a.min(b + x)); //(-a).max(-x-b); | 
   228             let c1 = -(a.min(b + x)); //(-a).max(-x-b); | 
|    230             let c2 = a.min(b - x); | 
   229             let c2 = a.min(b - x); | 
|    231             if c1 >= c2 { | 
   230             if c1 >= c2 { | 
|    232                 0.0 | 
   231                 0.0 | 
|    233             } else { | 
   232             } else { | 
|    234                 let e1 = F::cast_from(erf((c1 / t).as_())); | 
   233                 let e1 = F::cast_from(erf((c1 / t).as_())); | 
|    235                 let e2 = F::cast_from(erf((c2 / t).as_())); | 
   234                 let e2 = F::cast_from(erf((c2 / t).as_())); | 
|    236                 debug_assert!(e2 >= e1); | 
   235                 debug_assert!(e2 >= e1); | 
|    237                 c * (e2 - e1) | 
   236                 c * (e2 - e1) | 
|    238             } | 
   237             } | 
|    239         }); | 
   238         }) | 
|    240          | 
        | 
|    241         unscaled / gaussian.scale() | 
        | 
|    242     } | 
   239     } | 
|    243 } | 
   240 } | 
|    244  | 
   241  | 
|    245 impl<F : Float, R, C, S, const N : usize> Apply<Loc<F, N>> | 
   242 impl<F : Float, R, C, S, const N : usize> Apply<Loc<F, N>> | 
|    246 for Convolution<CubeIndicator<R, N>, BasicCutGaussian<C, S, N>> | 
   243 for Convolution<CubeIndicator<R, N>, BasicCutGaussian<C, S, N>> | 
|    274                         SupportProductFirst(ref cut, | 
   271                         SupportProductFirst(ref cut, | 
|    275                                             ref gaussian)) = self; | 
   272                                             ref gaussian)) = self; | 
|    276         let a = cut.r.value(); | 
   273         let a = cut.r.value(); | 
|    277         let b = ind.r.value(); | 
   274         let b = ind.r.value(); | 
|    278         let σ = gaussian.variance.value().sqrt(); | 
   275         let σ = gaussian.variance.value().sqrt(); | 
|    279         let π = F::PI; | 
        | 
|    280         let t = F::SQRT_2 * σ; | 
   276         let t = F::SQRT_2 * σ; | 
|    281         let c = σ * (8.0/π).sqrt(); | 
   277         let c = 0.5; // 1/(σ√(2π) * σ√(π/2) = 1/2 | 
|    282         let cd = (8.0).sqrt(); // σ * (8.0/π).sqrt() / t * (√2/π) | 
   278         let c_div_t = c / t; | 
|    283          | 
   279          | 
|    284         // Calculate the values for all component functions of the | 
   280         // Calculate the values for all component functions of the | 
|    285         // product. This is just the loop from apply above. | 
   281         // product. This is just the loop from apply above. | 
|    286         let unscaled_vs = y.map(|x| { | 
   282         let unscaled_vs = y.map(|x| { | 
|    287             let c1 = -(a.min(b + x)); //(-a).max(-x-b); | 
   283             let c1 = -(a.min(b + x)); //(-a).max(-x-b); | 
|    304             } else { | 
   300             } else { | 
|    305                 // erf'(z) = (2/√π)*exp(-z^2), and we get extra factor -1/√(2*σ) = -1/t | 
   301                 // erf'(z) = (2/√π)*exp(-z^2), and we get extra factor -1/√(2*σ) = -1/t | 
|    306                 // from the chain rule | 
   302                 // from the chain rule | 
|    307                 let de1 = (-(c1/t).powi(2)).exp(); | 
   303                 let de1 = (-(c1/t).powi(2)).exp(); | 
|    308                 let de2 = (-(c2/t).powi(2)).exp(); | 
   304                 let de2 = (-(c2/t).powi(2)).exp(); | 
|    309                 cd * (de1 - de2) | 
   305                 c_div_t * (de1 - de2) | 
|    310             } | 
   306             } | 
|    311         }) / gaussian.scale() | 
   307         }) | 
|    312     } | 
   308     } | 
|    313 } | 
   309 } | 
|    314  | 
   310  | 
|    315 impl<F : Float, R, C, S, const N : usize> Differentiable<Loc<F, N>> | 
   311 impl<F : Float, R, C, S, const N : usize> Differentiable<Loc<F, N>> | 
|    316 for Convolution<CubeIndicator<R, N>, BasicCutGaussian<C, S, N>> | 
   312 for Convolution<CubeIndicator<R, N>, BasicCutGaussian<C, S, N>> |