1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use num_traits::{FromPrimitive, Num, One, Signed, Zero};
use tinyvec::tiny_vec;
use crate::f64ad::{f64ad, NodeType, f64ad_locked_var_operation_one_parent};
impl Zero for f64ad {
fn zero() -> Self {
return f64ad::f64(0.0);
}
fn is_zero(&self) -> bool {
return self.value() == 0.0
}
}
impl One for f64ad {
fn one() -> Self {
Self::f64(1.0)
}
}
impl Num for f64ad {
type FromStrRadixErr = ();
fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
let val = f64::from_str_radix(str, radix).expect("error");
Ok(Self::f64(val))
}
}
impl Signed for f64ad {
fn abs(&self) -> Self {
return match self {
f64ad::f64ad_var(f) => {
let res = f.computation_graph.add_node(NodeType::Abs, tiny_vec!([u32; 2] => f.node_idx), tiny_vec!([f64; 1]));
f64ad::f64ad_var(res)
}
f64ad::f64ad_locked_var(f) => {
f64ad::f64ad_locked_var(f64ad_locked_var_operation_one_parent(f, None, NodeType::Abs))
}
f64ad::f64(f) => {
f64ad::f64(f.abs())
}
}
}
fn abs_sub(&self, other: &Self) -> Self {
return if *self <= *other {
f64ad::f64(0.0)
} else {
*self - *other
}
}
fn signum(&self) -> Self {
return match self {
f64ad::f64ad_var(f) => {
let res = f.computation_graph.add_node(NodeType::Signum, tiny_vec!([u32; 2] => f.node_idx), tiny_vec!([f64; 1]));
f64ad::f64ad_var(res)
}
f64ad::f64ad_locked_var(f) => {
f64ad::f64ad_locked_var(f64ad_locked_var_operation_one_parent(f, None, NodeType::Signum))
}
f64ad::f64(f) => {
f64ad::f64(f.signum())
}
}
}
fn is_positive(&self) -> bool {
return self.value() > 0.0;
}
fn is_negative(&self) -> bool {
return self.value() < 0.0;
}
}
impl FromPrimitive for f64ad {
fn from_i64(n: i64) -> Option<Self> {
Some(f64ad::f64(n as f64))
}
fn from_u64(n: u64) -> Option<Self> {
Some(f64ad::f64(n as f64))
}
}