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
use crate::{
basis::fixed::Constant,
core::Approximator,
geometry::Space,
LFA,
};
import_all!(stack);
import_all!(arithmetic);
import_all!(scaling);
import_all!(shifting);
import_all!(normalisation);
pub trait Composable: Sized {
fn lfa<A: Approximator>(self, approximator: A) -> LFA<Self, A> {
LFA::new(self, approximator)
}
fn stack<P>(self, p: P) -> Stack<Self, P> { Stack::new(self, p) }
fn add<P: Space>(self, p: P) -> Sum<Self, P>
where Self: Space {
Sum::new(self, p)
}
fn subtract<P: Space>(self, p: P) -> Sum<Self, Negate<P>>
where Self: Space {
Sum::new(self, Negate::new(p))
}
fn shift(self, offset: f64) -> Shift<Self> { Shift::new(self, offset) }
fn multiply<P: Space>(self, p: P) -> Product<Self, P>
where Self: Space {
Product::new(self, p)
}
fn divide<P: Space>(self, p: P) -> Product<Self, Reciprocal<P>>
where Self: Space {
Product::new(self, Reciprocal::new(p))
}
fn scale(self, factor: f64) -> Scale<Self> { Scale::new(self, factor) }
fn normalise_l1(self) -> L1Normalise<Self> { L1Normalise::new(self) }
fn normalise_l2(self) -> L2Normalise<Self> { L2Normalise::new(self) }
fn normalise_lp(self, p: u8) -> LpNormalise<Self> { LpNormalise::new(self, p) }
fn normalise_linf(self) -> LinfNormalise<Self> { LinfNormalise::new(self) }
fn with_constant(self) -> Stack<Self, Constant> {
self.stack(Constant::ones(1))
}
}
impl<T> Composable for T {}
#[cfg(test)]
mod tests {
use crate::{
basis::{fixed::Constant, Projector},
composition::Stack,
};
use quickcheck::quickcheck;
use super::Composable;
#[test]
fn test_stack_constant() {
fn prop_equivalency(input: Vec<f64>) -> bool {
let p1 = Stack::new(Constant::zeros(10), Constant::ones(10));
let p2 = Constant::zeros(10).stack(Constant::ones(10));
p1.project(&input) == p2.project(&input)
}
quickcheck(prop_equivalency as fn(Vec<f64>) -> bool);
}
}