1#![macro_use]
5
6use crate::vector::ops::Copy;
7use crate::Matrix;
8use num::traits::NumCast;
9use std::fmt;
10use std::iter::repeat;
11use std::ops::Index;
12use std::slice;
13
14#[derive(Debug, PartialEq)]
15pub struct Mat<T> {
16 rows: usize,
17 cols: usize,
18 data: Vec<T>,
19}
20
21impl<T> Mat<T> {
22 pub fn new_from_data(rows: usize, cols: usize, data: Vec<T>) -> Mat<T> {
23 Mat { rows, cols, data }
24 }
25
26 pub fn new(n: usize, m: usize) -> Mat<T> {
27 let len = n * m;
28 let mut data = Vec::with_capacity(len);
29 unsafe {
30 data.set_len(len);
31 }
32
33 Self::new_from_data(n, m, data)
34 }
35
36 pub fn rows(&self) -> usize {
37 self.rows
38 }
39 pub fn cols(&self) -> usize {
40 self.cols
41 }
42 pub unsafe fn set_rows(&mut self, n: usize) {
47 self.rows = n;
48 }
49 pub unsafe fn set_cols(&mut self, n: usize) {
54 self.cols = n;
55 }
56 pub unsafe fn push(&mut self, val: T) {
60 self.data.push(val);
61 }
62}
63
64impl<T: Clone> Mat<T> {
65 pub fn fill(value: T, n: usize, m: usize) -> Mat<T> {
66 Mat {
67 rows: n,
68 cols: m,
69 data: repeat(value).take(n * m).collect(),
70 }
71 }
72}
73
74impl<T> Index<usize> for Mat<T> {
75 type Output = [T];
76
77 fn index(&self, index: usize) -> &[T] {
78 let offset = (index * self.cols) as isize;
79
80 unsafe {
81 let ptr = (&self.data[..]).as_ptr().offset(offset);
82 slice::from_raw_parts(ptr, self.cols)
83 }
84 }
85}
86
87impl<T: fmt::Display> fmt::Display for Mat<T> {
88 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89 for i in 0usize..self.rows {
90 for j in 0usize..self.cols {
91 match write!(f, "{}", self[i][j]) {
92 Ok(_) => (),
93 x => return x,
94 }
95 }
96
97 match writeln!(f) {
98 Ok(_) => (),
99 x => return x,
100 }
101 }
102
103 Ok(())
104 }
105}
106
107impl<T> Matrix<T> for Mat<T> {
108 fn rows(&self) -> u32 {
109 let n: Option<u32> = NumCast::from(self.rows);
110 n.unwrap()
111 }
112
113 fn cols(&self) -> u32 {
114 let n: Option<u32> = NumCast::from(self.cols);
115 n.unwrap()
116 }
117
118 fn as_ptr(&self) -> *const T {
119 self.data[..].as_ptr()
120 }
121
122 fn as_mut_ptr(&mut self) -> *mut T {
123 (&mut self.data[..]).as_mut_ptr()
124 }
125}
126
127impl<'a, T> From<&'a dyn Matrix<T>> for Mat<T>
128where
129 T: Copy,
130{
131 fn from(a: &dyn Matrix<T>) -> Mat<T> {
132 let n = a.rows() as usize;
133 let m = a.cols() as usize;
134 let len = n * m;
135
136 let mut result = Mat {
137 rows: n,
138 cols: m,
139 data: Vec::with_capacity(len),
140 };
141 unsafe {
142 result.data.set_len(len);
143 }
144
145 Copy::copy_mat(a, &mut result);
146 result
147 }
148}
149
150#[macro_export]
151macro_rules! mat(
152 ($($($e: expr),+);*) => ({
153 let mut _temp = Mat::new(0, 0);
155 let mut rows = 0usize;
156 let mut _cols;
157 $(
158 rows += 1;
159 _cols = 0usize;
160 $(
161 _cols += 1;
162 unsafe {
163 _temp.push($e);
164 }
165 )+
166 )*
167
168 unsafe {
169 _temp.set_rows(rows);
170 _temp.set_cols(_cols);
171 }
172
173 _temp
174 });
175);
176
177#[cfg(test)]
178mod tests {
179 use crate::math::Mat;
180
181 #[test]
182 fn index() {
183 let a = mat![1f32, 2f32];
184 assert_eq!(1.0, a[0][0]);
185 assert_eq!(2.0, a[0][1]);
186
187 let b = mat![1f32; 2f32];
188 assert_eq!(1.0, b[0][0]);
189 assert_eq!(2.0, b[1][0]);
190
191 let m = mat![1f32, 2f32; 3f32, 4f32];
192 assert_eq!(1.0, m[0][0]);
193 assert_eq!(2.0, m[0][1]);
194 assert_eq!(3.0, m[1][0]);
195 assert_eq!(4.0, m[1][1]);
196 }
197}