使用Cython封装一个库,该库封装另一个库
|
我的目标是使用Cython包装Apohenia库,这是一个用于科学计算的C库。
这是不重建轮子的一种努力,并且Apophenia本身也试图通过基于GNU科学图书馆的结构来做到这一点:
typedef struct {
gsl_vector *vector;
gsl_matrix *matrix;
gsl_vector *weights;
apop_names *names;
...
} apop_data;
Apophenia提供了许多GSL不提供或笨拙地提供的向量/矩阵运算,但是如果GSL具有功能,则没有必要重写它。您应该能够根据需要经常编写在整个often1集及其GSL部分之间跳转的C代码,例如:
apop_data *dataset = apop_text_to_data(\"infile.csv\"); //fill the matrix element
gsl_vector *minv = apop_matrix_inverse(dataset->matrix);
apop_data *dinv = apop_matrix_to_data(minv);
apop_data *identity_matrix = apop_dot(dataset, dinv); // I = D * D^-1
dataset->vector = gsl_vector_alloc(10);
gsl_vector_set_all(dataset->vector, 1);
我不确定如何在Cython中包装它。典型的方法似乎是提供一个Python端结构,其中包含要包装的C结构的内部副本:
\"\"\"I\'m omitting the Cython declarations of the C structs and functions,
which are just translations of the C declarations. Let those be in c_apop.\"\"\"
cdef class apop_data:
cdef c_apop.apop_data *d
def set(self, row, col, val):
c_apop.apop_data_set(self.d, row, col, val)
def get(self, row, col):
c_apop.apop_data_get(self.d, row, col)
[et cetera]
cdef class gsl_vector:
cdef c_apop.gsl_vector *v
def set(self, row, val):
c_apop.gsl_vector_set(self.v, row)
def get(self, row):
c_apop.gsl_vector_get(self.v, row)
[et cetera]
但是现在我们陷入困境,因为如果要从数据集中获取vector元素,
pyd = apop_data(10)
v = pyd.d.vector
v
是原始Cgsl_vector
,而不是python对象,因此下一行不能是v.get(0)
或v.set(0, 1)
。
我们可以将方法添加到名为vector_get
和vector_set
的apop_data
类中,这些方法将返回python-wrappedgsl_vector
,但是会产生自己的问题:如果用户从pyv = pyd.get_vector()
重新分配py-vector的C向量,我们如何保证pyd.d.vector
重新分配了吗?
我已经尝试了几件事,但我感觉每次都错过了重点。关于如何针对这种情况最佳设计Cython类的任何建议?
没有找到相关结果
已邀请:
1 个回复
懊毁暗