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
use crate::matrix::Matrix;
impl<T> Matrix<T> {
/// Applies a function dependent on value
/// to each corresponding element between
/// the two matrices.
///
/// # Example
/// ```
/// use simp_linalg::matrix::Matrix;
///
/// let matrix1 = Matrix::from(vec![vec![1, 2],
/// vec![3, 4]]);
/// let matrix2 = Matrix::from(vec![vec![5, 6],
/// vec![7, 8]]);
///
/// let matrix3 = matrix1.map(&matrix2, |val1, val2| val1 * val2);
///
/// assert_eq!(matrix3, Matrix::from(vec![vec![5, 12],
/// vec![21, 32]]));
/// ```
///
/// # Panic!
/// This function will panic if the two matrices are not identically
/// sized.
pub fn map<F>(&self, other: &Matrix<T>, funct: F) -> Matrix<T>
where
F: Fn(&T, &T) -> T
{
if (self.rows != other.rows) || (self.cols != other.cols) {
panic!("Cannot map matrices of different sizes.")
}
let mut params = Vec::with_capacity(self.rows);
for row_idx in 0..self.rows {
let mut new_row = Vec::with_capacity(self.cols);
for col_idx in 0..self.cols {
new_row.push(funct(&self.matrix[row_idx][col_idx], &other.matrix[row_idx][col_idx]))
}
params.push(new_row)
}
Matrix::from(params)
}
/*
For anyone following the source code, lambda.rs
has a function called 'lambda_index' while map.rs
does not. This is on purpose, as it is pointless.
Consider what the generic function definition
would be for a map_index.
This is what it would be:
F: Fn(usize, usize) -> T
This is already used for lambda_index.
Additionally, the matrices are independent from
the function definition, and no actual mapping
will be done.
Therefore, it is pointless to add the method 'map_index',
as it does not make sense.
*/
/// Applies a function dependent on location and value
/// to each corresponding element between the two matrices.
///
/// # Example
/// ```
/// use simp_linalg::matrix::Matrix;
///
/// let matrix1 = Matrix::from(vec![vec![1, 2],
/// vec![3, 4]]);
/// let matrix2 = Matrix::from(vec![vec![5, 6],
/// vec![7, 8]]);
///
/// let matrix3 = matrix1.map_enumerate(&matrix2, |row, col, val1, val2| val1 * val2 + (row * col + 1));
///
/// assert_eq!(matrix3, Matrix::from(vec![vec![6, 13],
/// vec![22, 34]]));
/// ```
///
/// # Panic!
/// This function will panic if the two matrices are not identically
/// sized.
pub fn map_enumerate<F>(&self, other: &Matrix<T>, funct: F) -> Matrix<T>
where
F: Fn(usize, usize, &T, &T) -> T
{
if (self.rows != other.rows) || (self.cols != other.cols) {
panic!("Cannot map matrices of different sizes.")
}
let mut params = Vec::with_capacity(self.rows);
for row_idx in 0..self.rows {
let mut new_row = Vec::with_capacity(self.cols);
for col_idx in 0..self.cols {
new_row.push(funct(row_idx, col_idx, &self.matrix[row_idx][col_idx], &other.matrix[row_idx][col_idx]))
}
params.push(new_row)
}
Matrix::from(params)
}
}