Я пытаюсь использовать Boost.Units с Eigen 3.3.1, но после выполнения инструкций here и некоторых информационных данных found around, я до сих пор не могу понять, как сделать норму() Работа.Eigen norm() с Boost.Units
Вот то, что я до сих пор (извините за длинный код блока):
#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) с ошибкой, как
не мог преобразовать "повышение :: единиц :: SQRT ... (некоторая расшифровка ошибок шаблона)"
и
не удалось преобразовать "Эйген :: внутренний :: abs2_impl ... (какой-то неясной ошибки шаблон)"
Это потребовало бы несколько нетривиальных реорганизаций внутри Эйгеном. Прежде всего, 'Eigen :: numext :: sqrt' в настоящее время всегда возвращает тот же тип, что и в качестве аргумента (я думаю, это одна из самых простых вещей для исправления). – chtz