C++ 用运算符()扩展Eigen::EigenBase
我想对偏移量为(0.5,0)和(0,0.5)的网格使用MatrixXd类。在数学公式中,速度是在单元格i,i+1之间计算的,它被写成vel(i+0.5,j)。我想介绍如下语法:C++ 用运算符()扩展Eigen::EigenBase,c++,eigen,eigen3,C++,Eigen,Eigen3,我想对偏移量为(0.5,0)和(0,0.5)的网格使用MatrixXd类。在数学公式中,速度是在单元格i,i+1之间计算的,它被写成vel(i+0.5,j)。我想介绍如下语法: #include <Eigen/Dense> int main() { Eigen::MatrixXd m = Eigen::MatrixXd::Zero(5,5); // Want to use similar syntax: // m(0, 1.5) = 1.0; // and //
#include <Eigen/Dense>
int main() {
Eigen::MatrixXd m = Eigen::MatrixXd::Zero(5,5);
// Want to use similar syntax:
// m(0, 1.5) = 1.0;
// and
// m(3.5, 1) = 2.0;
// Instead of:
m(0, 2) = 1.0;
m(4, 1) = 2.0;
}
inline Scalar& operator()(int r, int c) {
return Base::operator()(r, c);
}
inline Scalar& operator()(double r, int c) {
return Base::operator()(int(r + 0.5), c);
}
inline Scalar& operator()(int r, double c) {
return Base::operator()(r, int(c + 0.5));
}
然而,这种方法:
==6035== Invalid free() / delete / delete[] / realloc()
==6035== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6035== by 0x4E4224A: aligned_free (Memory.h:177)
==6035== by 0x4E4224A: conditional_aligned_free<true> (Memory.h:230)
==6035== by 0x4E4224A: conditional_aligned_delete_auto<double, true> (Memory.h:416)
==6035== by 0x4E4224A: resize (DenseStorage.h:406)
==6035== by 0x4E4224A: resize (PlainObjectBase.h:293)
==6035== by 0x4E4224A: resize_if_allowed<Eigen::Matrix<double, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> >, double, double> (AssignEvaluator.h:720)
==6035== by 0x4E4224A: call_dense_assignment_loop<Eigen::Matrix<double, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> >, Eigen::internal::assign_op<double, double> > (AssignEvaluator.h:734)
==6035== by 0x4E4224A: run (AssignEvaluator.h:879)
==6035== by 0x4E4224A: call_assignment_no_alias<Eigen::Matrix<double, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> >, Eigen::internal::assign_op<double, double> > (AssignEvaluator.h:836)
==6035== by 0x4E4224A: call_assignment<Eigen::Matrix<double, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> >, Eigen::internal::assign_op<double, double> > (AssignEvaluator.h:804)
==6035== by 0x4E4224A: call_assignment<Eigen::Matrix<double, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> > > (AssignEvaluator.h:782)
==6035== by 0x4E4224A: _set<Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> > > (PlainObjectBase.h:710)
==6035== by 0x4E4224A: operator=<Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> > > (Matrix.h:225)
==6035== by 0x11044C: main (Runner.cpp:16)
==6035== Address 0x2e642f73726573 is not stack'd, malloc'd or (recently) free'd
==6035==Invalid free()/delete/delete[]/realloc()
==6035==at 0x4C30D3B:空闲(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
==6035==by 0x4E4224A:已对齐\u空闲(Memory.h:177)
==6035==by 0x4E4224A:条件对齐的空闲(Memory.h:230)
==6035==by 0x4E424A:条件对齐删除自动(Memory.h:416)
==6035==by 0x4E424A:调整大小(DenseStorage.h:406)
==6035==by 0x4E424A:调整大小(PlainObjectBase.h:293)
==6035==按0x4E424A:如果允许,请调整大小(AssignEvaluator.h:720)
==6035==by 0x4E424A:call\u density\u assignment\u循环(AssignEvaluator.h:734)
==6035==by 0x4E424A:run(AssignEvaluator.h:879)
==6035==by 0x4E424A:调用\u分配\u否\u别名(AssignEvaluator.h:836)
==6035==by 0x4E424A:call_赋值(AssignEvaluator.h:804)
==6035==by 0x4E424A:call_赋值(AssignEvaluator.h:782)
==6035==by 0x4E424A:_集(PlainObjectBase.h:710)
==6035==由0x4E424A:运算符=(矩阵h:225)
==6035==0x11044C:main(Runner.cpp:16)
==6035==地址0x2e642f73726573不是堆栈、malloc或(最近)空闲
如果偏移量不是作为类成员引入的,而是操作符()中的局部变量,则valgrind不会检测到任何错误
是否可以使用可设置的偏移量实现新的MatrixXd::operator()(双精度,双精度)
编辑:
运算符()在父类中定义:
本征设备功能
特征强内联CoeffReturnType运算符()(索引行,索引列)常量
{
本征断言(行>=0&&row=0&&col
也许,我发现运算符返回对标量临时对象的引用时存在一个问题:
inline Scalar& operator()(double r, double c) {
// double r_offset = -0.5, c_offset = -0.5;
return Base::operator()(int(r - r_offset), int(c - c_offset));
}
所以您应该按副本返回标量
你能分享Base::operator()(int(r-r_偏移量),int(c-c_偏移量))的代码吗 也许,我看到您的运算符返回对标量临时对象的引用时出现了一个问题:
inline Scalar& operator()(double r, double c) {
// double r_offset = -0.5, c_offset = -0.5;
return Base::operator()(int(r - r_offset), int(c - c_offset));
}
所以您应该按副本返回标量
你能分享Base::operator()(int(r-r_偏移量),int(c-c_偏移量))的代码吗 在原来的帖子中添加了答案。不确定返回副本是否是最佳解决方案。最初,我只是从中复制了一个at()方法。它返回了引用,所以我也尝试了它。编辑:不,不行。我需要这个代码的参考:
vel(0.5,0.5)=1.0代码>。没有引用,错误“=”:左操作数必须是l值,弹出窗口。@Kirikus关于您的错误,请发布一个,因为没有它我无法帮助您!在原来的帖子中添加了答案。不确定返回副本是否是最佳解决方案。最初,我只是从中复制了一个at()方法。它返回了引用,所以我也尝试了它。编辑:不,不行。我需要这个代码的参考:vel(0.5,0.5)=1.0代码>。没有引用,错误“=”:左操作数必须是l值,弹出窗口。@Kirikus关于您的错误,请发布一个,因为没有它我无法帮助您!首先,我认为用(double,double)
重载操作符()
是个坏主意。如果您真的需要,我建议将MatrixXd
对象包装在自定义类中。关于你的错误,请发一个帖子!首先,我认为用(double,double)
重载操作符()
是个坏主意。如果您真的需要,我建议将MatrixXd
对象包装在自定义类中。关于你的错误,请发一个帖子!
==6035== Invalid free() / delete / delete[] / realloc()
==6035== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6035== by 0x4E4224A: aligned_free (Memory.h:177)
==6035== by 0x4E4224A: conditional_aligned_free<true> (Memory.h:230)
==6035== by 0x4E4224A: conditional_aligned_delete_auto<double, true> (Memory.h:416)
==6035== by 0x4E4224A: resize (DenseStorage.h:406)
==6035== by 0x4E4224A: resize (PlainObjectBase.h:293)
==6035== by 0x4E4224A: resize_if_allowed<Eigen::Matrix<double, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> >, double, double> (AssignEvaluator.h:720)
==6035== by 0x4E4224A: call_dense_assignment_loop<Eigen::Matrix<double, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> >, Eigen::internal::assign_op<double, double> > (AssignEvaluator.h:734)
==6035== by 0x4E4224A: run (AssignEvaluator.h:879)
==6035== by 0x4E4224A: call_assignment_no_alias<Eigen::Matrix<double, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> >, Eigen::internal::assign_op<double, double> > (AssignEvaluator.h:836)
==6035== by 0x4E4224A: call_assignment<Eigen::Matrix<double, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> >, Eigen::internal::assign_op<double, double> > (AssignEvaluator.h:804)
==6035== by 0x4E4224A: call_assignment<Eigen::Matrix<double, -1, -1>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> > > (AssignEvaluator.h:782)
==6035== by 0x4E4224A: _set<Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> > > (PlainObjectBase.h:710)
==6035== by 0x4E4224A: operator=<Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, -1> > > (Matrix.h:225)
==6035== by 0x11044C: main (Runner.cpp:16)
==6035== Address 0x2e642f73726573 is not stack'd, malloc'd or (recently) free'd
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
{
eigen_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return coeff(row, col);
}
inline Scalar& operator()(double r, double c) {
// double r_offset = -0.5, c_offset = -0.5;
return Base::operator()(int(r - r_offset), int(c - c_offset));
}