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
use crate::{Interval, Equipartition, prelude::*};
use std::{
fmt::{self, Display},
ops::Index,
slice::Iter as SliceIter,
};
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct TwoSpace<D>([D; 2]);
impl<D> TwoSpace<D> {
pub fn new(ds: [D; 2]) -> Self { TwoSpace(ds) }
pub fn iter(&self) -> SliceIter<D> { self.0.iter() }
}
impl TwoSpace<Interval> {
pub fn equipartitioned(self, density: usize) -> TwoSpace<Equipartition> {
TwoSpace([
Equipartition::from_interval(self[0], density),
Equipartition::from_interval(self[1], density),
])
}
}
impl<D: Space> Space for TwoSpace<D> {
type Value = [D::Value; 2];
fn dim(&self) -> Dim { self[0].dim() + self[1].dim() }
fn card(&self) -> Card { self[0].card() * self[1].card() }
}
impl<D: Union + Clone> Union for TwoSpace<D> {
fn union(self, other: &Self) -> Self {
let TwoSpace([d1, d2]) = self;
[d1.union(&other[0]), d2.union(&other[1])].into()
}
}
impl<D: Intersection + Clone> Intersection for TwoSpace<D> {
fn intersect(self, other: &Self) -> Self {
let TwoSpace([d1, d2]) = self;
[d1.intersect(&other[0]), d2.intersect(&other[1])].into()
}
}
impl<D, X> Surjection<[X; 2], [D::Value; 2]> for TwoSpace<D>
where
D: Space + Surjection<X, <D as Space>::Value>,
X: Clone,
{
fn map_onto(&self, val: [X; 2]) -> [D::Value; 2] {
[self[0].map_onto(val[0].clone()), self[1].map_onto(val[1].clone())]
}
}
impl<D> Index<usize> for TwoSpace<D> {
type Output = D;
fn index(&self, idx: usize) -> &D { self.0.index(idx) }
}
impl<D: Clone> From<[D; 2]> for TwoSpace<D> {
fn from(pair: [D; 2]) -> TwoSpace<D> {
TwoSpace::new(pair.clone())
}
}
impl<D: Space + Display> fmt::Display for TwoSpace<D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self[0], self[1])
}
}
#[cfg(test)]
mod tests {
use crate::discrete::Ordinal;
use super::*;
#[test]
fn test_dim() {
assert_eq!(TwoSpace::new([Ordinal::new(2), Ordinal::new(2)]).dim(), Dim::Finite(2));
}
#[test]
fn test_card() {
assert_eq!(
TwoSpace::new([Ordinal::new(2), Ordinal::new(2)]).card(),
Card::Finite(4)
);
}
#[test]
fn test_partitioned() {
let ps = TwoSpace::new([
Interval::bounded(0.0, 5.0),
Interval::bounded(1.0, 2.0)
]).equipartitioned(5);
assert_eq!(ps[0], Equipartition::new(0.0, 5.0, 5));
assert_eq!(ps[1], Equipartition::new(1.0, 2.0, 5));
}
#[test]
fn test_surjection() {
let ps = TwoSpace::new([
Interval::bounded(0.0, 5.0),
Interval::bounded(1.0, 2.0)
]);
assert_eq!(ps.map_onto([6.0, 0.0]), [5.0, 1.0]);
assert_eq!(ps.map_onto([2.5, 1.5]), [2.5, 1.5]);
assert_eq!(ps.map_onto([-1.0, 10.0]), [0.0, 2.0]);
}
}