tract_linalg/generic/
erf.rs1use 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}