When I try to call lpNorm<1> with colwise() in Eigen I get the error:
error: 'Eigen::DenseBase > >::ColwiseReturnType' has no member named 'lpNorm'
Instead norm() and squaredNorm() work fine calling them colwise.
example
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
MatrixXf m(2,2), n(2,2);
m << 1,-2,
-3,4;
cout << "m.colwise().squaredNorm() = " << m.colwise().squaredNorm() << endl;
cout << "m.lpNorm<1>() = " << m.lpNorm<1>() << endl;
// cout << "m.colwise().lpNorm<1>() = " << m.colwise().lpNorm<1>() << endl;
}
works fine giving
m.colwise().squaredNorm() = 10 20
m.lpNorm<1>() = 10
If I uncomment the last line I get the error.
Can someone help?
It is not implemented for colwise in Eigen <=3.2.9. You have two options:
Upgrade to Eigen 3.3 (beta)
Loop over all columns and calculate the lp norms one by one.
You may by-pass it that way:
m.cwiseAbs().colwise().sum()
Unfortunately it only works in case of L1 norm (which is equivalent of an absolute value).
Related
I'm using eigen3 to take the inverse of the matrix,but the inverse is wrong.
I tried several examples,but the following this is wrong.
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
int main(){
Matrix3d Mat1;
Mat1 << 99.999999999999972 ,-29024.672261149386 ,29024.848775176863,-29024.672261149386, 8629880.2300641891 ,-8629930.2299046051,29024.848775176863,-8629930.2299046051 , 8629980.2300641891 ;
cout << "Mat1=\n" << Mat1 << endl;
Matrix3d Mat2=Mat1.inverse();
cout << "Mat1逆矩阵:\n" << Mat2 << endl;
cout << "Mat1*Mat2:\n" << Mat1*Mat2 << endl;
cout << "Mat2*Mat1:\n" << Mat2*Mat1 << endl;
cout << "Mat1行列式:\n" << Mat1.determinant() << endl;
the result is:
Mat1=
100 -29024.7 29024.8
-29024.7 8.62988e+06 -8.62993e+06
29024.8 -8.62993e+06 8.62998e+06
Mat1逆矩阵:
44.3313 -12557.7 -12557.8
-12557.7 3.58199e+06 3.58201e+06
-12557.8 3.58201e+06 3.58204e+06
Mat1*Mat2:
1 -0.000198364 0.000823975
-80.0958 0.785156 -0.242188
80.0963 -0.0634151 0.972687
Mat2*Mat1:
1 -80.0958 80.0963
-0.000198364 0.785156 -0.0625
0.000818345 -0.243301 0.972687
Mat1行列式:
5.73875
Shouldn't mat1*mat2 be a unit matrix?
Try using pseudo-inverse instead. That problem maybe a precision issues as #paddy said.
Got that code from here
#include <Eigen/QR>
Eigen::MatrixXd A = ... // fill in A
Eigen::MatrixXd pinv = A.completeOrthogonalDecomposition().pseudoInverse();
My result:
Mat3*Mat1:
1 3.05176e-05 -3.05176e-05
0 1 -0.0078125
2.88524e-05 -0.0137121 1.00454
Mat1*Mat3:
1.00004 -0.0101929 -0.0101624
-3.05176e-05 1.00781 0
5.83113e-05 -0.0134087 0.996313
Before anything else I must say that I've studied Comparing two matrices with eigen
but my question is not the same. Suppose I have two eigen matrices A and B, and I want to edit A in following way:
if (A(i,j) > B(i,j)) A(i,j) = A(i,j)
otherwise A(i,j) = B(i,j)
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?
It's A.cwiseMax(B).
#include <iostream>
#include <Eigen/Dense>
int main()
{
Eigen::Matrix2i A = Eigen::Matrix2i::Random();
Eigen::Matrix2i B = Eigen::Matrix2i::Random();
std::cout << "A =\n" << A << "\nB =\n" << B << "\n";
A = A.cwiseMax(B);
std::cout << "max(A,B) =\n" << A << "\n";
}
Output on my machine is
A =
730547559 607950953
-226810938 640895091
B =
884005969 -353856438
-649503489 576018668
max(A,B) =
884005969 607950953
-226810938 640895091
I am trying to get used to armadillo linear algebra library for c++ and I cannot figure out hot to operate on slices(matrices) of a cube. Whenever I try to operate on a slice, the program compiles but does not give any output, not even the outputs of statement before the slice operation.
Here's the code:
#include <armadillo>
#include <iostream>
using namespace arma;
using namespace std;
int main()
{
Cube<double> A(3 , 5 ,1, fill::randu);
Cube<double>B(5,3,1,fill::randu);
Mat<double>x =A.slice(0);
Mat<double>y = B.slice(0);
cout << x << "\n" << y << endl;
cout << x*y << endl; //code works fine if this line is removed
}
the problem is that the code works fine if the last line is removed. Why does this happen? Is there a better way to operate on matrices inside a cube ?
Use directions given in the accepted answer to this question, to install Armadillo on Windows using Visual Studio.
If you have asked the Linker to use blas_win64_MT.lib and lapack_win64_MT.lib libraries, make sure to add the respective .dll's in the same directory as your .exe file. Then using this code, I get the desired output.
#include <armadillo>
#include <iostream>
using namespace std;
using namespace arma;
int main()
{
Cube<double> A(3, 5, 1, fill::randu);
Cube<double> B(5, 3, 1, fill::randu);
Mat<double> x = A.slice(0);
Mat<double> y = B.slice(0);
std::cout << "x:\n" << x << "\ny:\n" << y << std::endl;
std::cout << "x*y:\n" << x*y << std::endl;
}
Output in command window:
Hope that helps!
There is this:
https://codeyarns.com/2016/02/16/how-to-compare-eigen-matrices-for-equality/
But there is no isApprox for tensors.
The following doesn't do what I want:
#include <Eigen/Core>
#include <unsupported/Eigen/CXX11/Tensor>
#include <array>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
// Create 2 matrices using tensors of rank 2
Eigen::Tensor<int, 2> a(2, 3);
Eigen::Tensor<int, 2>* b = &a;
cerr<<(*b==*b)<<endl;
}
because it does coordinate wise comparison and returns a tensor of the same dimension instead of a true/false vale.
How do I check if two tensors are identical? No isApprox for tensors.
I could write my own function, but I want to be able to use GPU power when available, and it seems like Eigen has built-in GPU support.
For an exact comparison of 2 tensors A and B, you can use the comparison operator followed by a boolean reduction:
Tensor<bool, 0> eq = (A==B).all();
This will return a tensor of rank 0 (i.e. a scalar) that contains a boolean value that's true iff each coefficient of A is equal to the corresponding coefficient of B.
There is no approximate comparison at the moment, although it wouldn't be difficult to add.
You can always use a couple of Eigen::Maps to do the isApprox checks.
#include <iostream>
#include <unsupported/Eigen/CXX11/Tensor>
using namespace Eigen;
int main()
{
Tensor<double, 3> t(2, 3, 4);
Tensor<double, 3> r(2, 3, 4);
t.setConstant(2.1);
r.setConstant(2.1);
t(1, 2, 3) = 2.2;
std::cout << "Size: " << r.size() << "\n";
std::cout << "t: " << t << "\n";
std::cout << "r: " << r << "\n";
Map<VectorXd> mt(t.data(), t.size());
Map<VectorXd> mr(r.data(), r.size());
std::cout << "Default isApprox: " << mt.isApprox(mr) << "\n";
std::cout << "Coarse isApprox: " << mt.isApprox(mr, 0.11) << "\n";
return 0;
}
P.S./N.B. Regarding Eigen's built in GPU support... Last I checked it is fairly limited and with good reason. It is/was limited to fixed size matrices as dynamic allocation on a GPU is really something you want to avoid like the common cold (if not like the plague). I take it back. It looks like the Tensor module supports GPUs pretty well.
I've recently configurated OpenCV in my machine as described in here.
I'm trying to run this simple code:
#include "opencv2/core/core.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int,char**)
{
Mat i = Mat::eye(4, 4, CV_64F);
i.at<double>(1,1) = CV_PI;
// First problem
cout << "i = " << i << ";" << endl;
Mat r = Mat(10, 3, CV_8UC3);
randu(r, Scalar::all(0), Scalar::all(255));
cout << "r (default) = " << r << ";" << endl << endl;
// Problematic Line:
cout << "r (python) = " << format(r,"python") << ";" << endl << endl;
return 0;
}
Which is part of one of the samples included in OpenCV 2.4.5. I should also note that I'm using Visual Studio 2008.
While debugging I get two problems. The first one is that the matrix i isn't displayed at all in the console application (The following screenshot was taken right after the 11th line was executed).
The second problem is a run-time error, wich takes place while trying to execute line 17:
Any thoughts?