spaces/
lib.rs

1//! Set/space primitives for defining machine learning problems.
2//!
3//! `spaces` provides set/space primitives to be used for defining properties of
4//! machine learning problems. Traits such as `Space`, and it's derivatives, may
5//! be used to define state/action spaces, for example. Mappings between
6//! different spaces may also be defined using traits such as `Surjection` to
7//! streamline many common preprocessing and type conversion tasks.
8extern crate itertools;
9extern crate num_traits;
10
11#[cfg(feature = "serialize")]
12#[macro_use]
13extern crate serde;
14
15mod macros;
16
17import_all!(card);
18
19pub mod discrete;
20pub mod real;
21
22import_all!(interval);
23import_all!(partition);
24
25import_all!(arrays);
26import_all!(tuples);
27
28pub type Euclidean<const N: usize> = [real::Reals; N];
29
30pub type Intervals<const N: usize> = [Interval; N];
31
32/// Trait for defining geometric spaces.
33pub trait Space {
34    /// The dimensionality of the space.
35    const DIM: usize;
36
37    /// The data representation of elements of the space.
38    type Value: Clone;
39
40    /// Return the number of elements in the set comprising the space.
41    fn card(&self) -> Card;
42
43    /// Returns true iff `val` is contained within the space.
44    fn contains(&self, val: &Self::Value) -> bool;
45}
46
47impl<D: Space> Space for Box<D> {
48    const DIM: usize = D::DIM;
49
50    type Value = D::Value;
51
52    fn card(&self) -> Card { (**self).card() }
53
54    fn contains(&self, val: &Self::Value) -> bool { (**self).contains(val) }
55}
56
57impl<'a, D: Space> Space for &'a D {
58    const DIM: usize = D::DIM;
59
60    type Value = D::Value;
61
62    fn card(&self) -> Card { (**self).card() }
63
64    fn contains(&self, val: &Self::Value) -> bool { (**self).contains(val) }
65}
66
67pub trait OrderedSpace: Space
68where Self::Value: PartialOrd
69{
70    /// Returns the value of the space's minimum value, if it exists.
71    fn min(&self) -> Option<Self::Value> { None }
72
73    /// Return the infimum of the space.
74    fn inf(&self) -> Option<Self::Value> { self.min() }
75
76    /// Returns the value of the dimension's supremum, if it exists.
77    fn max(&self) -> Option<Self::Value> { None }
78
79    /// Returns the supremum of the space.
80    fn sup(&self) -> Option<Self::Value> { self.max() }
81
82    /// Returns true iff `self` has a well-defined infimum.
83    fn is_lower_bounded(&self) -> bool { self.inf().is_some() }
84
85    /// Returns true iff `self` has a well-defined supremum.
86    fn is_upper_bounded(&self) -> bool { self.sup().is_some() }
87
88    /// Returns true iff `self` has a well-defined minimum and maximum.
89    fn is_bounded(&self) -> bool { self.is_lower_bounded() && self.is_upper_bounded() }
90}
91
92/// Trait for defining spaces containing a finite set of values.
93pub trait FiniteSpace: Space {
94    fn to_ordinal(&self) -> ::std::ops::Range<usize> {
95        0..self
96            .card()
97            .expect_finite("Finite spaces must have finite cardinality.")
98    }
99}
100
101/// Trait for types that can be combined in the form of a union.
102///
103/// The union of a collection of sets is the set that contains all elements in
104/// the collection.
105pub trait Union<S = Self> {
106    /// Return a space enclosing `self` and `other` of type `Self`.
107    fn union(self, other: &S) -> Self;
108
109    /// Return a space enclosing `self` and all `other_spaces` of
110    /// type `Self`.
111    fn union_many(self, other_spaces: &[S]) -> Self
112    where Self: Sized {
113        other_spaces
114            .into_iter()
115            .fold(self, |acc, other_space| acc.union(other_space))
116    }
117}
118
119/// Trait for types that can be combined in the form of an intersection.
120///
121/// The intersection of a collection of sets is the set that contains only those
122/// elements present in each.
123pub trait Intersect<S = Self> {
124    /// Return the smallest space enclosing `self` and `other` of type `Self`.
125    fn intersect(self, other: &S) -> Self;
126
127    /// Return the smallest space enclosing `self` and all `other_spaces` of
128    /// type `Self`.
129    fn intersect_many(self, other_spaces: &[S]) -> Self
130    where Self: Sized {
131        other_spaces
132            .into_iter()
133            .fold(self, |acc, other_space| acc.intersect(other_space))
134    }
135}
136
137mod prelude {
138    pub use super::{Card, FiniteSpace, Intersect, OrderedSpace, Space, Union};
139}