linalgo_structs/lib.rs
1/// A square matrix with a fixed size
2pub struct SquareMatrix<T> {
3    size: usize,
4    data: Vec<Vec<Option<T>>>,
5}
6
7impl<T: Clone> SquareMatrix<T> {
8    /// Creates an empty square matrix with given size and initializes all values to None
9    ///
10    /// # Examples
11    ///
12    /// ```
13    /// use linalgo_structs::SquareMatrix;
14    ///
15    /// let matrix: SquareMatrix<i32> = SquareMatrix::new(10);
16    /// ```
17    ///
18    /// # Panics
19    ///
20    /// Zero dimensional matrices aren't allowed, so we panic if the size is less than 1.
21    pub fn new(size: usize) -> Self {
22        if size == 0 {
23            panic!("Matrix size must be at least 1, got {}", size);
24        }
25
26        let mut row: Vec<Option<T>> = Vec::new();
27        row.resize(size, None);
28
29        let mut data: Vec<Vec<Option<T>>> = Vec::new();
30        data.resize(size, row);
31
32        Self { size, data }
33    }
34
35    /// Returns the size of the matrix
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use linalgo_structs::SquareMatrix;
41    ///
42    /// let matrix: SquareMatrix<i32> = SquareMatrix::new(10);
43    ///
44    /// assert_eq!(matrix.size(), 10);
45    /// ```
46    pub fn size(&self) -> usize {
47        self.size
48    }
49
50    /// Returns a reference to the value at the given position. Returns None if nothing is found
51    /// or if the position is not valid.
52    ///
53    /// # Examples
54    ///
55    /// ```
56    /// use linalgo_structs::SquareMatrix;
57    ///
58    /// let matrix: SquareMatrix<i32> = SquareMatrix::new(10);
59    ///
60    /// assert_eq!(matrix.get(0, 0), None);
61    /// ```
62    ///
63    /// ```
64    /// use linalgo_structs::SquareMatrix;
65    ///
66    /// let mut matrix: SquareMatrix<i32> = SquareMatrix::new(10);
67    /// matrix.set(5, 5, 10);
68    ///
69    /// assert_eq!(matrix.get(5, 5), Some(10).as_ref());
70    /// ```
71    pub fn get(&self, row: usize, column: usize) -> Option<&T> {
72        if let Some(row) = self.data.get(row) {
73            if let Some(entry) = row.get(column) {
74                return entry.as_ref();
75            }
76        }
77
78        None
79    }
80
81    /// Moves `value` into the matrix at the given position. Consumes `value`.
82    ///
83    /// # Examples
84    ///
85    /// ```
86    /// use linalgo_structs::SquareMatrix;
87    ///
88    /// let mut matrix: SquareMatrix<i32> = SquareMatrix::new(10);
89    ///
90    /// matrix.set(0, 0, 5);
91    /// matrix.set(5, 5, 0);
92    ///
93    /// assert_eq!(matrix.get(0, 0), Some(5).as_ref());
94    /// assert_eq!(matrix.get(5, 5), Some(0).as_ref());
95    /// assert_eq!(matrix.get(2, 2), None);
96    pub fn set(&mut self, row: usize, column: usize, value: T) {
97        if let Some(row) = self.data.get_mut(row) {
98            if let Some(entry) = row.get_mut(column) {
99                *entry = Some(value.to_owned());
100            }
101        }
102    }
103
104    /// Clones `value` into every valid position in the matrix. Does not consume `value`.
105    ///
106    /// # Examples
107    ///
108    /// ```
109    /// use linalgo_structs::SquareMatrix;
110    ///
111    /// let mut matrix: SquareMatrix<i32> = SquareMatrix::new(10);
112    /// matrix.set_all_to(&2);
113    ///
114    /// assert_eq!(matrix.get(0, 0), Some(2).as_ref());
115    /// assert_eq!(matrix.get(1, 1), Some(2).as_ref());
116    /// assert_eq!(matrix.get(2, 2), Some(2).as_ref());
117    /// assert_eq!(matrix.get(9, 9), Some(2).as_ref());
118    pub fn set_all_to(&mut self, value: &T) {
119        for row in self.data.iter_mut() {
120            for entry in row.iter_mut() {
121                *entry = Some(value.clone());
122            }
123        }
124    }
125}
126
127/// A vector with a fixed size
128pub struct Vector<T> {
129    size: usize,
130    data: Vec<Option<T>>,
131}
132
133impl<T: Clone> Vector<T> {
134    /// Creates an empty vector with given size and initializes all values to None
135    ///
136    /// # Examples
137    ///
138    /// ```
139    /// use linalgo_structs::Vector;
140    ///
141    /// let vector: Vector<i32> = Vector::new(5);
142    /// ```
143    ///
144    /// # Panics
145    ///
146    /// Zero dimensional vectors aren't allowed, so we panic if the size is less than 1.
147    pub fn new(size: usize) -> Self {
148        if size == 0 {
149            panic!("Vector size must be at least 1, got {}", size);
150        }
151
152        let mut data: Vec<Option<T>> = Vec::new();
153        data.resize(size, None);
154
155        Self { size, data }
156    }
157
158    /// Returns the size of the vector
159    ///
160    /// # Examples
161    ///
162    /// ```
163    /// use linalgo_structs::Vector;
164    ///
165    /// let vector: Vector<i32> = Vector::new(10);
166    ///
167    /// assert_eq!(vector.size(), 10);
168    /// ```
169    pub fn size(&self) -> usize {
170        self.size
171    }
172
173    /// Returns a reference to the value at the given position. Returns None if nothing is found
174    /// or if the position is not valid.
175    ///
176    /// # Examples
177    ///
178    /// ```
179    /// use linalgo_structs::Vector;
180    ///
181    /// let vector: Vector<i32> = Vector::new(10);
182    ///
183    /// assert_eq!(vector.get(0), None);
184    /// ```
185    ///
186    /// ```
187    /// use linalgo_structs::Vector;
188    ///
189    /// let mut vector: Vector<i32> = Vector::new(10);
190    /// vector.set(5, 10);
191    ///
192    /// assert_eq!(vector.get(5), Some(10).as_ref());
193    /// ```
194    pub fn get(&self, position: usize) -> Option<&T> {
195        self.data.get(position)?.as_ref()
196    }
197
198    /// Moves `value` into the vector at the given position. Consumes `value`.
199    ///
200    /// # Examples
201    ///
202    /// ```
203    /// use linalgo_structs::Vector;
204    ///
205    /// let mut vector: Vector<i32> = Vector::new(10);
206    ///
207    /// vector.set(0, 5);
208    /// vector.set(5, 0);
209    ///
210    /// assert_eq!(vector.get(0), Some(5).as_ref());
211    /// assert_eq!(vector.get(5), Some(0).as_ref());
212    /// assert_eq!(vector.get(2), None);
213    pub fn set(&mut self, position: usize, value: T) {
214        if let Some(entry) = self.data.get_mut(position) {
215            *entry = Some(value.to_owned());
216        }
217    }
218
219    /// Clones `value` into every valid position in the matrix. Does not consume `value`.
220    ///
221    /// # Examples
222    ///
223    /// ```
224    /// use linalgo_structs::Vector;
225    ///
226    /// let mut vector: Vector<i32> = Vector::new(10);
227    /// vector.set_all_to(&2);
228    ///
229    /// assert_eq!(vector.get(0), Some(2).as_ref());
230    /// assert_eq!(vector.get(1), Some(2).as_ref());
231    /// assert_eq!(vector.get(2), Some(2).as_ref());
232    /// assert_eq!(vector.get(9), Some(2).as_ref());
233    pub fn set_all_to(&mut self, value: &T) {
234        for entry in self.data.iter_mut() {
235            *entry = Some(value.clone());
236        }
237    }
238}