gpt4 book ai didi

c++ - 使用 Boost.Units 的 Eigen 范数()

转载 作者:行者123 更新时间:2023-11-30 05:18:41 28 4
gpt4 key购买 nike

我正在尝试将 Boost.Units 与 Eigen 3.3.1 一起使用,但在遵循说明后 here , 和一些信息 found around ,我仍然不知道如何使 norm() 工作。

这是我到目前为止的内容(抱歉代码块太长):

#include <boost/units/quantity.hpp>
#include <boost/units/systems/si/length.hpp>
#include <boost/units/systems/si/area.hpp>
#include <boost/units/cmath.hpp>
#include <Eigen/Geometry>

namespace Eigen {

//specialization of numeric traits
using boost::units::quantity;
template <typename Unit, typename Scalar>
struct NumTraits<quantity<Unit, Scalar>>
: GenericNumTraits<quantity<Unit, Scalar>>
{
typedef quantity<Unit, Scalar> Real;
typedef quantity<Unit, Scalar> NonInteger;
typedef quantity<Unit, Scalar> Nested;
typedef quantity<Unit, Scalar> Literal;

static inline Real epsilon() { return quantity<Unit, Scalar>(0); }
static inline Real dummy_precision() { return quantity<Unit, Scalar>(1e-6 * Unit()); }
static inline Real digits10() { return quantity<Unit, Scalar>(0); }

enum {
IsComplex = 0,
IsInteger = 0,
IsSigned = 1,
RequireInitialization = 1,
ReadCost = 1,
AddCost = 3,
MulCost = 3
};
};

//specialization of sum operator
template <typename Unit, typename Scalar>
struct ScalarBinaryOpTraits<quantity<Unit, Scalar>, quantity<Unit, Scalar>, internal::scalar_sum_op<quantity<Unit, Scalar>, quantity<Unit, Scalar>>> {
typedef typename boost::units::add_typeof_helper<quantity<Unit, Scalar>, quantity<Unit, Scalar>>::type ReturnType;
};

//specialization of product operator
template <typename Unit, typename Scalar>
struct ScalarBinaryOpTraits<Scalar, quantity<Unit, Scalar>,internal::scalar_product_op<Scalar, quantity<Unit, Scalar>>> {
typedef Scalar X;
typedef quantity<Unit, Scalar> Y;
typedef typename boost::units::multiply_typeof_helper<X, Y>::type ReturnType;
};
template <typename Unit, typename Scalar>
struct ScalarBinaryOpTraits<quantity<Unit, Scalar>, Scalar, internal::scalar_product_op<quantity<Unit, Scalar>, Scalar>> {
typedef quantity<Unit, Scalar> X;
typedef Scalar Y;
typedef typename boost::units::multiply_typeof_helper<X, Y>::type ReturnType;
};
template <typename Unit, typename Scalar>
struct ScalarBinaryOpTraits<quantity<Unit, Scalar>, quantity<Unit, Scalar>, internal::scalar_product_op<quantity<Unit, Scalar>, quantity<Unit, Scalar>>> {
typedef quantity<Unit, Scalar> X;
typedef quantity<Unit, Scalar> Y;
typedef typename boost::units::multiply_typeof_helper<X, Y>::type ReturnType;
};

namespace internal {

//specialization for abs2()
template<typename Unit, typename Scalar>
struct abs2_impl<quantity<Unit, Scalar>>
{
typedef quantity<Unit, Scalar> X;
typedef quantity<Unit, Scalar> Y;
typedef typename boost::units::multiply_typeof_helper<X, Y>::type ReturnType;

EIGEN_DEVICE_FUNC
static inline ReturnType run(const quantity<Unit, Scalar>& x)
{
return x * x;
}
};


} // namespace internal

} // namespace Eigen

namespace boost {

namespace units {

//required functions
using namespace boost::units::si;
inline quantity<area, double> abs2(const quantity<length, double>& x) { return x * x; }

} // namespace units

} // namespace boost

int main(int /*argc*/, char** /*argv[]*/)
{
//unit typedefs
using namespace boost::units;
using namespace boost::units::si;
using Length = quantity<length, double>;
using Area = quantity<area, double>;

//eigen typedefs
using LengthVector = Eigen::Matrix<Length, 3, 1>;
using AreaVector = Eigen::Matrix<Area, 3, 1>;
using LengthMatrix = Eigen::Matrix<Length, 3, 3>;

//test norm
LengthVector vector1;
Length result4 = vector1.norm();
}

但这无法编译(gcc 5.4.0)并出现类似错误

could not convert "boost::units::sqrt... (some undecipherable template error)"

could not convert "Eigen::internal::abs2_impl... (some obscure template error)"

最佳答案

template<typename Derived>
EIGEN_STRONG_INLINE
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
MatrixBase<Derived>::squaredNorm() const
{
return numext::real((*this).cwiseAbs2().sum());
}

template<typename Derived>
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
MatrixBase<Derived>::norm() const
{
return numext::sqrt(squaredNorm());
}

如上所示,Eigen3 norm() 函数使用了 squaredNorm()。但是,squaredNorm() 的声明要求返回类型必须与矩阵元素类型Derived 相同,这意味着返回值单位应与矩阵元素单位相同.比如一个米单位的位移 vector ,它的squaredNorm应该返回一个以meter_squared为单位的值,这与声明冲突。所以在不改变 Eigen 的实现的情况下,可能无法直接使用 squaredNorm()norm()

我的想法是在 Eigen 之外编写一个效用函数来实现 squaredNorm()norm()normalized() :

template<typename T, int Row, int Col>
EIGEN_STRONG_INLINE
static T norm(const Eigen::Matrix<T, Row, Col>& m)
{
return Eigen::numext::sqrt(squared_norm(m));
}

https://github.com/iastate-robotics/eigen3-units

关于c++ - 使用 Boost.Units 的 Eigen 范数(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41527392/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com