在 Cython 中设置 coefficient/element of Eigen::Matrix3d
Set coefficient/element of Eigen::Matrix3d in Cython
我正在尝试在 Cython 中为使用 Eigen::Matrix3d 矩阵的库创建一个包装器。如何设置 Matrix3d 对象的单个 element/coefficient?
我知道,我可以使用 coeff(row, col)
方法获取值,但找不到任何函数 set_coeff(row, col, value)
- 或者可能被调用 - 来设置值。
在使用
声明 Matrix3d 之后
cdef decl_eigen.Matrix3d t = decl_eigen.Matrix3d()
我想设置值,但是 none 以下构造在 Cython 中有效:
t << 1,2,3,4,5,6,7,8,9
t(0,0) = 1
t[0][0] = 1
而且我不能使用带有值的构造函数,因为据我所知不存在任何构造函数。
以下是我目前找到的文件:
decl_eigen.pxd:
cdef extern from "Eigen/Dense" namespace "Eigen":
cdef cppclass Vector3d:
Matrix3d() except +
double coeff(int row, int col)
decl_foo.pxd:
cimport decl_eigen
cdef extern from "../foo.hpp" namespace "MyFoo":
cdef cppclass Bar:
Bar() except +
void transform(decl_eigen.Matrix3d &transformation)
foo.pyx:
import decl_eigen
cimport decl_foo
cdef class Bar:
cdef decl_foo.Bar *thisptr
def __cinit__(self):
self.thisptr = new decl_foo.Bar()
def __dealloc__(self):
del self.thisptr
def transform(self, transformation):
cdef decl_eigen.Matrix3d t = decl_eigen.Matrix3d()
for i in range(3):
for j in range(3):
k = i*3 + j
# Set the coefficient of t(i,j) to transformation[k], but how????
self.thisptr.transform(t)
谢谢。
它并不像它应该的那么简单,但你可以让它发挥作用。
Eigen 中的元素访问看起来主要是通过 operator()
:
完成的
// (copied from http://eigen.tuxfamily.org/dox/GettingStarted.html)
MatrixXd m(2,2);
m(0,0) = 3;
m(1,0) = 2.5;
m(0,1) = -1;
m(1,1) = m(1,0) + m(0,1);
因此,我们需要定义 operator() 以便您可以在 Cython 中访问它。我假设它 returns a double&
- 我实际上无法在 Eigen 中找到定义,因为它深埋在模板 class 层次结构中(它实际上并不重要 returns - 它表现得像 returns double&,应该足够好了)。
不幸的是,operator()
在 Cython 中似乎有些损坏(请参阅 Cython C++ wrapper operator() overloading error),因此我们必须将其别名作为其他名称。我用过 element
.
cdef extern from "eigen3/Eigen/Dense" namespace "Eigen":
# I'm also unsure if you want a Matrix3d or a Vector3d
# so I assumed matrix
cdef cppclass Matrix3d:
Matrix3d() except +
double& element "operator()"(int row,int col)
原则上我们希望能够做到 m.element(0,0) = 5
。然而,Cython 不喜欢这样。因此,我不得不创建一个函数,通过对指针类型机制的稍微复杂的赋值来实现这一点。
cdef void set_matrix_element(Matrix3d& m, int row, int col, double elm):
cdef double* d = &(m.element(row,col))
d[0] = elm
因此,要设置矩阵元素,我们只需调用此函数即可。这是我用来测试它的功能:
def get_numbers():
cdef Matrix3d m = Matrix3d()
cdef int i
for i in range(3):
set_matrix_element(m,i,i,i)
return m.element(0,0),m.element(1,1),m.element(2,2),m.element(1,2)
# returns 0,1,2, and something else (I get 0, but in principle
# I think it's undefined since it's never been specifically set)
我正在尝试在 Cython 中为使用 Eigen::Matrix3d 矩阵的库创建一个包装器。如何设置 Matrix3d 对象的单个 element/coefficient?
我知道,我可以使用 coeff(row, col)
方法获取值,但找不到任何函数 set_coeff(row, col, value)
- 或者可能被调用 - 来设置值。
在使用
声明 Matrix3d 之后cdef decl_eigen.Matrix3d t = decl_eigen.Matrix3d()
我想设置值,但是 none 以下构造在 Cython 中有效:
t << 1,2,3,4,5,6,7,8,9
t(0,0) = 1
t[0][0] = 1
而且我不能使用带有值的构造函数,因为据我所知不存在任何构造函数。
以下是我目前找到的文件:
decl_eigen.pxd:
cdef extern from "Eigen/Dense" namespace "Eigen":
cdef cppclass Vector3d:
Matrix3d() except +
double coeff(int row, int col)
decl_foo.pxd:
cimport decl_eigen
cdef extern from "../foo.hpp" namespace "MyFoo":
cdef cppclass Bar:
Bar() except +
void transform(decl_eigen.Matrix3d &transformation)
foo.pyx:
import decl_eigen
cimport decl_foo
cdef class Bar:
cdef decl_foo.Bar *thisptr
def __cinit__(self):
self.thisptr = new decl_foo.Bar()
def __dealloc__(self):
del self.thisptr
def transform(self, transformation):
cdef decl_eigen.Matrix3d t = decl_eigen.Matrix3d()
for i in range(3):
for j in range(3):
k = i*3 + j
# Set the coefficient of t(i,j) to transformation[k], but how????
self.thisptr.transform(t)
谢谢。
它并不像它应该的那么简单,但你可以让它发挥作用。
Eigen 中的元素访问看起来主要是通过 operator()
:
// (copied from http://eigen.tuxfamily.org/dox/GettingStarted.html)
MatrixXd m(2,2);
m(0,0) = 3;
m(1,0) = 2.5;
m(0,1) = -1;
m(1,1) = m(1,0) + m(0,1);
因此,我们需要定义 operator() 以便您可以在 Cython 中访问它。我假设它 returns a double&
- 我实际上无法在 Eigen 中找到定义,因为它深埋在模板 class 层次结构中(它实际上并不重要 returns - 它表现得像 returns double&,应该足够好了)。
不幸的是,operator()
在 Cython 中似乎有些损坏(请参阅 Cython C++ wrapper operator() overloading error),因此我们必须将其别名作为其他名称。我用过 element
.
cdef extern from "eigen3/Eigen/Dense" namespace "Eigen":
# I'm also unsure if you want a Matrix3d or a Vector3d
# so I assumed matrix
cdef cppclass Matrix3d:
Matrix3d() except +
double& element "operator()"(int row,int col)
原则上我们希望能够做到 m.element(0,0) = 5
。然而,Cython 不喜欢这样。因此,我不得不创建一个函数,通过对指针类型机制的稍微复杂的赋值来实现这一点。
cdef void set_matrix_element(Matrix3d& m, int row, int col, double elm):
cdef double* d = &(m.element(row,col))
d[0] = elm
因此,要设置矩阵元素,我们只需调用此函数即可。这是我用来测试它的功能:
def get_numbers():
cdef Matrix3d m = Matrix3d()
cdef int i
for i in range(3):
set_matrix_element(m,i,i,i)
return m.element(0,0),m.element(1,1),m.element(2,2),m.element(1,2)
# returns 0,1,2, and something else (I get 0, but in principle
# I think it's undefined since it's never been specifically set)