tract_linalg/generic/
erf.rs

1use crate::element_wise::ElementWiseKer;
2
3#[allow(non_upper_case_globals)]
4#[allow(clippy::excessive_precision)]
5fn serf(x: &mut f32) {
6    const a1: f32 = 0.0705230784;
7    const a2: f32 = 0.0422820123;
8    const a3: f32 = 0.0092705272;
9    const a4: f32 = 0.0001520143;
10    const a5: f32 = 0.0002765672;
11    const a6: f32 = 0.0000430638;
12
13    let signum = x.signum();
14    let abs = x.abs();
15    let y = a6 * abs;
16    let y = (a5 + y) * abs;
17    let y = (a4 + y) * abs;
18    let y = (a3 + y) * abs;
19    let y = (a2 + y) * abs;
20    let y = (a1 + y) * abs;
21    let y = 1.0 - (y + 1.0).powi(16).recip();
22
23    *x = y.copysign(signum)
24}
25
26#[derive(Clone, Debug)]
27pub struct SErf4;
28
29impl ElementWiseKer<f32> for SErf4 {
30    fn name() -> &'static str {
31        "generic"
32    }
33
34    fn alignment_items() -> usize {
35        16
36    }
37
38    fn alignment_bytes() -> usize {
39        16
40    }
41
42    fn nr() -> usize {
43        4
44    }
45
46    fn run(x: &mut [f32], _: ()) {
47        debug_assert!(x.len() % Self::nr() == 0);
48        debug_assert!(x.as_ptr() as usize % Self::alignment_bytes() == 0);
49        x.iter_mut().for_each(serf)
50    }
51}