-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathcache.rs
More file actions
128 lines (121 loc) · 3.82 KB
/
cache.rs
File metadata and controls
128 lines (121 loc) · 3.82 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use super::{Derivative, PartialDerivative};
use num_dual::*;
use std::cmp::{max, min};
use std::collections::HashMap;
#[derive(Clone, Debug)]
pub(crate) struct Cache {
pub map: HashMap<PartialDerivative, f64>,
pub hit: u64,
pub miss: u64,
}
impl Cache {
pub fn with_capacity(components: usize) -> Cache {
let capacity = 6 + 3 * components + components * (components + 1) / 2;
Cache {
map: HashMap::with_capacity(capacity),
hit: 0,
miss: 0,
}
}
pub fn get_or_insert_with_f64<F: FnOnce() -> f64>(&mut self, f: F) -> f64 {
if let Some(&value) = self.map.get(&PartialDerivative::Zeroth) {
self.hit += 1;
value
} else {
self.miss += 1;
let value = f();
self.map.insert(PartialDerivative::Zeroth, value);
value
}
}
pub fn get_or_insert_with_d64<F: FnOnce() -> Dual64>(
&mut self,
derivative: Derivative,
f: F,
) -> f64 {
if let Some(&value) = self.map.get(&PartialDerivative::First(derivative)) {
self.hit += 1;
value
} else {
self.miss += 1;
let value = f();
self.map.insert(PartialDerivative::Zeroth, value.re);
self.map
.insert(PartialDerivative::First(derivative), value.eps[0]);
value.eps[0]
}
}
pub fn get_or_insert_with_d2_64<F: FnOnce() -> Dual2_64>(
&mut self,
derivative: Derivative,
f: F,
) -> f64 {
if let Some(&value) = self
.map
.get(&PartialDerivative::SecondMixed(derivative, derivative))
{
self.hit += 1;
value
} else {
self.miss += 1;
let value = f();
self.map.insert(PartialDerivative::Zeroth, value.re);
self.map
.insert(PartialDerivative::First(derivative), value.v1[0]);
self.map.insert(
PartialDerivative::SecondMixed(derivative, derivative),
value.v2[0],
);
value.v2[0]
}
}
pub fn get_or_insert_with_hd64<F: FnOnce() -> HyperDual64>(
&mut self,
derivative1: Derivative,
derivative2: Derivative,
f: F,
) -> f64 {
let d1 = min(derivative1, derivative2);
let d2 = max(derivative1, derivative2);
if let Some(&value) = self.map.get(&PartialDerivative::SecondMixed(d1, d2)) {
self.hit += 1;
value
} else {
self.miss += 1;
let value = f();
self.map.insert(PartialDerivative::Zeroth, value.re);
self.map
.insert(PartialDerivative::First(derivative1), value.eps1[0]);
self.map
.insert(PartialDerivative::First(derivative2), value.eps2[0]);
self.map.insert(
PartialDerivative::SecondMixed(d1, d2),
value.eps1eps2[(0, 0)],
);
value.eps1eps2[(0, 0)]
}
}
pub fn get_or_insert_with_hd364<F: FnOnce() -> Dual3_64>(
&mut self,
derivative: Derivative,
f: F,
) -> f64 {
if let Some(&value) = self.map.get(&PartialDerivative::Third(derivative)) {
self.hit += 1;
value
} else {
self.miss += 1;
let value = f();
self.map.insert(PartialDerivative::Zeroth, value.re);
self.map
.insert(PartialDerivative::First(derivative), value.v1);
self.map.insert(
PartialDerivative::SecondMixed(derivative, derivative),
value.v2,
);
self.map
.insert(PartialDerivative::Third(derivative), value.v3);
value.v3
}
}
}