I've been converting RGBDSLAM to armhf (https://github.com/felixendres/rgbdslam_v2) and I've been encountering errors with this function:
template <typename T >
QMatrix4x4 eigenTF2QMatrix(const T& transf)
{
Eigen::Matrix<double, 4, 4, Eigen::RowMajor> m = transf.matrix();
//QMatrix4x4 qmat( static_cast<qreal*>( m.data() ) ); (original line)
QMatrix4x4 qmat( m.data() );
printQMatrix4x4("From Eigen::Transform", qmat);
return qmat;
}
The line:
QMatrix4x4 qmat( m.data() );
as well as the original:
QMatrix4x4 qmat( static_cast<qreal*>( m.data() ) );
Gives me the error:
error: invalid conversion from 'Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 4, 1> >::Scalar* {aka double*}' to 'int' [-fpermissive]
How can I fix this function to work on arm?
You cannot cast a pointer and expect it to work. There is the cast method of Eigen, but it does not work with temporaries, so you will have to perform a copy:
using Eigen;
Matrix<qreal, 4, 4, RowMajor> mcopy = m.cast<qreal>();
QMatrix4x4 qmat(mcopy.data());
Related
I'd like to efficiently initialize segments of an VectorXd object from the Eigen library. This vector is large (~1e6) so I would like to do this efficiently. Below is an example showing what I was thinking.
size_t N = 1e6;
std::vector<double> F(1., 2., 3., 4.);
Eigen::VectorXd ln_f_origin( F.size() * num_B );
for (size_t i=0; i<F.size(); i++) {
ln_f_origin.segment(i*num_B, num_B) = log(F[i]/num_B);
}
This doesn't seem to be working. I'm getting the following error:
error: no match for 'operator=' (operand types are 'Eigen::DenseBase<Eigen::Matrix<double, -1, 1> >::FixedSegmentReturnType<-1>::Type' {aka 'Eigen::VectorBlock<Eigen::Matrix<double, -1, 1>, -1>'} and 'double')
I'm getting no matching function for call to ‘normalize(cv::Point3f&)’ error in this code snippet using gcc 9.3.0 and OpenCV 4.3.0:
cv::Point3f p{3, 0, 0}, q{0, 2, 0};
p.cross(q);
cv::normalize(p);
According to current documentation, both cross and normalize accept the same parameter type, which is const Vec< _Tp, cn > &. Why then call to cross compiles, but call to normalize doesn't?
EDIT
I know that cv::normalize((Vec3f)p); works. The question is why this explicit conversion to Vec3f is necessary here, but not in case of cross()?
cv::norm(...) gives you the norm (a scalar value) of your vector. You can normalize a vector by dividing by its norm.
Given two vector p, q, you can get the normal vector as:
cv::Point3f p{3, 0, 0}, q{0, 2, 0};
cv::Point3f r = p.cross(q);
cv::Point3f rn = r / cv::norm(r);
You can also use cv::Vec3f instead of cv::Point:
cv::Vec3f p{3, 0, 0}, q{0, 2, 0};
cv::Vec3f r = p.cross(q);
cv::Vec3f rn = r / cv::norm(r);
// or
cv::Vec3f rm = cv::normalize(r);
The question is why this explicit conversion to Vec3f is necessary here
Because cv::normalized is defined for cv::Vec_<Tp, 3>, not for cv::Point3_<Tp>
template<typename _Tp, int cn> inline
Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v)
{
double nv = norm(v);
return v * (nv ? 1./nv : 0.);
}
Please note that it just divides the vector by its norm, as showed above for the cv::Point3f case.
but not in case of cross()
cross is a method of the class cv::Point3_
Also note that cv::Point3_ has an overloaded conversion operator for cv::Vec
//! conversion to cv::Vec<>
operator Vec<_Tp, 3>() const;
According to the doc for 4.3.0, you need to include <opencv/core/matx.hpp>, have you tried that?
I do also understand from the doc that you need to assign the return value, the input argument is const, and you need to do that also for the cross product. So it's going o be something like:
#include <opencv/core/matx.hpp>
...
cv::Point3f p{3, 0, 0}, q{0, 2, 0};
auto normalized = cv::normalize(p.cross(q));
--EDIT--
There's also a mismatch in the type (Vec instead of Point). This last version builds fine:
cv::Vec3f p{3, 0, 0}, q{0, 2, 0};
auto normalized = cv::normalize(p.cross(q)); // Defined only for Vec_
cv::Point3f p3 = normalized; // Get back a Point3f, or continue with a Vec?
I'm trying to implement the activation function tanh on my CNN, but it doesn't work, the result is always "NaN". So i created a simple application where i have a randomized matrix and try to apply the tanh(x) function thus to understand where's the problem?
Here's my implementation :
Eigen::MatrixXd A = Eigen::MatrixXd::Random(10,1000);
Eigen::MatrixXd result, deriv;
result = A.array().tanh();
deriv = 1.0 - result*result;
and the only result to this is this error :
no match for ‘operator-’ (operand types are ‘double’ and ‘const Eigen::Product<Eigen::Matrix<double, -1, -1>, Eigen::Matrix<double, -1, -1>, 0>’)
deriv = (1.0 - result*result );
~~~~^~~~~~~~~~~~~~~
Could you please help me ?
The product result*result does not have the right dimensions for a matrix multiplication. We can use result*result.transpose() instead (unless a coefficient-wise multiplication is intended, in which case one could use result.array()*result.array()).
To subtract the values of the resulting matrix from a matrix full of ones, the .array() method can be used:
deriv = 1. - (result*result.transpose()).array();
I used openCV to create a matrix of ones
like this :
cv::Mat sum;
Eigen::MatrixXd SUM, Acv;
cv::eigen2cv(A,Acv)
sum=Mat::ones(Acv.rows,Acv.cols, CV_32FC1);
cv::cv2eigen(sum,SUM);
so :
deriv = SUM - result*result;
and now, here's another problem :(
/usr/include/eigen3/Eigen/src/Core/CwiseBinaryOp.h :110 : Eigen::CwiseBinaryOp<BinaryOp, Lhs, Rhs>::CwiseBinaryOp(const Lhs&, const Rhs&, const BinaryOp&) [with BinaryOp = Eigen::internal::scalar_difference_op<double, double>; LhsType = const Eigen::Matrix<double, -1, -1>; RhsType = const Eigen::Product<Eigen::Matrix<double, -1, -1>, Eigen::Matrix<double, -1, -1>, 0>; Eigen::CwiseBinaryOp<BinaryOp, Lhs, Rhs>::Lhs = Eigen::Matrix<double, -1, -1>; Eigen::CwiseBinaryOp<BinaryOp, Lhs, Rhs>::Rhs = Eigen::Product<Eigen::Matrix<double, -1, -1>, Eigen::Matrix<double, -1, -1>, 0>]: l'assertion « aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols() » a échoué.
I'm sure this question exists somewhere on this site, but I guess I'm not too sure what to search because I haven't found my answer yet. So I apolgoize if I am posting a duplicate.
Anyway, I am trying to create a vector of pointers that point to a vectors.
Here is what I have so far:
float knot_vector1[] = {-1,-1,-1 0,1,1,1};
float knot_vector2[] = {-1, -1, 1, 1};
float knot_vector3[] = {-1, -1, -1, -1, 0, .5, .5, .5, 1, 1, 1, 1};
// initialize vectors with the arrays defined above
vector<float> U1 (knot_vector1, knot_vector1 + sizeof(knot_vector1) / sizeof(knot_vector1[0]) );
vector<float> U2 (knot_vector2, knot_vector2 + sizeof(knot_vector2) / sizeof(knot_vector2[0]) );
vector<float> U3 (knot_vector3, knot_vector3 + sizeof(knot_vector3) / sizeof(knot_vector3[0]) );
vector<float> *ptr_u1 = &U1; // creating pointers that point to my vectors
vector<float> *ptr_u2 = &U2;
vector<float> *ptr_u3 = &U3;
vector<vector<float>*> knotvectors[] = {ptr_u1, ptr_u2, ptr_u3};
Here is the error I receive:
error: conversion from 'std::vector<float>*' to non-scalar type 'std::vector<std::vector<float>*>' requested|
So obviously something is wrong with the last line where I define my vector of pointers. What is the proper way to do this?
Thank you in advance.
This
vector<vector<float>*> knotvectors[] = {ptr_u1, ptr_u2, ptr_u3};
is an array of vector<vector<float>*>.
You want
vector<vector<float>*> knotvectors = {ptr_u1, ptr_u2, ptr_u3};
It seems you mean the following
vector<vector<float>*> knotvectors = {ptr_u1, ptr_u2, ptr_u3};
Or maybe it would be better just to write
vector<vector<float>> knotvectors = { U1, U2, U3};
I am trying to compile my code, which has matrix multiplication, with intel C++ compiler. For the matrix multiplication, I am using Eigen library. This is the sample code. I am using VS2013 with the latest version of Eigen library.
#define EIGEN_USE_MKL_ALL
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
Matrix<double, 1, 200, RowMajor> y_pred;
y_pred.setRandom(); // Eigen library function
double learning_rate = 0.5;
cout << learning_rate * y_pred << endl;
return 1;
}
When I am using intel C++ compiler I get the following error:
1>error : more than one operator "*" matches these operands:
1> function "Eigen::operator*(const double &, const Eigen::MatrixBase<Eigen::Matrix<double, 1, 200, 1, 1, 200>> &)"
1> function "Eigen::operator*(const std::complex<double> &, const Eigen::MatrixBase<Eigen::Matrix<double, 1, 200, 1, 1, 200>> &)"
1> function "Eigen::internal::operator*(const float &, const Eigen::Matrix<std::complex<float>, -1, -1, 0, -1, -1> &)"
1> function "Eigen::internal::operator*(const float &, const Eigen::Matrix<std::complex<float>, -1, 1, 0, -1, 1> &)"
1> function "Eigen::internal::operator*(const float &, const Eigen::Matrix<std::complex<float>, 1, -1, 1, 1, -1> &)"
1> function "Eigen::internal::operator*(const float &, const Eigen::Matrix<Eigen::scomplex, -1, -1, 1, -1, -1> &)"
1> operand types are: float * Eigen::Matrix<double, 1, 200, 1, 1, 200>
1> y_pred = learning_rate * y_pred;
You can explicitly perform a scalar computation:
cout << learning_rate * y_pred.array() << endl;