1# Matrix {#dsppp_matrix}
2
3Matrixes can be used similarly to vectors:
4
5```cpp
6Matrix<float32_t,ROWS,COLS> a;
7Matrix<float32_t,ROWS,COLS> b;
8```
9
10If the dimensions of the matrixes are not known at build time, you would instead write:
11
12```
13Matrix<float32_t> a(rows,cols);
14Matrix<float32_t> b(rows,cols);
15```
16
17Once you have matrixes, you need to initialize them.  A matrix is also a vector, so you can initialize it by indexing into the vector:
18
19```cpp
20for(std::size_t i=0;i<ROWS*COLS;i++)
21{
22      a[i] = float32_t(i);
23}
24```
25
26You can also use a bidimensional indexing:
27
28```cpp
29for(std::size_t row=0; row<ROWS; row++)
30{
31   for(std::size_t col=0; col<COLS; col++)
32   {
33            b(row,col) = float32_t(row*col);
34   }
35}
36```
37
38Once you have initialized matrixes, you can operate on them:
39
40```cpp
41Matrix<float32_t,ROWS,COLS> result = a * a + b;
42```
43
44The operators `+` and `*` are merged into the loop. `*` is the element-wise multiply. For the vector / matrix products you should use the operator `dot`.
45
46Note that fusion of operators will not work with `dot(Matrix, Matrix`). It is only supported with vectors : `dot(Vector,Vector)` or `dot(Matrix,Vector)`.
47
48## VectorView
49
50We can create virtual vectors which are view of some slices of the matrix.
51
52### Row vector
53
54To set the second row to `0.0f`, you can do:
55
56```
57result.row(1) = 0.0f;
58```
59
60To set the odd elements of the 3rd row to `0.0f` we can do:
61
62```
63result.row<2>(2,1) = 0.0f;
64```
65
66The first argument `2` is the row number (starting from `0`).
67
68The second argument `1` is where is the row we start the view : element `1`.
69
70`<2>` is the stride known at built time.
71
72The `row` API is:
73
74```cpp
75template<int S=1>
76VectorView<P,S> row(const index_t i,const index_t start=0,const index_t stop=C)
77
78```
79
80`stop` is the index of the first element **after** the end of the view.
81
82`i` is the row index
83
84### Column vector
85
86There is a similar API for columns.
87
88Let's set the odd elements of columns 3 to `5.0f`:
89
90```
91result.col<2>(2,1) = 5.0f;
92```
93
94## MatrixView
95
96It is also possible to create a virtual matrix : a view onto a subset of the matrix.
97
98Let's add the bottom right corner of the matrix to itself:
99
100```cpp
101result.sub(4,8,4,8) = result.sub(4,8,4,8) + result.sub(4,8,4,8)
102```
103
104The API is:
105
106```cpp
107MatrixView<P,C> sub(const index_t rs,
108                    const index_t re,
109                    const index_t cs,
110                    const index_t ce)
111```
112
113You specify the row start and row end, then column start and column end.
114
115Note that the end is the first index **after** the end of your rows or columns.
116
117No stride is supported for matrix view in this version of the library.
118
119## Matrix operations
120
121In addition to the vector operations `+`,`-` and `*`, matrixes are supporting more operations:
122
123* `dot` for vector / matrix products
124* `diagonal` to create a diagonal matrix from a vector.
125* `identity` to create an identity matrix
126* `tranpose` to create the transposed matrix
127* `outer` for the outer product of two vectors
128
129### dot
130
131```cpp
132result = dot(a,b);
133```
134
135The compiler may use the move semantic to copy the temporary result of the `dot` function to `result`.
136
137In this case, no copy would occur and `result` after the assignment would be a vector allocated by `dot` so using the `TMP_ALLOC` .
138
139### diagonal
140
141```cpp
142result = Matrix<float32_t,ROWS,COLS>::diagonal(c);
143```
144
145### identity
146
147```cpp
148result = Matrix<float32_t,ROWS,COLS>::identity();
149```
150
151### transpose
152
153```cpp
154result = a.transpose();
155```
156
157or
158
159```cpp
160transposeTo(result,a);
161```
162
163### outer product
164
165```cpp
166result = outer(c,c);
167```
168
169