1#[polydat::polydat_node(category = Math)]
11fn sin(input: f64) -> f64 {
12 input.sin()
13}
14
15#[polydat::polydat_node(category = Math)]
16fn cos(input: f64) -> f64 {
17 input.cos()
18}
19
20#[polydat::polydat_node(category = Math)]
21fn tan(input: f64) -> f64 {
22 input.tan()
23}
24
25#[polydat::polydat_node(category = Math)]
26fn asin(input: f64) -> f64 {
27 input.asin()
28}
29
30#[polydat::polydat_node(category = Math)]
31fn acos(input: f64) -> f64 {
32 input.acos()
33}
34
35#[polydat::polydat_node(category = Math)]
36fn atan(input: f64) -> f64 {
37 input.atan()
38}
39
40#[polydat::polydat_node(category = Math)]
41fn sqrt(input: f64) -> f64 {
42 input.sqrt()
43}
44
45#[polydat::polydat_node(category = Math)]
46fn abs_f64(input: f64) -> f64 {
47 input.abs()
48}
49
50#[polydat::polydat_node(category = Math)]
51fn ln(input: f64) -> f64 {
52 input.ln()
53}
54
55#[polydat::polydat_node(category = Math)]
56fn exp(input: f64) -> f64 {
57 input.exp()
58}
59
60#[polydat::polydat_node(category = Math, simd = "reg_add_f64", simd_total)]
61fn f64_add(a: f64, b: f64) -> f64 {
62 a + b
63}
64
65#[polydat::polydat_node(category = Math, simd = "reg_sub_f64", simd_total)]
66fn f64_sub(a: f64, b: f64) -> f64 {
67 a - b
68}
69
70#[polydat::polydat_node(category = Math, simd = "reg_mul_f64", simd_total)]
71fn f64_mul(a: f64, b: f64) -> f64 {
72 a * b
73}
74
75#[polydat::polydat_node(category = Math)]
76fn f64_div(a: f64, b: f64) -> f64 {
77 if b != 0.0 { a / b } else { 0.0 }
78}
79
80#[polydat::polydat_node(category = Math)]
81fn f64_mod(a: f64, b: f64) -> f64 {
82 if b != 0.0 { a % b } else { 0.0 }
83}
84
85#[polydat::polydat_node(category = Math)]
97fn atan2(y: f64, x: f64) -> f64 {
98 y.atan2(x)
99}
100
101#[polydat::polydat_node(category = Math)]
103fn pow(base: f64, exponent: f64) -> f64 {
104 base.powf(exponent)
105}
106
107#[cfg(any())]
108#[cfg(test)]
109mod tests {
110 use super::*;
111 use polydat::ast::{PolydatNode, Value};
112 use std::f64::consts::PI;
113
114 #[test]
115 fn sin_known_values() {
116 let node = Sin::new();
117 let mut out = [Value::None];
118 node.eval(&[Value::F64(0.0)], &mut out);
119 assert!((out[0].as_f64() - 0.0).abs() < 1e-10);
120 node.eval(&[Value::F64(PI / 2.0)], &mut out);
121 assert!((out[0].as_f64() - 1.0).abs() < 1e-10);
122 }
123
124 #[test]
125 fn cos_known_values() {
126 let node = Cos::new();
127 let mut out = [Value::None];
128 node.eval(&[Value::F64(0.0)], &mut out);
129 assert!((out[0].as_f64() - 1.0).abs() < 1e-10);
130 node.eval(&[Value::F64(PI)], &mut out);
131 assert!((out[0].as_f64() + 1.0).abs() < 1e-10);
132 }
133
134 #[test]
135 fn sqrt_known() {
136 let node = Sqrt::new();
137 let mut out = [Value::None];
138 node.eval(&[Value::F64(4.0)], &mut out);
139 assert!((out[0].as_f64() - 2.0).abs() < 1e-10);
140 }
141
142 #[test]
143 fn atan2_quadrants() {
144 let node = Atan2::new();
145 let mut out = [Value::None];
146 node.eval(&[Value::F64(1.0), Value::F64(0.0)], &mut out);
148 assert!((out[0].as_f64() - PI / 2.0).abs() < 1e-10);
149 }
150
151 #[test]
152 fn pow_known() {
153 let node = Pow::new();
154 let mut out = [Value::None];
155 node.eval(&[Value::F64(2.0), Value::F64(10.0)], &mut out);
156 assert!((out[0].as_f64() - 1024.0).abs() < 1e-10);
157 }
158
159 #[test]
160 fn ln_exp_roundtrip() {
161 let node_ln = Ln::new();
162 let node_exp = Exp::new();
163 let mut out = [Value::None];
164 node_exp.eval(&[Value::F64(3.0)], &mut out);
165 let e3 = out[0].as_f64();
166 node_ln.eval(&[Value::F64(e3)], &mut out);
167 assert!((out[0].as_f64() - 3.0).abs() < 1e-10);
168 }
169
170 #[test]
171 fn compiled_matches_eval() {
172 let node = Sin::new();
173 let compiled = node.compiled_u64().unwrap();
174 let input = PI / 4.0;
175 let mut eval_out = [Value::None];
176 node.eval(&[Value::F64(input)], &mut eval_out);
177 let mut comp_out = [0u64];
178 compiled(&[input.to_bits()], &mut comp_out);
179 assert_eq!(eval_out[0].as_f64(), f64::from_bits(comp_out[0]));
180 }
181}