Eigen virtually extend sparse matrix - c++

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.

Related

Rationale for Eigen API for Matrix with Scalar operations

Consider the following code:
#include <Eigen/Core>
using Matrix = Eigen::Matrix<float, 2, 2>;
Matrix func1(const Matrix& mat) { return mat + 0.5; }
Matrix func2(const Matrix& mat) { return mat / 0.5; }
func1() does not compile; you need to replace mat with mat.array() in the function body to fix it ([1]). However, func2() does compile as-is.
My question has to do with why the API is designed this way. Why is addition-with-scalar and division-by-scalar treated differently? What problems would arise if the following method is added to the Matrix class, and why haven't those problems arisen already for the operator/ method?:
auto operator+(Scalar s) const { return this->array() + s; }
From a mathematics perspective, a scalar added to a matrix "should" be the same as adding the scalar only to the diagonal. That is, a math text would usually use M + 0.5 to mean M + 0.5I, for I the identity matrix. There are many ways to justify this. For example, you can appeal to the analogy I = 1, or you can appeal to the desire to say Mx + 0.5x = (M + 0.5)x whenever x is a vector, etc.
Alternatively, you could take M + 0.5 to add 0.5 to every element. This is what you think is right if you don't think of matrices from a "linear algebra mindset" and treat them as just collections (arrays) of numbers, where it is natural to just "broadcast" scalar operations.
Since there are multiple "obvious" ways to handle + between a scalar and a matrix, where someone expecting one may be blindsided by the other, it is a good idea to do as Eigen does and ban such expressions. You are then forced to signify what you want in a less ambiguous way.
The natural definition of / from an algebra perspective coincides with the array perspective, so no reason to ban it.

Function to invert Eigen matrix without branching statements for auto differentiation

I need to invert an Eigen matrix (9x9 in my particular case) as a part of code that I want to automatically differentiate using CppAD. For this to succeed the code executing the inversion can not contain any branching like for example if or switch statements. Unfortunately, the inverse function of Eigen contains branching with makes the algorithmic differentiation of CppAD fail.
Mathematically it should be possible to come up with a formulation that does not need branching for a fixed matrix size that is guaranteed to be invertible. Is that correct?
Do you know of any library that implements such an inverse without branching?
There is a mechanical conversion from branch to no-branch for arithmetic functions.
Duplicate all the variables you use in each branch, and calculate both halves. At the end of the block, multiply the if branch by condition, and the else branch by !condition, then sum them.
Similarly for a switch, calculate all the cases, and multiply by value == case.
E.g.
Mat frob_branch(Mat a, Mat b) {
if (a.baz()) {
return a * b;
} else {
return b * a;
}
}
becomes
Mat frob_no_branch(Mat a, Mat b) {
auto if_true = a * b;
auto if_false = b * a;
bool condition = a.baz();
return (if_true * condition) + (if_false * !condition);
}
In general, it is possible to invert arbitrary large (invertible) matrices without branching, but this gets inefficient for bigger matrices. Eigen only does this for matrices up to size 4x4.
If you want the derivation of the inverse, just use the identity
deriv (inv(A)) = - inv(A) * deriv(A) * inv(A)
i.e., compute the inverse of the plain matrix, then compute the expression above.

Why glm transform functions are applied "backwards"?

Edit: it is "backwards" to me - I may be missing some intuition
Given a glm transform function such as glm::translate, the two parameters are first a matrix m and then a vector v for translation.
Intuitively, I would expect this function to apply the translation "after" my matrix transform, i.e. multiplying an object by the returned matrix will first apply m followed by the translation v specified.
This intuition comes from the fact that one usually builds a transformation in mathmetical order e.g. first compute a scale matrix, then apply rotation, then transform etc. so I would think the function calling order would be the same (i.e. given a matrix, I can simply call glm::translate to apply a translation which happens after my matrix's transform is applied)
However, as mentioned in this thread, that is not the case - the translation is applied first, followed by the matrix m passed in.
I don't believe this has anything to do with column major/row major convention and notation as some threads suggest. Is there a historical reason for this? It just seems a bit backwards to me and I would probably rewrite the functions unless there's a good enough reason for it.
This intuition comes from the fact that one usually builds a transformation in mathmetical order
But there is no such thing as a mathematical order. Consider the following: v is an n-dimensional vector and M a n x n square matrix. Now the question is: which is the correct multiplication order? And that depends on your convention again. In most classic math textbook, vectors are defined as column vectors. And then: M * v is the only valid multiplication order, while v * M is simply not a valid operation mathematically.
If v is a column vector, then it's transpose v^T is a row vector and then v^T * M is the only valid multiplication order. However, to achieve the same result as before, say x = M * v, you have to also transpose M: x^T = v^T * M^T.
If M is the product of two matrices A and B, what we get here due to the non-commutative way of matrix multiplication is this:
x = M * v
x = A * B * v
x = A * (B * v)
or, we could say:
y = B * v
x = A * y
so clearly, B is applied first.
In the transposed convention with row matrices, we need to follow (A * B)^T = B^T * A^T and get
x^T = v^T * M^T
x^T = v^T * B^T * A^T
x^T = (v^T * B^T) * A^T
So B^T again is applied first.
Actually, when you consider the multiplication order, the matrix which is written closest to the vector is generally the one applied first.
I don't believe this has anything to do with column major/row major convention and notation as some threads suggest.
You are right, it has absolutely nothing to do with that. The storage order can be arbitrary and does not change the meaning of the matrices and operations. The confusion often comes from the fact that interpreting a matrix which is stored column-major as a matrix stored row-major (or vice-versa) will just have the effect of transposing the matrix.
Also, GLSL and HLSL and many math libraries do not use explicit column or row vectors, but use it as it fits. E.g., in GLSL you can write:
vec4 v;
mat4 M;
vec4 a = M * v; // v is treated as column vector here
vec4 b = v * M; // v is treated as row vector now
// NOTE: a and b are NOT equal here, they would be if b = v * transpose(M), so by swapping the multiplication order, you get the effect of transposing the matrix
Is there a historical reason for this?
OpenGL follows classical math conventions at many points (i.e. the window space origin is bottom-left and not top-left as most window systems do work), the old fixed function view space convention was to use a right-handed coordinate system (z pointing out of the screen towards the viewer, so the camera looking towards -z), and the OpenGL spec uses column vectors to this day. This means that the vertex transform has to be M * v and the "reverse" order of the transformations applies.
This means, in legacy GL, the following sequence:
glLoadIdentity(); // M = I
glRotate(...); // M = M * R = R
glTranslate(...); // M = M * T = R * T
will first translate the object, and then rotate it.
GLM was designed to follow the OpenGL conventions by default, and the function glm::mat4 glm::translate(glm::mat4 const& m, glm::vec3 const& translation); is explicitely emulating the old fixed-function GL behavior.
It just seems a bit backwards to me and I would probably rewrite the functions unless there's a good enough reason for it.
Do as you wish. You could set up fnctions which instead of psot-multiply do a pre-multiplication. Or you could set up all transformation matrices as transposed, and post-multiply in the order you consider "intuitive". But note that for someone following either classical math conventions, or typical GL conventions, the "backwards" notation is the "intuitive" one.

How to do Y = aX + Y in C++

I am trying to do matrix operations using C++ STL containers.
There are two vectors of sizes say Y and X of sizes m,n(m>n). I want to multiply X with a scalar and add it from a given index in Y. In this process I don't want to transform X (don't want to use std::transform). In fact the X's are columns in a matrix DPtr. One version I tried is given below.
std::vector<double> D(&DPtr[index1],&DPtr[index1]+size_C);
std::transform(D.begin(), D.end(), D.begin(),std::bind2nd(std::multiplies<double>(), val1*val2));
std::transform (D.begin(), D.end(), YPtr.begin()+index2, YPtr.begin()+index2, std::plus<double>());
I am trying to copy the column in to a temporary vector and do operations on it.
Can some one help me in rewriting the code in a much simpler manner where I need not copy columns into another vector?
I am guessing I have to use std::for_each and lamda expression or a function call? But I am new to C++?
Just to give a lead, I want to write it as
std::for_each(YPtr.begin()+index2,YPtr.begin()+index2+(size_c-1),scalarAdd);
using a function scalarAdd or any lamda expression where I can access DPtr directly.
Also can I write
YPtr.begin()+index2+(size_c-1)
.
as the second argument.Is it valid?
Also Imagine I made the matrix as a C++-vector where all columns of DPtr matrix are stored in one single C++ vector D.
Visual Representation of my question
May I suggest you use a dedicated linear-algebra library like Eigen? With that you could simply write Y += X * a, and the library+compiler will figure out the best implementation for you.
Since you are using C++11, you could use std::transform together with a lambda (std::for_each is not recommended since you need to transform your Y).
std::transform(DPtr.begin() + index1, DPtr.begin() + index1 + size_c, // X
YPtr.begin() + index2, // Y_in
YPtr.begin() + index2, // Y_out
[](double x, double y_in) { return a*x + y_in; });
// y_out = a*x + y_in, for every entry.

Eigen LDLT Cholesky decomposition in-place

I am trying to get Eigen3 to solve a linear system A * X = B with an in-place Cholesky decomposition. I cannot afford to have any temporaries of the size of A pushed on the stack, but I am free to destroy A in the process.
Unfortunately,
A.llt().solveInPlace(B);
is out of question, since A.llt() implicitly pushes a temporary matrix of the size of A on the stack. For the LLT case, I could get access to the necessary functionality like so:
// solve A * X = B in-place for positive-definite A
template <typename AType, typename BType>
void AllInPlaceSolve(AType& A, BType& B)
{
typedef Eigen::internal::LLT_Traits<AType, Eigen::Upper> TraitsType;
TraitsType::inplace_decomposition(A);
TraitsType::getL(A).solveInPlace(B);
TraitsType::getU(A).solveInPlace(B);
}
This works fine, but I am worried that:
My matrices A might be positive semidefinite only, in which case a LDLT decomposition is required
The LLT decomposition calculates sqrt() unnecessarily for the solution of the system
I could not find a way to hook in Eigen's LDLT functionality similarly to the code above, since the code is structured very differently.
So my question is: Is there a way to use Eigen3 for solving a linear system using LDLT decompositions using no more scratch space than for the diagonal matrix D?
One option is to allocate a LDLT solver only once, and call the compute method:
LDLT<MatType> ldlt(size);
// ...
ldlt.compute(A);
x = ldlt.solve(b);
If that's also not an option, you can const cast the matrix stored by the ldlt object:
LDLT<MatType> ldlt(MatType::Identity(size,size));
MatType& A = const_cast<MatType&>(ldlt.matrixLDLT());
plays with A, and then:
ldlt.compute(A);
x = ldlt.solve(b);
This is ugly, but this should work as long as MatType is column major.