I have the following line of code in a sycl application under a parallel_for:
queue.submit(
[&map, &output](cl::sycl::handler& cgh)
{
auto d_image = output.get_access<access::mode::read_write>(cgh);
auto d_map_probabilities =
map.probabilities.get_access<access::mode::read>(cgh);
cgh.parallel_for<class CreateImage>(
map.probabilities.get_range(),
[=](id<3> work_position)
{
// ... Code!
float3 relative{};
float elevation =
atan2(relative.z(), length(relative.xy())) * 30.0f * M_2_PI_F;
}
}
);
For which i get the error:
error: no matching function for call to 'length'
atan2(relative.z(), length(relative.xy())) * 30.0f * M_2_PI_F;
^~~~~~
/opt/sycl/bin/../include/sycl/CL/sycl/builtins.hpp:1032:7: note: candidate template ignored: requirement 'detail::is_contained<sycl::detail::SwizzleOp<sycl::vec<float, 3>, sycl::detail::GetOp<float>, sycl::detail::GetOp<float>, sycl::detail::GetOp, 0, 1>, sycl::detail::type_list<sycl::detail::type_list<float>, sycl::detail::type_list<sycl::vec<float, 1>, sycl::vec<float, 2>, sycl::vec<float, 3>, sycl::vec<float, 4>>>>::value' was not satisfied [with T = sycl::detail::SwizzleOp<sycl::vec<float, 3>, sycl::detail::GetOp<float>, sycl::detail::GetOp<float>, sycl::detail::GetOp, 0, 1>]
float length(T p) __NOEXC {
^
/opt/sycl/bin/../include/sycl/CL/sycl/builtins.hpp:1039:8: note: candidate template ignored: requirement 'detail::is_contained<sycl::detail::SwizzleOp<sycl::vec<float, 3>, sycl::detail::GetOp<float>, sycl::detail::GetOp<float>, sycl::detail::GetOp, 0, 1>, sycl::detail::type_list<sycl::detail::type_list<double>, sycl::detail::type_list<sycl::vec<double, 1>, sycl::vec<double, 2>, sycl::vec<double, 3>, sycl::vec<double, 4>>>>::value' was not satisfied [with T = sycl::detail::SwizzleOp<sycl::vec<float, 3>, sycl::detail::GetOp<float>, sycl::detail::GetOp<float>, sycl::detail::GetOp, 0, 1>]
double length(T p) __NOEXC {
^
/opt/sycl/bin/../include/sycl/CL/sycl/builtins.hpp:1046:6: note: candidate template ignored: requirement 'detail::is_contained<sycl::detail::SwizzleOp<sycl::vec<float, 3>, sycl::detail::GetOp<float>, sycl::detail::GetOp<float>, sycl::detail::GetOp, 0, 1>, sycl::detail::type_list<sycl::detail::type_list<sycl::detail::half_impl::half>, sycl::detail::type_list<sycl::vec<sycl::detail::half_impl::half, 1>, sycl::vec<sycl::detail::half_impl::half, 2>, sycl::vec<sycl::detail::half_impl::half, 3>, sycl::vec<sycl::detail::half_impl::half, 4>>>>::value' was not satisfied [with T = sycl::detail::SwizzleOp<sycl::vec<float, 3>, sycl::detail::GetOp<float>, sycl::detail::GetOp<float>, sycl::detail::GetOp, 0, 1>]
half length(T p) __NOEXC {
^
Basically it comes down to this. The operation relative.xy() produces the type:
sycl::detail::SwizzleOp<sycl::vec<float, 3>, sycl::detail::GetOp<float>, sycl::detail::GetOp<float>, sycl::detail::GetOp, 0, 1>
which is not implicitly convertible to float2 which is required by the length function. It should be though, this was fine to do in opencl. This can be solved by the workaround:
float2 rel_part = relative.xy();
float elevation = atan2(relative.z(), length(rel_part)) * 30.0f * M_2_PI_F;
Or
float elevation = atan2(relative.z(), length(float2{relative.xy()})) * 30.0f * M_2_PI_F;
But this defeats the purpose of a nice swizzle definition. Is there a way around this?
Related
I am trying to implement some auto-differentation jacobians for verification of analytical jacobians. These are the functions in question being tested. When I compile them with g++ I get the following error:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__functional/perfect_forward.h:14:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/tuple:1546:5: error: no matching function for call to '__apply_tuple_impl'
_VSTD::__apply_tuple_impl(
^~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__config:858:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_ABI_NAMESPACE
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/tuple:1530:79: note: expanded from macro '_LIBCPP_NOEXCEPT_RETURN'
#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
^~~~~~~~~~~
/Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/forward/utils/derivative.hpp:161:19: note: in instantiation of function template specialization 'std::apply<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> (Cantera::Reactor::*const &)(Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &), const std::tuple<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &> &>' requested here
auto u = std::apply(f, at.args);
^
/Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/forward/utils/gradient.hpp:138:13: note: in instantiation of function template specialization 'autodiff::detail::eval<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> (Cantera::Reactor::*)(Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &), Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &, autodiff::detail::Real<1, double> &>' requested here
F = eval(f, at, detail::wrt(xi)); // evaluate F with xi seeded so that dF/dxi is also computed
^
/Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/forward/utils/gradient.hpp:75:21: note: in instantiation of function template specialization 'autodiff::detail::jacobian(Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> (Cantera::Reactor::*const &)(Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &), const Wrt<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &> &, const At<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &> &, Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &, Eigen::Matrix<double, -1, -1, 0> &)::(anonymous class)::operator()<int, autodiff::detail::Real<1, double> &>' requested here
f(i++, item[j]);
^
/Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/common/meta.hpp:138:9: note: in instantiation of function template specialization 'autodiff::detail::ForEachWrtVar(const Wrt<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &> &, (lambda at /Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/forward/utils/gradient.hpp:136:24) &&)::(anonymous class)::operator()<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0>>' requested here
f(std::get<i>(tuple));
^
/Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/common/meta.hpp:94:9: note: in instantiation of function template specialization 'autodiff::detail::ForEach(const std::tuple<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &> &, (lambda at /Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/forward/utils/gradient.hpp:67:23) &&)::(anonymous class)::operator()<autodiff::detail::Index<0>>' requested here
f(Index<i>{});
^
/Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/common/meta.hpp:102:5: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
AuxFor<ibegin, ibegin, iend>(std::forward<Function>(f));
^
/Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/common/meta.hpp:108:5: note: in instantiation of function template specialization 'autodiff::detail::For<0UL, 1UL, (lambda at /Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/common/meta.hpp:137:12)>' requested here
For<0, iend>(std::forward<Function>(f));
^
/Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/common/meta.hpp:137:5: note: in instantiation of function template specialization 'autodiff::detail::For<1UL, (lambda at /Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/common/meta.hpp:137:12)>' requested here
For<N>([&](auto i) constexpr {
^
/Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/forward/utils/gradient.hpp:67:5: note: in instantiation of function template specialization 'autodiff::detail::ForEach<const std::tuple<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &> &, (lambda at /Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/forward/utils/gradient.hpp:67:23)>' requested here
ForEach(wrt.args, [&](auto& item) constexpr
^
/Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/forward/utils/gradient.hpp:136:5: note: in instantiation of function template specialization 'autodiff::detail::ForEachWrtVar<(lambda at /Users/walkerant/mambaforge3/envs/ct-build/include/autodiff/forward/utils/gradient.hpp:136:24), Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &>' requested here
ForEachWrtVar(wrt, [&](auto&& i, auto&& xi) constexpr {
^
src/zeroD/Reactor.cpp:569:15: note: in instantiation of function template specialization 'autodiff::detail::jacobian<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> (Cantera::Reactor::*)(Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &), Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &, Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &, Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0>, Eigen::Matrix<double, -1, -1, 0>>' requested here
autodiff::jacobian(&Reactor::_autodiffEval, autodiff::wrt(yV), autodiff::at(yV), ydot, jac);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/tuple:1534:26: note: candidate template ignored: substitution failure [with _Fn = Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> (Cantera::Reactor::*const &)(Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &), _Tuple = const std::tuple<Eigen::Matrix<autodiff::detail::Real<1, double>, -1, 1, 0> &> &, _Id = <0>]
constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
^
3 errors generated.
scons: *** [build/src/zeroD/Reactor.os] Error 1
scons: building terminated because of errors.
I have checked out deleted functions but the code is not explicitly deleting any functions. This issue only arises with the call of autodiff::jacobian, if I comment that line out and recompile, everything runs just fine. Is there a way I can try to track down why the compiler is saying these functions are deleted? I am using this auto-differentiation package called autodiff.
The code in question is:
#include <autodiff/forward/real.hpp>
#include <autodiff/forward/real/eigen.hpp>
Eigen::SparseMatrix<double> Reactor::autodiffJacobian()
{
double y[m_nv];
getState(y);
autodiff::VectorXreal yV(Eigen::Map<Eigen::VectorXd>(y, m_nv));
Eigen::MatrixXd jac(m_nv, m_nv);
autodiff::VectorXreal ydot;
autodiff::jacobian(&Reactor::_autodiffEval, autodiff::wrt(yV), autodiff::at(yV), ydot, jac);
return jac.sparseView();
// return jac;
}
autodiff::VectorXreal Reactor::_autodiffEval(autodiff::VectorXreal& y)
{
vector_fp yT(m_nv);
for (size_t i = 0; i < m_nv; i++) {
yT[i] = y[i].val();
}
updateState(yT.data());
vector_fp lhs(m_nv, 1);
vector_fp rhs(m_nv, 0);
eval(0, lhs.data(), rhs.data());
autodiff::VectorXreal ydot(m_nv);
for (size_t i = 0; i < m_nv; i++) {
ydot[i] = rhs[i]/lhs[i];
}
return ydot;
}
The code is compiled with:
g++ -o build/src/zeroD/Reactor.os -c --std=c++17 -I/ext/eigen/Eigen -I/ext/eigen -O3 -Wno-inline -g -Wall -include src/pch/system.h -fPIC -DNDEBUG -Iinclude -I/ext -Ibuild/src -Ict-build/include src/zeroD/Reactor.cpp
Edit
The error has to something to do with it being in a class. I created a very simple example to replicate the process from an accepted example in autodiff.
// C++ includes
#include <iostream>
// autodiff include
#include <autodiff/forward/real.hpp>
#include <autodiff/forward/real/eigen.hpp>
using namespace autodiff;
VectorXreal ft(const VectorXreal& x, const VectorXreal& p, const real& q)
{
return x * p.sum() * exp(q);
}
class scratch
{
private:
/* data */
public:
scratch(/* args */);
~scratch();
VectorXreal f(const VectorXreal& x, const VectorXreal& p,
const real& q);
Eigen::MatrixXd jac();
};
VectorXreal scratch::f(const VectorXreal& x, const VectorXreal& p, const real& q)
{
return x * p.sum() * exp(q);
}
Eigen::MatrixXd scratch::jac()
{
VectorXreal x(5); // the input vector x with 5 variables
x << 1, 2, 3, 4, 5; // x = [1, 2, 3, 4, 5]
VectorXreal p(3);
p << 1, 2, 3; // p = [1, 2, 3]
real q = -2;
VectorXreal F;
Eigen::MatrixXd Jqpx = jacobian(ft, wrt(q, p, x), at(x, p, q), F);
return Jqpx;
}
int main()
{
scratch sobj;
Eigen::MatrixXd Jqpx = sobj.jac();
std::cout << "Jqpx = \n" << Jqpx << std::endl;
}
I want to use "reshape()" fuction in Eigen unsupported tensor, but my source code cannot be compiled.
The compilation was done as follows.
g++ -std=c++14 -I (path to Eigen) eigen_practice.cpp -o eigen_practice
and here is my source code.
# include "unsupported/Eigen/CXX11/Tensor"
using namespace Eigen;
int main(){
Tensor<float, 2> input(7, 11);
Eigen::array<int, 3> three_dims{{7, 11, 1}};
Tensor<float, 3> result = input.reshape(three_dims);
return 0;
}
And here is the error messeage.
In file included from eigen_practice.cpp:12:
In file included from /Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/Tensor:145:
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:397:7: error:
no matching member function for call to 'resize'
resize(TensorEvaluator<const Assign, DefaultDevice>(assign, Defaul...
^~~~~~
eigen_practice.cpp:63:28: note: in instantiation of function template
specialization 'Eigen::Tensor<float, 3, 0,
long>::Tensor<Eigen::TensorReshapingOp<const std::__1::array<int, 3>,
Eigen::Tensor<float, 2, 0, long> > >' requested here
Tensor<float, 3> result = input.reshape(three_dims);
^
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:423:10: note:
candidate function template not viable: no known conversion from 'const
Eigen::TensorEvaluator<const Eigen::TensorAssignOp<Eigen::Tensor<float, 3,
0, long>, const Eigen::TensorReshapingOp<const std::__1::array<int, 3>,
Eigen::Tensor<float, 2, 0, long> > >, Eigen::DefaultDevice>::Dimensions'
(aka 'const std::__1::array<int, 3>') to 'Eigen::Tensor<float, 3, 0,
long>::Index' (aka 'long') for 1st argument
void resize(Index firstDimension, IndexTypes... otherDimensions)
^
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:432:28: note:
candidate function not viable: no known conversion from
'array<int, [...]>' to 'const array<long, [...]>' for 1st argument
EIGEN_DEVICE_FUNC void resize(const array<Index, NumIndices>& dimensions)
^
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:450:28: note:
candidate function not viable: no known conversion from 'const
Eigen::TensorEvaluator<const Eigen::TensorAssignOp<Eigen::Tensor<float, 3,
0, long>, const Eigen::TensorReshapingOp<const std::__1::array<int, 3>,
Eigen::Tensor<float, 2, 0, long> > >, Eigen::DefaultDevice>::Dimensions'
(aka 'const std::__1::array<int, 3>') to 'const
DSizes<Eigen::Tensor<float, 3, 0, long>::Index, NumIndices>' (aka 'const
DSizes<long, NumIndices>') for 1st argument
EIGEN_DEVICE_FUNC void resize(const DSizes<Index, NumIndices>& dimensions) {
^
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:479:10: note:
candidate template ignored: could not match 'Sizes' against 'array'
void resize(const Sizes<Indices...>& dimensions) {
^
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:459:10: note:
candidate function not viable: requires 0 arguments, but 1 was provided
void resize()
^
1 error generated.
This source code is just a copy of what is in the documentation.
(https://eigen.tuxfamily.org/dox/unsupported/eigen_tensors.html)
So it should compile, but it doesn't.
How can I solve it?
And why the error message mentions about "resize()" function?
template <typename T>
bool operator()(const T* parameters, T* residuals) const
{
Eigen::Matrix<T, 3, 1> pose(parameters[0],parameters[1],parameters[2]);
Eigen::Vector3f pose1 = pose.cast<float>();
Eigen::Affine2f transform = occ->getTransformForState(pose1); // transform: rotation->translation
Eigen::Vector3f tmp1 = occ->interpMapValueWithDerivatives( transform * currPoint);
Eigen::Matrix<T, 3, 1> transformedPointData(tmp1.cast<T>()); /// {M,dM/dx,dM/dy}
T funVal = T(1) - transformedPointData[0];
residuals[0] = funVal;
return true;
}
I have a template member function like above. During compilation, it reports
error: expected primary-expression before ‘float’
Eigen::Vector3f pose1 = pose.cast<float>();
I have to cast to type "float" to make it consistent with "getTransformForState" function's input and output.
I compared with other examples provided by Eigen Library but couldnt find anything wrong.
Any ideas are highly appreciated !
-------------------- update ------------------------
By changing as pose.template cast<float>()
The error is changed as:
/usr/include/eigen3/Eigen/src/Core/MathFunctions.h: In instantiation of ‘static NewType Eigen::internal::cast_impl<OldType, NewType>::run(const OldType&) [with OldType = ceres::Jet<double, 3>; NewType = float]’:
/usr/include/eigen3/Eigen/src/Core/MathFunctions.h:328:44: required from ‘NewType Eigen::internal::cast(const OldType&) [with OldType = ceres::Jet<double, 3>; NewType = float]’
/usr/include/eigen3/Eigen/src/Core/Functors.h:351:104: required from ‘const NewType Eigen::internal::scalar_cast_op<Scalar, NewType>::operator()(const Scalar&) const [with Scalar = ceres::Jet<double, 3>; NewType = float]’
/usr/include/eigen3/Eigen/src/Core/CwiseUnaryOp.h:114:75: required from ‘const Scalar Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::coeff(Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index) const [with UnaryOp = Eigen::internal::scalar_cast_op<ceres::Jet<double, 3>, float>; XprType = const Eigen::Matrix<ceres::Jet<double, 3>, 3, 1, 0, 3, 1>; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Scalar = float; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index = long int]’
/usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:495:33: required from ‘void Eigen::DenseCoeffsBase<Derived, 1>::copyCoeff(Eigen::DenseCoeffsBase<Derived, 1>::Index, const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<ceres::Jet<double, 3>, float>, const Eigen::Matrix<ceres::Jet<double, 3>, 3, 1, 0, 3, 1> >; Derived = Eigen::Matrix<float, 3, 1>; Eigen::DenseCoeffsBase<Derived, 1>::Index = long int]’
/usr/include/eigen3/Eigen/src/Core/Assign.h:180:5: required from ‘static void Eigen::internal::assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index, Stop>::run(Derived1&, const Derived2&) [with Derived1 = Eigen::Matrix<float, 3, 1>; Derived2 = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<ceres::Jet<double, 3>, float>, const Eigen::Matrix<ceres::Jet<double, 3>, 3, 1, 0, 3, 1> >; int Index = 0; int Stop = 3]’
/usr/include/eigen3/Eigen/src/Core/Assign.h:314:21: [ skipping 5 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/eigen3/Eigen/src/Core/Matrix.h:281:31: required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const Eigen::MatrixBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<ceres::Jet<double, 3>, float>, const Eigen::Matrix<ceres::Jet<double, 3>, 3, 1, 0, 3, 1> >; _Scalar = float; int _Rows = 3; int _Cols = 1; int _Options = 0; int _MaxRows = 3; int _MaxCols = 1]’
The error message means the compiler doesn't know that pose.cast is a template. There are three basic options for what a class member .foo can be:
A value (e.g. a data member or an enum value)
A type name (e.g. something defined with typedef)
A template for one of the above.
In your case, pose is of type Eigen::Matrix<T, 3, 1>. The compiler doesn't yet know what Eigen::Matrix<T, 3, 1> looks like because it depends on what T is (someone could have specialized Eigen::Matrix differently for different types).
So when you access a member of an unknown class (as with pose.cast), the compiler assumes it's option #1 (a value). This leads to it parsing pose.cast < as the beginning of a less-than comparison. The next token (float) triggers an error because the compiler was expecting another value, not a type name.
The fix is to tell the compiler explicitly that .cast is a template:
Eigen::Vector3f pose1 = pose.template cast<float>();
(The fix for case #2 is to use the typename keyword to force interpretation as a type name.)
I'm trying to convert a Matrix3d rotation to a Quaternion<double>, but I got only weird compiler errors so far. The code I'm using is:
Quaternion<double> getQuaternionFromRotationMatrix(const Matrix3d& mat)
{
AngleAxisd aa;
aa = mat;
Quaternion<double> q = aa;// conversion error
return q;
}
And the compiler errors:
path/src/Utils.cpp: In function ‘Eigen::Quaternion<double> Utils::getQuaternionFromRotationMatrix(const Matrix3d&)’:
path/src/Utils.cpp:55:26: error: conversion from ‘Eigen::AngleAxisd {aka Eigen::AngleAxis<double>}’ to non-scalar type ‘Eigen::Quaternion<double>’ requested
In file included from /usr/local/include/eigen3/Eigen/Core:283:0,
from /usr/local/include/eigen3/Eigen/Dense:1,
from path/include/Utils.h:4,
from path/src/Utils.cpp:1:
/usr/local/include/eigen3/Eigen/src/Core/Assign.h: In member function ‘Derived& Eigen::DenseBase<Derived>::lazyAssign(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::Matrix<double, 3, 1>, Derived = Eigen::Block<Eigen::Matrix<double, 4, 4>, 4, -0x00000000000000001, true, true>]’:
/usr/local/include/eigen3/Eigen/src/Core/Assign.h:534:123: instantiated from ‘static Derived& Eigen::internal::assign_selector<Derived, OtherDerived, false, false>::run(Derived&, const OtherDerived&) [with Derived = Eigen::Block<Eigen::Matrix<double, 4, 4>, 4, -0x00000000000000001, true, true>, OtherDerived = Eigen::Matrix<double, 3, 1>]’
/usr/local/include/eigen3/Eigen/src/Core/Assign.h:574:89: instantiated from ‘Derived& Eigen::MatrixBase<Derived>::operator=(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::Matrix<double, 3, 1>, Derived = Eigen::Block<Eigen::Matrix<double, 4, 4>, 4, -0x00000000000000001, true, true>]’
path/src/Utils.cpp:34:20: instantiated from here
/usr/local/include/eigen3/Eigen/src/Core/Assign.h:504:3: error: static assertion failed: "YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES"
Does someone know how to convert between both representations?
The constructors from an AngleAxis or Matrix are explicit meaning you have to write the conversion as follow:
Matrix3f mat;
Quaternionf q(mat);
or
Quaternionf q;
q = mat;
Same for AngleAxis.
Sometime ago user ggael gave an answer to the
problem of mapping a eigen::vectorXf to an eigen::matrixXf.
Now, i need to do something similar, but to an existing matrix,
e.g i know i can:
for(int i=0;i<p;++i){
VectorXf vec=q.col(i);
/*q is a p**2 by n matrix*/
Map<MatrixXf> qi(vec.data(),p,p);
/*run function that uses qi to produce a scalare and store that scalar*/
}
but (it seems to me) it would be more efficient to
create qi once and for all outside the loop and then
use the same qi over and over again (is that right?)
Also, i wonder whether the intermediate step where
i map q.col(i) to vec is really necessary...
A recent answer proposes to do:
qi=Map<MatrixXd>(vec.data(),p,p);
but doing that yields:
In function ‘Eigen::VectorXi DepType(const MatrixXf&, const MatrixXf&, const int&)’:
DeC.cpp:279:34: error: no matching function for call to ‘Eigen::Map<Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001> >::Map(Eigen::PlainObjectBase<Eigen::Matrix<float, -0x00000000000000001, 1> >::Scalar*, int&, int&)’
DeC.cpp:279:34: note: candidates are:
/eigen/Eigen/src/Core/Map.h:179:12: note: Eigen::Map<MatrixType, MapOptions, StrideType>::Map(Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType, Eigen::Map<MatrixType, MapOptions, StrideType>::Index, Eigen::Map<MatrixType, MapOptions, StrideType>::Index, const StrideType&) [with PlainObjectType = Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0, StrideType = Eigen::Stride<0, 0>, Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType = double*, Eigen::Map<MatrixType, MapOptions, StrideType>::Index = long int]
/home/kaveh/Desktop/work/p1/geqw4/vi3/out/sp/ccode/eigen/Eigen/src/Core/Map.h:179:12: note: no known conversion for argument 1 from ‘Eigen::PlainObjectBase<Eigen::Matrix<float, -0x00000000000000001, 1> >::Scalar* {aka float*}’ to ‘double*’
/eigen/Eigen/src/Core/Map.h:166:12: note: Eigen::Map<MatrixType, MapOptions, StrideType>::Map(Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType, Eigen::Map<MatrixType, MapOptions, StrideType>::Index, const StrideType&) [with PlainObjectType = Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0, StrideType = Eigen::Stride<0, 0>, Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType = double*, Eigen::Map<MatrixType, MapOptions, StrideType>::Index = long int]
/eigen/Eigen/src/Core/Map.h:166:12: note: no known conversion for argument 1 from ‘Eigen::PlainObjectBase<Eigen::Matrix<float, -0x00000000000000001, 1> >::Scalar* {aka float*}’ to ‘double*’
/eigen/Eigen/src/Core/Map.h:154:12: note: Eigen::Map<MatrixType, MapOptions, StrideType>::Map(Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType, const StrideType&) [with PlainObjectType = Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0, StrideType = Eigen::Stride<0, 0>, Eigen::Map<MatrixType, MapOptions, StrideType>::PointerArgType = double*]
/eigen/Eigen/src/Core/Map.h:154:12: note: candidate expects 2 arguments, 3 provided
/eigen/Eigen/src/Core/Map.h:119:79: note: Eigen::Map<Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001> >::Map(const Eigen::Map<Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001> >&)
/eigen/Eigen/src/Core/Map.h:119:79: note: candidate expects 1 argument, 3 provided
e.g. it seems Eigen thinks qi is a vector....:(
The following:
qi=Map<MatrixXd>(vec.data(),p,p);
means that you want to copy the coefficients of Map(vec.data(),p,p) into the matrix referenced by qi. However, what you actually want is to re-initialize the Map<> object. To do so you must call the constructor again using the construct new syntax of C++:
new (&qi) Map<MatrixXd>(vec.data(),p,p);
Moreover, I must say that a Map<> object is extremely lightweight: it is only one pointer and 2 integers that are statically allocated on the stack. So moving the declaration of Map<> qi outside the loop will have zero effect on the performance. On the other hand, note that you do not need to copy q.col(i) into a temporary buffer. If q is column major, you can directly do:
Map<MatrixXf> qi(q.col(i).data(),p,p);