使用 CwiseUnaryOp 作为左值
Using a CwiseUnaryOp as an lvalue
我正在使用 Eigen 的 EIGEN_MATRIXBASE_PLUGIN 功能来实现 CwiseUnary 表达式,但我在使用 operator=
扩展这项工作时遇到了问题
我正在使用一个包含两个成员的结构:.val_ 和 .d_,并且我添加了一个 CwiseUnaryOp 来访问它们:
template<typename T>
struct d_Op {
EIGEN_EMPTY_STRUCT_CTOR(d_Op)
typedef T result_type;
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const result_type&
operator()(const stan::math::fvar<T> &v) const { return v.d_; }
};
template<typename T>
struct val_Op {
EIGEN_EMPTY_STRUCT_CTOR(val_Op)
typedef T result_type;
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const result_type&
operator()(const stan::math::fvar<T> &v) const { return v.val_; }
};
inline const CwiseUnaryOp<d_Op<typename stan::partials_type<Scalar>::type>, const Derived>
d_() const { return CwiseUnaryOp<d_Op<typename stan::partials_type<Scalar>::type>,
const Derived>
(derived(), d_Op<typename stan::partials_type<Scalar>::type>());
}
inline const CwiseUnaryOp<val_Op<typename stan::partials_type<Scalar>::type>, const Derived>
val_() const { return CwiseUnaryOp<val_Op<typename stan::partials_type<Scalar>::type>,
const Derived>
(derived(), val_Op<typename stan::partials_type<Scalar>::type>());
}
这样,给定一个 Matrix<stan::math::fvar<double>,-1,-1> m
类型的矩阵,我可以简单地写成:m.val_()
.
一切正常,但我想扩展它以写入这些值,而不是仅仅读取它们(即 m.val_() = MatrixXD::Random(int,int)
)。但是我不知道如何重载 =
运算符,给我这样的错误:
test.cpp:30:14: error: no match for ‘operator=’ (operand types are ‘const
Eigen::CwiseUnaryOp<Eigen::MatrixBase<Eigen::Matrix<stan::math::fvar<double>,
-1, -1> >::val_Op<double>, const Eigen::Matrix<stan::math::fvar<double>, -1, -1> >’
and ‘Eigen::MatrixXd’ {aka ‘Eigen::Matrix<double, -1, -1>’})
我是不是漏掉了一些很明显的东西?
编辑:改用 CwiseUnaryView 时的输出:
test.cpp:30:14: error: no match for ‘operator=’
(operand types are ‘const Eigen::CwiseUnaryView<Eigen::MatrixBase<Eigen::Matrix<stan::math::fvar<double>, -1, -1> >::val_Op<double>, const Eigen::Matrix<stan::math::fvar<double>, -1, -1> >’
and ‘Eigen::MatrixXd’ {aka ‘Eigen::Matrix<double, -1, -1>’})
a.val_() = inp;
这是一个最小的工作示例,其中包含一个虚拟 fvar
实现,并在任何 class:
之外定义了 CwiseUnaryView
#include <Eigen/Core>
template<class X>
struct fvar
{
X d_, val_;
};
template<typename T>
struct d_Op {
EIGEN_EMPTY_STRUCT_CTOR(d_Op)
typedef T result_type;
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const result_type&
operator()(const fvar<T> &v) const { return v.d_; }
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE result_type&
operator()(fvar<T> &v) const { return v.d_; }
};
void foo(Eigen::Matrix<fvar<float>, 4,4> &out, Eigen::Matrix4f const &in)
{
Eigen::CwiseUnaryView<d_Op<float>, Eigen::Matrix<fvar<float>, 4,4> > view(out);
view = in;
}
启用优化后,这将编译为一个简单的循环:
https://godbolt.org/z/mgktfv
我正在使用 Eigen 的 EIGEN_MATRIXBASE_PLUGIN 功能来实现 CwiseUnary 表达式,但我在使用 operator=
扩展这项工作时遇到了问题我正在使用一个包含两个成员的结构:.val_ 和 .d_,并且我添加了一个 CwiseUnaryOp 来访问它们:
template<typename T>
struct d_Op {
EIGEN_EMPTY_STRUCT_CTOR(d_Op)
typedef T result_type;
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const result_type&
operator()(const stan::math::fvar<T> &v) const { return v.d_; }
};
template<typename T>
struct val_Op {
EIGEN_EMPTY_STRUCT_CTOR(val_Op)
typedef T result_type;
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const result_type&
operator()(const stan::math::fvar<T> &v) const { return v.val_; }
};
inline const CwiseUnaryOp<d_Op<typename stan::partials_type<Scalar>::type>, const Derived>
d_() const { return CwiseUnaryOp<d_Op<typename stan::partials_type<Scalar>::type>,
const Derived>
(derived(), d_Op<typename stan::partials_type<Scalar>::type>());
}
inline const CwiseUnaryOp<val_Op<typename stan::partials_type<Scalar>::type>, const Derived>
val_() const { return CwiseUnaryOp<val_Op<typename stan::partials_type<Scalar>::type>,
const Derived>
(derived(), val_Op<typename stan::partials_type<Scalar>::type>());
}
这样,给定一个 Matrix<stan::math::fvar<double>,-1,-1> m
类型的矩阵,我可以简单地写成:m.val_()
.
一切正常,但我想扩展它以写入这些值,而不是仅仅读取它们(即 m.val_() = MatrixXD::Random(int,int)
)。但是我不知道如何重载 =
运算符,给我这样的错误:
test.cpp:30:14: error: no match for ‘operator=’ (operand types are ‘const
Eigen::CwiseUnaryOp<Eigen::MatrixBase<Eigen::Matrix<stan::math::fvar<double>,
-1, -1> >::val_Op<double>, const Eigen::Matrix<stan::math::fvar<double>, -1, -1> >’
and ‘Eigen::MatrixXd’ {aka ‘Eigen::Matrix<double, -1, -1>’})
我是不是漏掉了一些很明显的东西?
编辑:改用 CwiseUnaryView 时的输出:
test.cpp:30:14: error: no match for ‘operator=’
(operand types are ‘const Eigen::CwiseUnaryView<Eigen::MatrixBase<Eigen::Matrix<stan::math::fvar<double>, -1, -1> >::val_Op<double>, const Eigen::Matrix<stan::math::fvar<double>, -1, -1> >’
and ‘Eigen::MatrixXd’ {aka ‘Eigen::Matrix<double, -1, -1>’})
a.val_() = inp;
这是一个最小的工作示例,其中包含一个虚拟 fvar
实现,并在任何 class:
CwiseUnaryView
#include <Eigen/Core>
template<class X>
struct fvar
{
X d_, val_;
};
template<typename T>
struct d_Op {
EIGEN_EMPTY_STRUCT_CTOR(d_Op)
typedef T result_type;
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const result_type&
operator()(const fvar<T> &v) const { return v.d_; }
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE result_type&
operator()(fvar<T> &v) const { return v.d_; }
};
void foo(Eigen::Matrix<fvar<float>, 4,4> &out, Eigen::Matrix4f const &in)
{
Eigen::CwiseUnaryView<d_Op<float>, Eigen::Matrix<fvar<float>, 4,4> > view(out);
view = in;
}
启用优化后,这将编译为一个简单的循环: https://godbolt.org/z/mgktfv