Difference between revisions of "API Showcase"

From Eigen
Jump to: navigation, search
(Operating on blocks inside a matrix or vector)
(Computing sums)
Line 41: Line 41:
 
==Computing sums==
 
==Computing sums==
 
<source lang="cpp">
 
<source lang="cpp">
m.sum(); // returns the sum of all coefficients in m
+
result = m.sum(); // returns the sum of all coefficients in m
m.row(i).sum();
+
result = m.row(i).sum();
m.block(firstRow, firstCol, rows, cols).sum();
+
result = m.block(firstRow, firstCol, rows, cols).sum();
m.rowwise().sum(); // returns a vector of the sums in each row
+
#include<Eigen/Array> // provides rowwise()
 +
result = m.rowwise().sum(); // returns a vector of the sums in each row
 +
</source>
 +
 
 +
Here is how you would compute the sum of the cubes of the i-th column of a matrix:
 +
<source lang="cpp">
 +
#include<Eigen/Array> // provides cube()
 +
result = m.col(i).cwise().cube().sum();
 
</source>
 
</source>
  

Revision as of 14:25, 4 December 2008

Here are some examples of Eigen's fine API.

Performing row operations on a matrix

Suppose that you have a matrix m, a number alpha, and integers i and j, and you want to add alpha times the j-th row into the i-th row. You can do:

m.row(i) += alpha * m.row(j);

Here row() returns a "block inside a matrix" expression that can be used as a lvalue. This is only made possible in C++ by the technique of expression templates, used pervasively throughout Eigen. The great thing about the above code, is that it compiles to completely optimized assembly -- despite the abstraction! The arrays are traversed only once, no temporary is introduced. If the rows' size is fixed at compile time, Eigen will consider unrolling the loop if it is small enough. If vectorization is enabled, it will be successfully used.

Thus, as the user of Eigen, in most cases you can simply copy pseudocode from books and let Eigen handle the details.

The next great thing about Eigen's expressions, as opposed to fixed-function libraries such as BLAS, is that arbitrary expressions can be used. For example, if you also another number beta and another integer k, you can do:

m.row(i) += alpha * m.row(j) + beta * m.row(k);

Eigen will still optimize this completely, as above.

Any other kind of operation on the rows (or columns, or arbitrary blocks as shown below) of a matrix is possible, with the same optimizations being automatically handled by Eigen:

m.row(i).swap(m.row(j));
m.row(i) *= factor;

Operating on blocks inside a matrix or vector

Let m be a matrix. All the following operations are allowed by Eigen, with the self-explanatory effect. Here again, Eigen does its best to optimize everything for you, like traversing the arrays only once, vectorizing if possible, etc.

m.block(firstRow, firstCol, rows, cols).setZero();
m.corner(Eigen::TopLeft, rows, cols) = some_other_matrix;
m.block<2,2>(firstRow, firstCol).setIdentity(); // optimized variant when the # of rows, cols are known at compile-time

There are also vector-specific operations. Let v be a vector.

v.segment(first, size) = some_other_vector;
v.segment<3>(position1) = v.segment<3>(position2); // optimized variant when the size is known at compile-time
v.start(n).setConstant(12); // writes 12 in the n first coefficients of v
m.diagonal().end(n) *= lambda; // multiplies by lambda the n last diagonal coefficients of a matrix m

Computing sums

result = m.sum(); // returns the sum of all coefficients in m
result = m.row(i).sum();
result = m.block(firstRow, firstCol, rows, cols).sum();
#include<Eigen/Array> // provides rowwise()
result = m.rowwise().sum(); // returns a vector of the sums in each row

Here is how you would compute the sum of the cubes of the i-th column of a matrix:

#include<Eigen/Array> // provides cube()
result = m.col(i).cwise().cube().sum();

Comma-initializer

Like other libraries, Eigen has a comma-initializer allowing to construct a matrix like this:

Matrix3f m;
m << 1, 2, 3,
     4, 5, 6,
     7, 8, 9;

Unlike other libraries, Eigen's comma-initializer can be combined at will with expressions, which makes it very powerful. Here is a matrix being constructed by blocks:

Matrix4f m;
m << Matrix2f::Identity(),             Matrix2f::Zero(),
     (Matrix2f()<<1,2,3,4).finished(), Matrix2f::Identity();
/* The matrix m is now:
   1 0 0 0
   0 1 0 0
   1 2 1 0
   3 4 0 1
*/

You can even use a comma-initializer to fill directly an expression. Here is how you would write 1,2,3 in the first row of a matrix:

Matrix3f m;
m.row(0) << 1,2,3;