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
121
122
use num_traits::Signed;
use std::ops::{Index, IndexMut, Neg};
#[derive(Debug)]
pub struct Matrix<C> {
pub rows: usize,
pub columns: usize,
data: Vec<C>,
}
impl<C: Clone> Matrix<C> {
pub fn new(rows: usize, columns: usize, value: C) -> Matrix<C> {
let mut v = Vec::with_capacity(rows * columns);
v.resize(rows * columns, value);
Matrix {
rows: rows,
columns: columns,
data: v,
}
}
pub fn new_square(size: usize, value: C) -> Matrix<C> {
Self::new(size, size, value)
}
pub fn fill(&mut self, value: C) {
self.data.clear();
self.data.resize(self.rows * self.columns, value);
}
}
impl<C: Clone> Clone for Matrix<C> {
fn clone(&self) -> Matrix<C> {
Matrix {
rows: self.rows,
columns: self.columns,
data: self.data.clone(),
}
}
}
impl<C: Clone + Signed> Neg for Matrix<C> {
type Output = Matrix<C>;
fn neg(self) -> Matrix<C> {
Matrix {
rows: self.rows,
columns: self.columns,
data: self.data.iter().map(|x| -x.clone()).collect::<Vec<_>>(),
}
}
}
impl<C> Matrix<C> {
pub fn from_vec(rows: usize, columns: usize, values: Vec<C>) -> Matrix<C> {
assert_eq!(
rows * columns,
values.len(),
"length of vector does not correspond to announced dimensions"
);
Matrix {
rows: rows,
columns: columns,
data: values,
}
}
pub fn square_from_vec(values: Vec<C>) -> Matrix<C> {
let size = (values.len() as f32).sqrt().round() as usize;
assert_eq!(
size * size,
values.len(),
"length of vector is not a square number"
);
Self::from_vec(size, size, values)
}
pub fn is_square(&self) -> bool {
self.rows == self.columns
}
fn idx(&self, i: &(usize, usize)) -> usize {
i.0 * self.columns + i.1
}
}
impl<'a, C> Index<&'a (usize, usize)> for Matrix<C> {
type Output = C;
fn index(&self, index: &'a (usize, usize)) -> &C {
&self.data[self.idx(index)]
}
}
impl<'a, C> IndexMut<&'a (usize, usize)> for Matrix<C> {
fn index_mut(&mut self, index: &'a (usize, usize)) -> &mut C {
let i = self.idx(index);
&mut self.data[i]
}
}