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
Related
Does armadillo offer functions that apply element-wise operations only on the diagonal elements of a matrix? Say I want to run an inverse on it then I get infs on off-diagonals. I know that I can get it with arma::inv(m), but for diagonal matrices it seems faster to run it element-wise.
Minimal example:
#include <iostream>
#include <armadillo>
int main() {
arma::Col<double> v = {1.2, 3.14, 2.71, 0.1};
arma::Mat<double> m = arma::diagmat(v);
std::cout << " A diagonal matrix:\n" << m << "\n\n";
std::cout << " It's elemenet-wise inverse:\n" << 1.0/m << std::endl;
return 0;
}
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
What is the correct way to determine if a number (in my case it is a value of power of two calculated by pow(2,n)) is within the limits of values that one variable type can take? I'm doing it like this: if(pow (2,128)>std::numeric_limits<float>::max()), but this is evaluated as true although it is expected that float's maximum value is 2^128 or something more. Is there any better way to do this comparison?
For these kinds of limit checking, you can move the terms around to stay within the limits of the type.
In this case, pow(2,n) == exp(ln(2)*n) mathematically, so, rearranging terms, you can use n > ln(maxval)/ln(2)
You can take the base 2 logarithm of the maximum limit for the type of variable and compare it to n. For example: if(n > std::log2(std::numeric_limits<float>::max()). You probably don't want n to be exactly on the limit though, since I think stuff like floating point error might cause some problems.
First of all can you answer what is the result of pow(2, 128)?
The real question is what is the type for this expression?
The second question is do you know how floating point numbers work?
Take a look on this code to give you a hints:
#include <cmath>
#include <iostream>
#include <limits>
template<class T>
void printInfo(const std::string& desc, T x)
{
std::cout << desc << ' ' << typeid(x).name() << ' ' << x << std::endl;
}
int main()
{
printInfo("A", std::pow(2, 128));
printInfo("B", std::pow(2.0f, 128));
printInfo("A", std::pow(2, 128.0f));
auto c = std::pow(2.0f, 128.0f);
printInfo("C", c);
std::cout << (c > std::numeric_limits<float>::max()) << std::endl;
std::cout << (c == std::numeric_limits<float>::infinity()) << std::endl;
return 0;
}
https://wandbox.org/permlink/bHdKqToDKdC0hSvW
I recommend review documentation of numeric_limits.
And analyze this code:
#include <cmath>
#include <iostream>
#include <limits>
template<class T>
void print2exp()
{
std::cout << typeid(T).name() << '\n';
std::cout << "Radix = " << std::numeric_limits<T>::radix << '\n';
auto maxExp = std::numeric_limits<T>::max_exponent;
std::cout << "Max exp = " << maxExp << '\n';
std::cout << "2^maxExp = " << std::pow(static_cast<T>(2), static_cast<T>(maxExp)) << '\n';
std::cout << "2^(maxExp - 1) = " << std::pow(static_cast<T>(2), static_cast<T>(maxExp - 1)) << '\n';
}
int main()
{
print2exp<float>();
print2exp<double>();
print2exp<long double>();
return 0;
}
https://wandbox.org/permlink/J0hACKUKvKlV8lYK
So proper approach to this is (assuming that radix is 2):
if (x < std::numeric_limits<T>::max_exponent) {
return std::pow(static_cast<T>(2), static_cast<T>(x));
} else {
throw invalid_argument("x is to big to be use as 2^x");
}
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).
I have been trying out a couple computer algebra libraries for C++ to use with a vector calculus course I am taking. I am having trouble with nonlinear equations in GiNaC and in SymbolicC++ it actually worked.
Here is a simple example, but the problem is I can't figure out how to evaluate to a number and maybe cast it to a double or float:
#include <iostream>
#include "symbolicc++.h"
using namespace std;
int main(void)
{
Symbolic x("x"), y("y");
Equation e1 = (x^2) + (y^2) == 13;
Equation e2 = (x^2) - y == 7;
Equations eqs = {e1, e2};
list<Symbolic> symbs = {x, y};
list<Equations> sols = solve(eqs, symbs);
Symbolic x_sol, y_sol;
int i = 1;
for( auto iter1 = sols.begin(); iter1 != sols.end(); iter1++)
{
x_sol = x.subst((*(*iter1).begin()));
y_sol = y.subst((*(--(*iter1).end())));
cout << "p" << i << " = {" << x_sol << ", " << y_sol << "};" << endl;
i++;
}
return 0;
}
With that output I can copy and past it to ginsh and it evaluates just fine, but it stays in expanded form in SymbolicC++.
The exact ouput I am getting is as follows:
p1 = {1/2*(-2*(25)^(1/2)+26)^(1/2), -1/2*(25)^(1/2)-1/2};
p2 = {1/2*(2*(25)^(1/2)+26)^(1/2), 1/2*(25)^(1/2)-1/2};
p3 = {-1/2*(-2*(25)^(1/2)+26)^(1/2), -1/2*(25)^(1/2)-1/2};
p4 = {-1/2*(2*(25)^(1/2)+26)^(1/2), 1/2*(25)^(1/2)-1/2};
How can I evaluate expressions like these and cast them to doubles?
I realize that this an answer to almost a year old question. But there's no way to directly cast a string to a number. You would need to calculate the floating-point value you're interested - the same way you do it on a calculator. https://code.google.com/p/exprtk/ is a link to a very easy to use library to accomplish exactly what you're looking for. You will have to get the Symbolic object into a string class using a string stream
Try:
cout << "p" << i << " = {" << double(x_sol) << ", " << double(y_sol) << "};" << endl;