Dot product in Eigen by multiplying by transpose? - c++

I can't seem to make it work, should it?
e.g.:
Vector3d a;
Vector3d b;
...
double c = a.transpose() * b; // Doesn't work
double c = a.dot(b); // Seems to work
I'm coming from MATLAB where a'*b is the thing. I can deal with using dot if needed, but I'd like to know if I'm just doing something dumb.

In matlab, a'*b is syntactic sugar for dot(a, b). Note that the requirement for vectors is "they must have the same length" and not that one is a row vector, and one a column. This is the same as Eigen's a.dot(b).
In Eigen, a.transpose() * b works, it just doesn't return a double but rather a 1x1 matrix. If you wrote it as MatrixXd c = a.transpose() * b; or double c = (a.transpose() * b)[0]; it should work as expected.
That above paragraph was the case at in Eigen 2 (which apparently OP was using). Since then (Eigen 3), #ggael of course, is right. This answer regarded a general case where the dimensions of a and b are not known at compile time. In the case where Vector3d or VectorXd are used, then double c = a.transpose() * b; works as well, not as stated in the question. With versions <= 2.0.15, the original is correct without any reservations.

Related

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.

Is there a way to set up an app to solve equations and then compare them in C++?

I am trying to write a piece of code for my old Highschool teacher for a game he had us play literally called the "Dice Game." Let's just say that the game takes two d12's and multiplies them together to get a number (D) in this instance. Then you take 3 d6's and roll them to get your A, B, and C variables. You would then either Add, Subtract, Multiply, Divide, Exponentiate, or Root by that number to get as close to as you could to D. Those operations would stand for x and y in the following equation
AxByC=D
I don't know how else to word this, but I am having trouble finding any way to solve these equations and then compare them. Maybe I am missing something simple, but I don't know.
EDIT: I should probably be more clear about the question. I know how to set all the equations up. It is just a matter of finding a way to compare the answers to the D variable and then the other answers to the equation to see which one is closer. The closest number to D wins, thus the whole point to the dice game.
If you are just trying to compare the answers to the D variable, why not loop through each equations result and compare them equal to D?
for (int i = 0; i < equationResults.size(); i++) {
if (equationResults[i] == D)
return true;
}
EDIT: If you are trying to find the closest to D, you can compare each answer to D and subtract the answer from D and store it, then return the min value:
closeToD[0] = D - equationResults[0];
return *min_element(closeToD.begin(), closeToD.end());
Since you can juggle the values around, as well as picking operators, you actually have two problems: generating the permutations of variables and generating the permutations of operators. The first part is rather straightforward:
std::array<int, 3> input;
std::sort(input.begin(), input.end());
do {
compute(input[0], input[1], input[2]);
} while (std::next_permutation(input.begin(), input.end()));
The compute part could be a function that takes such an array of 3 values and finds the best value, or closest to D, or just all values.
Generating all permutations of operators is slightly more annoying because next_permutation can't compare them, and also we accept duplicates. The easiest way is to just brute-force through them; I'll do it just for the slightly easier operators:
std::array<int, 16> compute(int a, int b, int c) {
return {
a + b + c,
a + b - c,
a + b * c,
a + b / c,
a - b + c,
a - b - c,
a - b * c,
a - b / c,
a * b + c,
a * b - c,
a * b * c,
a * b / c,
a / b + c,
a / b - c,
a / b * c,
a / b / c,
};
}
Generating such list of operations programmatically is a bit more challenging; you can't simply do (a op b) op c because of the aforementioned precedence. Doing it this way guarantees that the results are actually achievable because of the operator precedence built into the language.
This will still do redundant computations - e.g. in the first case, the result will be the same regardless of the permutation of a/b/c. Eliminating those is perhaps a more interesting exercise for later. Perhaps a small relief is the fact that if a == b or b == c, next_permutation will already take care of that for us, cutting the number of iterations from 6 to either 3 or 1.

Add Matrix and DiagonalMatrix in Eigen3

I want to add elements to the diagonal of a Eigen::MatrixXd object with the Eigen3 library (version 3.3.2).
Both for optimisation and being able to use constness, I want to do this by adding a diagonal matrix to the original, like this
const MatrixXd a(2,2); a << 1, 2, 3, 4;
const VectorXd v(2); v << 10, 20;
const MatrixXd b = a + v.asDiagonal();
But this doesn't work: I get a compiler error about there being no operator+. Adding two MatrixXd does work, so I would expect it to behave for the diagonal specialisation.
Removing the constness doesn't help. Using statically sized matrices makes no difference, so it's not a dynamic-sizing thing. And explicitly constructing a DiagonalMatrix rather than using the DiagonalWrapper returned by asDiagonal() also gives the same error.
Multiplication is well-formed for these types: MatrixXd c = a * v.asDiagonal(); compiles and runs just fine. Am I doing something wrong, or is operator+(Matrix,DiagonalMatrix) just missing from the library?
Thanks to #CoryKramer for linking to an equivalent question being asked and answered on the KDE/Eigen forum: https://forum.kde.org/viewtopic.php?f=74&t=136617 Here's a summary for posterity:
"Normal" addition of an Eigen Matrix and either a DiagonalMatrix or DiagonalWrapper isn't a supported operation, while multiplication or compound += addition are fine. += isn't an option if trying to work with const objects, but constructing an explicit Matrix2d from the asDiagonal() call -- why didn't I think of trying that?! -- works nicely:
MatrixXd b = a + Matrix2d(v.asDiagonal());
I guess there are potential performance penalties, which is why this isn't supported without the type construction. But they're unlikely to be worse than the dirty alternative of manually looping over diagonal indices.

Eigen and C++11 type inference fails for Cholesky of matrix product

I am trying to take the cholesky decomposition of the product of a matrix with its transpose, using Eigen and C++11 "auto" type. The problem comes when I try to do
auto c = a * b
auto cTc = c.tranpose() * c;
auto chol = cTc.llt();
I am using XCode 6.1, Eigen 3.2.2. The type error I get is here.
This minimal example shows the problem on my machine. Change the type of c from auto to MatrixXd to see it work.
#include <iostream>
#include <Eigen/Eigen>
using namespace std;
using namespace Eigen;
int main(int argc, const char * argv[]) {
MatrixXd a = MatrixXd::Random(100, 3);
MatrixXd b = MatrixXd::Random(3, 100);
auto c = a * b;
auto cTc = c.transpose() * c;
auto chol = cTc.llt();
return 0;
}
Is there a way to make this work while still using auto?
As a side question, is there a performance reason to not assert the matrix is a MatrixXd at each stage? Using auto would allow Eigen to keep the answer as whatever weird template expression it fancies. I'm not sure if typing it as MatrixXd would cause problems or not.
The problem is that the first multiplication returns a Eigen::GeneralProduct instead of a MatrixXd and auto is picking up the return type. You can implicitly create a MatrixXd from a Eigen::GeneralProduct so when you explicitly declare the type it works correctly. See http://eigen.tuxfamily.org/dox/classEigen_1_1GeneralProduct.html
EDIT: I'm not an expert on the Eigen product or performance characteristics of doing the casting. I just surmised the answer from the error message and confirmed from the online documentation. Profiling is always your best bet for checking the performance of different parts of your code.
Let me summarize what's is going on and why it's wrong. First of all, let's instantiate the auto keywords with the types they are taking:
typedef GeneralProduct<MatrixXd,MatrixXd> Prod;
Prod c = a * b;
GeneralProduct<Transpose<Prod>,Prod> cTc = c.transpose() * c;
Note that Eigen is an expression template library. Here, GeneralProduct<> is an abstract type representing the product. No computation are performed. Therefore, if you copy cTc to a MatrixXdas:
MatrixXd d = cTc;
which is equivalent to:
MatrixXd d = c.transpose() * c;
then the product a*b will be carried out twice! So in any case it is much preferable to evaluate a*b within an explicit temporary, and same for c^T*c:
MatrixXd c = a * b;
MatrixXd cTc = c.transpose() * c;
The last line:
auto chol = cTc.llt();
is also rather wrong. If cTc is an abstract product type, then it tries to instantiate a Cholesky factorization working on a an abstract product type which is not possible. Now, if cTc is a MatrixXd, then your code should work but this still not the preferred way as the method llt() is rather to implement one-liner expression like:
VectorXd b = ...;
VectorXd x = cTc.llt().solve(b);
If you want a named Cholesky object, then rather use its constructor:
LLT<MatrixXd> chol(cTc);
or even:
LLT chol(c.transpose() * c);
which is equivalent unless you have to use c.transpose() * c in other computations.
Finally, depending of the sizes of a and b, it might be preferable to compute cTc as:
MatrixXd cTc = b.transpose() * (a.transpose() * a) * b;
In the future (i.e., Eigen 3.3), Eigen will be able to see:
auto c = a * b;
MatrixXd cTc = c.transpose() * c;
as a product of four matrices m0.transpose() * m1.transpose() * m2 * m3 and put the parenthesis at the right place. However, it cannot know that m0==m3 and m1==m2, and therefore if the preferred way is to evaluate a*b in a temporary, then you will still have to do it yourself.
I'm not an expert at Eigen, but libraries like this often return proxy objects from operations and then use implicit conversion or constructors to force the actual work. (Expression Templates are an extreme example of this.) This avoids unnecessary copying of the full matrix of data in many situations. Unfortunately, auto is quite happy to just create an object of the proxy type, which normally users of the library would never explicitly declare. Since you need to ultimately have the numbers calculated, there is not a performance hit per se from casting to a MatrixXd. (Scott Meyers, in "Effective Modern C++", gives the related example of using auto with vector<bool>, where operator[](size_t i) returns a proxy.)
DO NOT use auto with Eigen expressions. I bumped into even more "dramatic" issues with this before, see
eigen auto type deduction in general product
and was advised by one of the Eigen creators (Gael) not to use auto with Eigen expressions.
The cast from an expression to a specific type like MatrixXd should be extremely fast, unless you want lazy evaluation (since when doing the cast the result is evaluated).

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;