QVM - 用户定义的四元数和标量
QVM - user-defined quaternion and scalar
我正在尝试将 boost::qvm
与 boost::multiprecision
结合使用。我构建了一个用户定义的四元数,但无法缩放四元数。我想按 boost::multiprecision::cpp_dec_float_100
的数量来缩放它。贝娄是我的代码。我也用注释掉的代码试了一下。
#include <bits/stdc++.h>
#include <boost/numeric/odeint.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/qvm.hpp>
using namespace std;
typedef boost::multiprecision::cpp_dec_float_100 fl;
struct fquat { fl a[4]; };
namespace boost { namespace qvm {
template <>
struct quat_traits<fquat>: quat_traits_defaults<fquat,fl> {
template <int I>
static inline scalar_type & write_element( fquat & q ) {
return q.a[I];
}
};
template <> struct is_scalar<fl> { static bool const value=true; };
template <> struct scalar_traits<fl>
{ BOOST_QVM_INLINE_CRITICAL static fl value( int v ) { return fl(v); }};
/*
template <>
struct deduce_quat<fquat, fl> {
typedef fquat type;
};
template <>
struct deduce_quat2<fquat, fquat, fl> {
typedef fquat type;
};
*/
} }
int main()
{
fquat q = {fl(1),fl(1),fl(1),fl(1)};
fl x = fl(3);
q *= x;
return 0;
}
我得到的错误是:
test2.cpp: In function ‘int main()’:
test2.cpp:48:7: error: no match for ‘operator*=’ (operand types are ‘fquat’ and ‘fl’ {aka ‘boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100> >’})
48 | q *= x;
| ~~^~~~
我意识到可以简单地重载运算符,但这是 by boost 预期的解决方案吗?
代码:
fquat operator* (fquat const &q, fl y)
{
return fquat {boost::qvm::S(q)*y , boost::qvm::X(q)*y , boost::qvm::Y(q)*y , boost::qvm::Z(q)*y} ;
}
ADL 找不到 QVM 定义的运算符,您需要帮助编译器:
using boost::qvm::operator*=;
q *= x;
您可以使 ADL 工作,可能有多种方式。
一种方法是使 boost::qvm
成为您的类型的关联命名空间。另一个是 using
您自己的命名空间中的适当运算符。
在您自己的命名空间中显式使用
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/numeric/odeint.hpp>
#include <boost/qvm.hpp>
namespace MyLib {
using fl = boost::multiprecision::cpp_dec_float_100;
struct fquat {
fl a[4];
};
using boost::qvm::operator*=;
} // namespace MyLib
namespace boost::qvm {
template <>
struct quat_traits<MyLib::fquat>
: quat_traits_defaults<MyLib::fquat, MyLib::fl> {
template <int I>
static inline scalar_type& write_element(MyLib::fquat& q)
{
return q.a[I];
}
};
template <> struct is_scalar<MyLib::fl> {
static bool const value = true;
};
template <> struct scalar_traits<MyLib::fl> {
BOOST_QVM_INLINE_CRITICAL static MyLib::fl value(int v)
{
return MyLib::fl(v);
}
};
template <> struct deduce_quat<MyLib::fquat, MyLib::fl> {
using type = MyLib::fquat;
};
template <> struct deduce_quat2<MyLib::fquat, MyLib::fquat, MyLib::fl> {
using type = MyLib::fquat;
};
} // namespace boost::qvm
using MyLib::fl;
using MyLib::fquat;
int main()
{
fquat q = {fl(1), fl(1), fl(1), fl(1)};
fl x = fl(3);
q *= x;
}
破解 ADL
或者,使用 ADL-hook,例如
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/numeric/odeint.hpp>
#include <boost/qvm.hpp>
namespace boost::qvm {
struct my_ADL_hook {
};
} // namespace boost::qvm
using fl = boost::multiprecision::cpp_dec_float_100;
template <typename = boost::qvm::my_ADL_hook> struct fquat_t {
fl a[4];
};
using fquat = fquat_t<>;
namespace boost::qvm {
template <> struct quat_traits<fquat> : quat_traits_defaults<fquat, fl> {
template <int I> static inline scalar_type& write_element(fquat& q)
{
return q.a[I];
}
};
template <> struct is_scalar<fl> {
static bool const value = true;
};
template <> struct scalar_traits<fl> {
BOOST_QVM_INLINE_CRITICAL static fl value(int v) { return fl(v); }
};
//template <> struct deduce_quat<fquat, fl> { using type = fquat; } ;
//template <> struct deduce_quat2<fquat, fquat, fl> { using type = fquat; } ;
} // namespace boost::qvm
int main()
{
fquat q = {1, 1, 1, 1};
fl x = 3;
q *= x;
}
我正在尝试将 boost::qvm
与 boost::multiprecision
结合使用。我构建了一个用户定义的四元数,但无法缩放四元数。我想按 boost::multiprecision::cpp_dec_float_100
的数量来缩放它。贝娄是我的代码。我也用注释掉的代码试了一下。
#include <bits/stdc++.h>
#include <boost/numeric/odeint.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/qvm.hpp>
using namespace std;
typedef boost::multiprecision::cpp_dec_float_100 fl;
struct fquat { fl a[4]; };
namespace boost { namespace qvm {
template <>
struct quat_traits<fquat>: quat_traits_defaults<fquat,fl> {
template <int I>
static inline scalar_type & write_element( fquat & q ) {
return q.a[I];
}
};
template <> struct is_scalar<fl> { static bool const value=true; };
template <> struct scalar_traits<fl>
{ BOOST_QVM_INLINE_CRITICAL static fl value( int v ) { return fl(v); }};
/*
template <>
struct deduce_quat<fquat, fl> {
typedef fquat type;
};
template <>
struct deduce_quat2<fquat, fquat, fl> {
typedef fquat type;
};
*/
} }
int main()
{
fquat q = {fl(1),fl(1),fl(1),fl(1)};
fl x = fl(3);
q *= x;
return 0;
}
我得到的错误是:
test2.cpp: In function ‘int main()’:
test2.cpp:48:7: error: no match for ‘operator*=’ (operand types are ‘fquat’ and ‘fl’ {aka ‘boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<100> >’})
48 | q *= x;
| ~~^~~~
我意识到可以简单地重载运算符,但这是 by boost 预期的解决方案吗? 代码:
fquat operator* (fquat const &q, fl y)
{
return fquat {boost::qvm::S(q)*y , boost::qvm::X(q)*y , boost::qvm::Y(q)*y , boost::qvm::Z(q)*y} ;
}
ADL 找不到 QVM 定义的运算符,您需要帮助编译器:
using boost::qvm::operator*=;
q *= x;
您可以使 ADL 工作,可能有多种方式。
一种方法是使 boost::qvm
成为您的类型的关联命名空间。另一个是 using
您自己的命名空间中的适当运算符。
在您自己的命名空间中显式使用
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/numeric/odeint.hpp>
#include <boost/qvm.hpp>
namespace MyLib {
using fl = boost::multiprecision::cpp_dec_float_100;
struct fquat {
fl a[4];
};
using boost::qvm::operator*=;
} // namespace MyLib
namespace boost::qvm {
template <>
struct quat_traits<MyLib::fquat>
: quat_traits_defaults<MyLib::fquat, MyLib::fl> {
template <int I>
static inline scalar_type& write_element(MyLib::fquat& q)
{
return q.a[I];
}
};
template <> struct is_scalar<MyLib::fl> {
static bool const value = true;
};
template <> struct scalar_traits<MyLib::fl> {
BOOST_QVM_INLINE_CRITICAL static MyLib::fl value(int v)
{
return MyLib::fl(v);
}
};
template <> struct deduce_quat<MyLib::fquat, MyLib::fl> {
using type = MyLib::fquat;
};
template <> struct deduce_quat2<MyLib::fquat, MyLib::fquat, MyLib::fl> {
using type = MyLib::fquat;
};
} // namespace boost::qvm
using MyLib::fl;
using MyLib::fquat;
int main()
{
fquat q = {fl(1), fl(1), fl(1), fl(1)};
fl x = fl(3);
q *= x;
}
破解 ADL
或者,使用 ADL-hook,例如
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/numeric/odeint.hpp>
#include <boost/qvm.hpp>
namespace boost::qvm {
struct my_ADL_hook {
};
} // namespace boost::qvm
using fl = boost::multiprecision::cpp_dec_float_100;
template <typename = boost::qvm::my_ADL_hook> struct fquat_t {
fl a[4];
};
using fquat = fquat_t<>;
namespace boost::qvm {
template <> struct quat_traits<fquat> : quat_traits_defaults<fquat, fl> {
template <int I> static inline scalar_type& write_element(fquat& q)
{
return q.a[I];
}
};
template <> struct is_scalar<fl> {
static bool const value = true;
};
template <> struct scalar_traits<fl> {
BOOST_QVM_INLINE_CRITICAL static fl value(int v) { return fl(v); }
};
//template <> struct deduce_quat<fquat, fl> { using type = fquat; } ;
//template <> struct deduce_quat2<fquat, fquat, fl> { using type = fquat; } ;
} // namespace boost::qvm
int main()
{
fquat q = {1, 1, 1, 1};
fl x = 3;
q *= x;
}