aboutsummaryrefslogtreecommitdiffhomepage
path: root/doc/C02_TutorialMatrixArithmetic.dox
blob: 431ef595e2fcad0905f22d286e83ee5ca0918c27 (plain)
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
namespace Eigen {

/** \page TutorialMatrixArithmetic Tutorial - Matrix and vector arithmetic
    \ingroup Tutorial

This tutorial aims to provide an overview and some details on how to perform arithmetic between matrices, vectors and scalars with Eigen.

\b Table \b of \b contents
  - \ref TutorialMatrixArithmCommaInitializer
  - \ref TutorialMatrixArithmElementaryOperations
    - \ref TutorialMatrixArithmExamples
    - \ref TutorialMatrixArithmProduct
    - \ref TutorialMatrixArithmSimpleExample
    - \ref TutorialMatrixCombiningOperators
    - \ref TutorialMatrixOperatorValidity
  - \ref TutorialMatrixArithmReductionOperations


\section TutorialMatrixArithmCommaInitializer Comma initializer
Eigen offers a comma initializer syntax which allows to set all the coefficients of any dense objects (matrix, vector, array, block, etc.) to specific values:
<table class="tutorial_code"><tr><td>
\code Matrix3f m;
m << 1, 2, 3,
     4, 5, 6,
     7, 8, 9;
cout << m;
\endcode
</td>
<td>
output:
\code
1 2 3
4 5 6
7 8 9
\endcode
</td></tr></table>

Moreover, Eigen also supports to load a matrix through a set of blocks:
<table class="tutorial_code"><tr><td>
\code
int rows=5, cols=5;
MatrixXf m(rows,cols);
m << (Matrix3f() << 1, 2, 3, 4, 5, 6, 7, 8, 9).finished(),
     MatrixXf::Zero(3,cols-3),
     MatrixXf::Zero(rows-3,3),
     MatrixXf::Identity(rows-3,cols-3);
cout << m;
\endcode
</td>
<td>
output:
\code
1 2 3 0 0
4 5 6 0 0
7 8 9 0 0
0 0 0 1 0
0 0 0 0 1
\endcode
</td></tr></table>

FIXME: is this still needed?
<span class="note">\b Side \b note: here \link CommaInitializer::finished() .finished() \endlink
is used to get the actual matrix object once the comma initialization
of our temporary submatrix is done. Note that despite the apparent complexity of such an expression,
Eigen's comma initializer usually compiles to very optimized code without any overhead.</span>

\section TutorialMatrixArithmElementaryOperations Basic arithmetic operators

Eigen takes advantage of C++ operator overloading to make arithmetic operations intuitive. In the case of matrices and vectors, Eigen only supports arithmetic operations that have a linear-algebraic meaning. Therefore, adding an scalar to a vector or matrix cannot be written as \p scalar \p + \p matrix . Nonetheless, Eigen provides an Array class that is able to perform other types of operations such as column-wise and row-wise addition, substraction, etc. For more information see FIXME:link to Array class.

\subsection TutorialMatrixArithmExamples Usage examples
Some basic examples are presented in the following table, showing how easy it is to express arithmetic operations with Eigen.

<table class="tutorial_code" align="center">
<tr><td>
matrix/vector product \matrixworld</td><td>\code
col2 = mat1 * col1;
row2 = row1 * mat1;     row1 *= mat1;
mat3 = mat1 * mat2;     mat3 *= mat1; \endcode
</td></tr>
<tr><td>
add/subtract</td><td>\code
mat3 = mat1 + mat2;      mat3 += mat1;
mat3 = mat1 - mat2;      mat3 -= mat1;\endcode
</td></tr>
<tr><td>
scalar product/division</td><td>\code
mat3 = mat1 * s1;   mat3 = s1 * mat1;   mat3 *= s1;
mat3 = mat1 / s1;   mat3 /= s1;\endcode
</td></tr>
</table>

\subsection TutorialMatrixArithmProduct	Product types
It is important to point out that the product operation can be understood in different ways between matrices and vectors. Eigen treats the \p * \operator as matrix product or multiplication by a scalar. However, dot and cross products are also supported through the \p .dot() and \p .cross() operations:

\code
  Matrix3f	m1,m2,m3;
  Vector3f	v1,v2,v3;
  
  // matrix product
  m1 = m2 * m3;
  
  // vector cross product: v1 = v2 X v3
  v1 = v2.cross(v3);
  
  // vector dot product: v2 . v3 (returns scalar)
  float dotResult = v2.dot(v3);  
\endcode

<strong> Note:</strong> cross product is only defined for 3-dimensional vectors.

\subsection TutorialMatrixArithmSimpleExample A simple example with matrix linear algebra

The next piece of code shows a simple program that creates two dynamic 3x3 matrices and initializes them, performing some simple operations and displaying the results at each step.

\code
  #include <Eigen/Dense>
  #include <iostream>
  
  using namespace Eigen;
  
  int main()
  {
    MatrixXf	m(3,3);	// Matrix m is 3x3
    VectorXf	n(3,3);	// 3-component vector
    
    m << 1,2,3,		// Assign some values to m
         4,5,6,
         7,8,9;
         
    n << 10,11,12,	// Assign some values to n
         13,14,15,
         16,17,18;

         
    // simple matrix-product-scalar
    std::cout << "3*m = " << 3*m << std::endl;

    // simple matrix-divided-by-scalar
    std::cout << "m/3 = " << m/3 << std::endl;
    
    // matrix multiplication
    std::cout << "m*n = " << m*n << std::endl;
    
    return 0;
  }
\endcode


\subsection TutorialMatrixCombiningOperators Combining operators in a single statement

As said before, Eigen's classes already provide implementations for linear-algebra operations. Combining operators in more complex expressions is posssible and often desirable, since it may help to avoid temporary memory allocations, making code execution faster (FIXME: add reference to lazy evaluation?) :

\code
  MatrixXf	m(3,3), n(3,3);
  MatrixXf	q(3,3), p(3,3);
  
  // initialize... etc
  .....
  
  // METHOD 1: use temporary allocation
  {
    MatrixXf	tempMatrix;

    tempMatrix = m + 3*n;
    p = tempMatrix * q;
  }

  // METHOD 2: avoids extra memory allocation if possible
  // (Eigen will take care of that automatically)
  p = (m + 3*n) * q;	// matrix addition and multiplication by a vector
  
\endcode

Eigen will try to do its best in order to avoid temporary allocation and evaluate the expressions as fast as possible. FIXME: anything else to say here, is this correct?


\subsection TutorialMatrixOperatorValidity Validity of operations
The validity of the operations between matrices depend on the data type. In order to report whether an operation is valid or not, Eigen makes use of both compile-time and run-time information. In the case that the size of the matrices and vectors involved in the operations are known at compile time (fixed-size matrices such as \p Matrix3f), Eigen will be able to perfom a compile-time check and stop the compiler with an error if one of the operations is not possible:

\code
  Matrix3f m;
  Vector4f v;
  
  v = m*v;	// Compile-time error: YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
\endcode

On the other hand, operations between dynamic-size matrices will take place at run-time, generating a run-time assertion if invalid operands are detected. FIXME: link to how to change the handler?

\code
  MatrixXf	m(3,3);
  VectorXf	v(4);
  
  v = m * v;	// Run-time assertion: "invalid matrix product"
\endcode


\section TutorialMatrixArithmReductionOperations Basic arithmetic reduction operations
Eigen also provides some basic but extremely useful reduction arithmetic operators to obtain values such as the sum or the maximum or minimum of all the coefficients in a given matrix or vector. The following table presents the basic arithmetic reduction operations and their syntax.

<table class="tutorial_code" align="center">
<tr><td align="center">\b Reduction \b operation</td><td align="center">\b Usage \b example</td></tr>
<tr><td>
Sum of all the coefficients in a matrix</td><td>\code
MatrixXf m;
float totalSum = m.sum();\endcode</td></tr>
<tr><td>
Maximum coefficient in a matrix</td><td>\code
MatrixXf m;
int row, col;

// minimum value will be stored in minValue
//  and the row and column where it was found in row and col,
//  (these two parameters are optional)
float minValue = m.minCoeff(&row,&col);\endcode</td></tr>
<tr><td>
Maximum coefficient in a matrix</td><td>\code
MatrixXf m;
int row, col;

// maximum value will be stored in maxValue
//  and the row and column where it was found in row and col,
//  (these two parameters are optional)
float maxValue = m.maxCoeff(&row,&col);\endcode</td></tr>
<tr><td>
Product between all coefficients in a matrix</td><td>\code
MatrixXf m;

float product = m.prod();\endcode</td></tr>
<tr><td>
Mean of coefficients in a matrix</td><td>\code
MatrixXf m;

float mean = m.mean();\endcode</td></tr>
<tr><td>
Matrix's trace</td><td>\code
MatrixXf m;

float trace = m.trace();\endcode</td></tr>
</table>




*/

}