Translating Matlab's bsxfun to Eigen - c++

Say we have a matrix A of dimension MxN and a vector a of dimension Mx1. In Matlab, to multiply 'a' with all columns of 'A', we can do
bsxfun(#times, a, A)
Is there an equivalent approach in Eigen, without having to loop over the columns of the matrix?
I'm trying to do
M = bsxfun(#times, a, A) + bsxfun(#times, a2, A2)
and hoping that Eigen's lazy evaluation will make it more efficient.
Thanks!

You can do:
M = A.array().colwise()*a.array();
The .array() is needed to redefine the semantic of operator* to coefficient-wise products (not needed if A and a are Array<> objects).
In this special case, it is probably better to write it as a scaling operation:
M = a.asDiagonal() * A;
In both cases you won't get any temporary thanks to lazy evaluation.

Related

How can I divide the Eigen::matrix by Eigen::vector?

following is my code.
Eigen::Matrix3d first_rotation = firstPoint.q.matrix();
Eigen::Vector3d first_trans= firstPoint.t;
for(auto &iter:in_points )
{
iter.second.t= first_rotation / (iter.second.t-first_trans).array();
}
However,the vscode says"no operator / matches the operands" for division."
How can I division a matrix by a vector?
In Matlab, the line was t2 = R1 \ (R2 - t1);
Matlab defined the / and \ operators, when applied to matrices, as solving linear equation systems, as you can read up on in their operator documentation. In particular
x = A\B solves the system of linear equations A*x = B
Eigen doesn't do this. And I don't think most other languages or libraries do it either. The main point is that there are multiple ways to decompose a matrix for solving. Each with their own pros and cons. You can read up on it in their documentation.
In your case, you can save time by reusing the decomposition multiple times. Something like this:
Eigen::PartialPivLU<Eigen::Matrix3d> first_rotation =
firstPoint.q.matrix().partialPivLu();
for(auto &iter: in_points)
iter.second.t = first_rotation.solve(
(iter.second.t-first_trans).eval());
Note: I picked LU over e.g. householderQr because that is what Matlab does for general square matrices. If you know more about your input matrix, e.g. that it is symmetrical, or not invertible, try something else.
Note 2: I'm not sure it is necessary in this case but I added a call to eval so that the left side of the assignment is not an alias of anything on the right side. With dynamically sized vectors, this would introduce extra memory allocations but here it is fine.

Eigen virtually extend sparse matrix

I have a dense matrix A of size 2N*N that has to be multiplied by a matrix B, of size N*2N.
Matrix B is actually a horizontal concatenation of 2 sparse matrices, X and Y. B requires only a read-only access.
Unfortunately for me, there doesn't seem to be a concatenate operation for sparse matrices. Of course, I could simply create a matrix of size N*2N and populate it with the data, but this seems rather wasteful. It seems like there could be a way to group X and Y into some sort of matrix view.
Additional simplification in my case is that either X or Y is a zero matrix.
For your specific case, it is sufficient to multiply A by either X or Y - depending on which one is nonzero. The result will be exactly the same as the multiplication by B (simple matrix algebra).
If your result matrix is column major (the default), you can assign partial results to vertical sub-blocks like so (if X or Y is structurally zero, the corresponding sub-product is calculated in O(1)):
typedef Eigen::SparseMatrix<float> SM;
void foo(SM& out, SM const& A, SM const& X, SM const &Y)
{
assert(X.rows()==Y.rows() && X.rows()==A.cols());
out.resize(A.rows(), X.cols()+Y.cols());
out.leftCols(X.cols()) = A*X;
out.rightCols(Y.cols()) = A*Y;
}
If you really want to, you could write a wrapper class which holds references to two sparse matrices (X and Y) and implement operator*(SparseMatrix, YourWrapper) -- but depending on how you use it, it is probably better to make an explicit function call.

Eigen matrix right division equivalent

in Matlab if I write
A = B*inv(C)
(with A, B and C being square matrices), I get a warning that matrix inversion should be replaced with a matrix "right-division" (due to being numerically more stable and accurate) like
A = B/C
In my Eigen C++ project I have the following code:
Eigen::Matrix<double> A = B*(C.inverse());
and I was woundering if there is an equivalent replacement for taking the matrix inverse in Eigen analogous to the one in Matlab mentioned above?
I know that matrix "left-division" can be expressed by solving a system of equations for expressions like
A = inv(C)*B
but what about
A = C*inv(B)
in Eigen?
At the moment the most efficient way to do this is to rewrite your equation to
A^T = inv(C^T) * B^T
A = (inv(C^T) * B^T)^T
which can be implemented in Eigen as
SomeDecomposition decompC(C); // decompose C with a suiting decomposition
Eigen::MatrixXd A = decompC.transpose().solve(B.transpose()).transpose();
There were/are plans, that eventually, one can write
A = B * decompC.inverse();
and Eigen will evaluate this in the most efficient way.

Comparing two matrices with eigen

Let's say I have two eigen matrices A and B, and I want to create a third matrix defined by
C(i,j) = 5.0 if A(i,j) > B(i,j), 0 otherwise
I guess it is possible to do it without an explicit for loop. But I am not very proficient with Eigen yet. What whould be the best approach?
Assuming A, B and C are MatrixXd you can do:
C = (A.array()>B.Array()).cast<double>() * 5.0;

Can I solve a system of linear equations, in the form Ax = b with A being sparse, using Eigen?

I need to convert a MATLAB code into C++, and I'm stuck with this instruction:
a = K\F
, where K is a sparse matrix of size n x n, and F is a column vector of size n.
I know it's easy to solve that using the Eigen library - I have tried the fullPivLu() method, and I've been able to built a working snippet, using a Matrix and a Vector.
However, my K is a SparseMatrix<double> (while F is a VectorXd). My declarations:
SparseMatrix<double> K(nec, nec);
VectorXd F(nec);
and it seems that SparseMatrix doesn't have the fullPivLu() method, nor the lu() one.
I've tried, in fact, these two different approaches, taken from the documentation:
//1.
MatrixXd x = K.fullPivLu().solve(F);
//2.
VectorXf x;
K.lu().solve(F, &x);
They don't work, because fullPivLu() and lu() are not members of 'Eigen::SparseMatrix<_Scalar>'
So, I am asking: is there a way to solve a system of linear equations (the MATLAB's mldivide, or '\'), using Eigen for C++, with K being a sparse matrix?
Thank you for any help.
Would Eigen::SparseLU work for you?