Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient matrix transpose matrix multiplication in Eigen

I have access to a number of matrix libraries, but for this project I am using Eigen, due to its compile time definition and its inclusion of SVD.

Now, I am doing the following operation:

Eigen::Matrix<double,M,N> A;     // populated in the code

Eigen::Matrix<double,N,N> B = A.transpose() * A;

As I understand, this makes a copy of A and forms the transpose, which is multiplied by A again. This operation is being performed on relatively small matrices (M=20-30,N=3), but many millions of times per second, meaning it must be as fast as possible.

I read that using the following is faster:

B.noalias() = A.transpose() * A;

I could write my own subroutine that accepts A as an input and fills B, but I was wondering if there is an efficient, existing implementation that uses the least amount of cycles.

like image 228
Dar Cos Avatar asked Mar 10 '17 07:03

Dar Cos


People also ask

Can you transpose a matrix using matrix multiplication?

No, you cannot ! Nope. A more interesting question is whether there is a pair T1,T2 of matrices such that T1AT2=AT.

What is matrix multiplied by transpose?

What is the Multiplication Property of Transpose? The multiplication property of transpose is that the transpose of a product of two matrices will be equal to the product of the transpose of individual matrices in reverse order.

Can you transpose a 2x2 matrix?

Below is a 2x2 matrix like it is used in complex multiplication. The transpose of a square matrix can be considered a mirrored version of it: mirrored over the main diagonal. That is the diagonal with the a's on it. For a square matrix of any size, the same principle would hold.

What is matrix multiplication in C++?

Matrix multiplication in C++ is a binary operation in which two matrices can be added, subtracted and multiplied. Input for row number, column number, first matrix elements, and second matrix elements is taken from the consumer to multiply the matrices. Then the matrices entered by the consumer are multiplied.


1 Answers

First of all, since Eigen relies on template expressions, A.transpose() does not evaluate into a temporary.

Secondly, in:

Matrix<double,N,N> B = A.transpose() * A;

Eigen knows that B cannot appear on the right hand side of the expression (because here the compiler calls the constructor of B), and therefore, no temporary is created at all. This is equivalent to:

Matrix<double,N,N> B;             // declare first
B.noalias() = A.transpose() * A;  // eval later

Finally, for such small matrices, I don't expect that the use of B.selfadjointView().rankUpdate(A) will help (as suggested in kennytm comment).

On the otherhand, with N=3, it might be worth trying the lazy implementation:

B = A.transpose().lazyProduct(A)

just to be sure. Eigen's has built-in heuristics to choose the best product implementation, but since the heuristic has to be simple and fast to evaluate, it might not be 100% right.

like image 70
ggael Avatar answered Oct 02 '22 03:10

ggael