matrix/format/conventional/
mod.rs1use std::ops::{Deref, DerefMut, Index, IndexMut};
6use std::ptr;
7
8use {Element, Matrix, Position, Size};
9
10#[derive(Clone, Debug, PartialEq)]
12pub struct Conventional<T: Element> {
13 pub rows: usize,
15 pub columns: usize,
17 pub values: Vec<T>,
19}
20
21macro_rules! new(
22 ($rows:expr, $columns:expr, $values:expr) => (
23 Conventional {
24 rows: $rows,
25 columns: $columns,
26 values: $values,
27 }
28 );
29);
30
31mod convert;
32mod decomposition;
33mod operation;
34
35size!(Conventional);
36
37impl<T: Element> Conventional<T> {
38 pub fn new<S: Size>(size: S) -> Self {
40 let (rows, columns) = size.dimensions();
41 new!(rows, columns, vec![T::zero(); rows * columns])
42 }
43
44 pub fn from_slice<S: Size>(size: S, values: &[T]) -> Self {
46 let (rows, columns) = size.dimensions();
47 debug_assert_eq!(values.len(), rows * columns);
48 new!(rows, columns, values.to_vec())
49 }
50
51 pub fn from_vec<S: Size>(size: S, values: Vec<T>) -> Self {
53 let (rows, columns) = size.dimensions();
54 debug_assert_eq!(values.len(), rows * columns);
55 new!(rows, columns, values)
56 }
57
58 pub unsafe fn with_uninitialized<S: Size>(size: S) -> Self {
60 let (rows, columns) = size.dimensions();
61 new!(rows, columns, buffer!(rows * columns))
62 }
63
64 #[inline]
69 pub unsafe fn erase(&mut self) {
70 ptr::write_bytes(self.values.as_mut_ptr(), 0, self.values.len())
71 }
72
73 pub fn resize<S: Size>(&mut self, size: S) {
75 let (rows, columns) = size.dimensions();
76 if self.rows == rows {
77 if self.columns > columns {
78 self.values.truncate(rows * columns);
79 } else {
80 self.values
81 .extend(vec![T::zero(); rows * (columns - self.columns)]);
82 }
83 self.columns = columns;
84 } else {
85 let mut matrix = Conventional::zero(size);
86 let rows = min!(self.rows, rows);
87 let columns = min!(self.columns, columns);
88 for j in 0..columns {
89 for i in 0..rows {
90 matrix[(i, j)] = self[(i, j)];
91 }
92 }
93 *self = matrix;
94 }
95 }
96}
97
98impl<T: Element> Matrix for Conventional<T> {
99 type Element = T;
100
101 fn nonzeros(&self) -> usize {
102 self.values
103 .iter()
104 .fold(0, |sum, &value| if value.is_zero() { sum } else { sum + 1 })
105 }
106
107 #[inline]
108 fn zero<S: Size>(size: S) -> Self {
109 Conventional::new(size)
110 }
111}
112
113impl<T: Element, P: Position> Index<P> for Conventional<T> {
114 type Output = T;
115
116 #[inline(always)]
117 fn index(&self, index: P) -> &Self::Output {
118 let (i, j) = index.coordinates();
119 &self.values[j * self.rows + i]
120 }
121}
122
123impl<T: Element, P: Position> IndexMut<P> for Conventional<T> {
124 #[inline(always)]
125 fn index_mut(&mut self, index: P) -> &mut Self::Output {
126 let (i, j) = index.coordinates();
127 &mut self.values[j * self.rows + i]
128 }
129}
130
131impl<T: Element> Deref for Conventional<T> {
132 type Target = [T];
133
134 #[inline]
135 fn deref(&self) -> &Self::Target {
136 self.values.deref()
137 }
138}
139
140impl<T: Element> DerefMut for Conventional<T> {
141 #[inline]
142 fn deref_mut(&mut self) -> &mut Self::Target {
143 self.values.deref_mut()
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use prelude::*;
150
151 #[test]
152 fn erase() {
153 let mut matrix = Conventional::from_vec(10, vec![42.0; 10 * 10]);
154 unsafe { matrix.erase() };
155 assert!(matrix.iter().all(|&value| value == 0.0));
156 }
157
158 #[test]
159 fn resize_fewer_columns() {
160 let mut matrix = Conventional::from_vec((2, 3), vec![1.0, 4.0, 2.0, 5.0, 3.0, 6.0]);
161 matrix.resize((2, 2));
162 assert_eq!(
163 matrix,
164 Conventional::from_vec(
165 (2, 2),
166 matrix![
167 1.0, 2.0;
168 4.0, 5.0;
169 ],
170 )
171 );
172 }
173
174 #[test]
175 fn resize_fewer_rows() {
176 let mut matrix = Conventional::from_vec((2, 3), vec![1.0, 4.0, 2.0, 5.0, 3.0, 6.0]);
177 matrix.resize((1, 3));
178 assert_eq!(
179 matrix,
180 Conventional::from_vec(
181 (1, 3),
182 matrix![
183 1.0, 2.0, 3.0;
184 ],
185 )
186 );
187 }
188
189 #[test]
190 fn resize_more_columns() {
191 let mut matrix = Conventional::from_vec((2, 3), vec![1.0, 4.0, 2.0, 5.0, 3.0, 6.0]);
192 matrix.resize((2, 4));
193 assert_eq!(
194 matrix,
195 Conventional::from_vec(
196 (2, 4),
197 matrix![
198 1.0, 2.0, 3.0, 0.0;
199 4.0, 5.0, 6.0, 0.0;
200 ],
201 )
202 );
203 }
204
205 #[test]
206 fn resize_more_rows() {
207 let mut matrix = Conventional::from_vec((2, 3), vec![1.0, 4.0, 2.0, 5.0, 3.0, 6.0]);
208 matrix.resize((3, 3));
209 assert_eq!(
210 matrix,
211 Conventional::from_vec(
212 (3, 3),
213 matrix![
214 1.0, 2.0, 3.0;
215 4.0, 5.0, 6.0;
216 0.0, 0.0, 0.0;
217 ],
218 )
219 );
220 }
221
222 #[test]
223 fn resize_more_columns_rows() {
224 let mut matrix = Conventional::from_vec((2, 3), vec![1.0, 4.0, 2.0, 5.0, 3.0, 6.0]);
225 matrix.resize((3, 4));
226 assert_eq!(
227 matrix,
228 Conventional::from_vec(
229 (3, 4),
230 matrix![
231 1.0, 2.0, 3.0, 0.0;
232 4.0, 5.0, 6.0, 0.0;
233 0.0, 0.0, 0.0, 0.0;
234 ],
235 )
236 );
237 }
238
239 #[test]
240 fn nonzeros() {
241 let matrix = Conventional::from_vec(2, vec![1.0, 2.0, 3.0, 0.0]);
242 assert_eq!(matrix.nonzeros(), 3);
243 }
244}