[英]Passing a pointer to a struct in cython
我正在嘗試為復雜版本的MUMPS解算器(zmumps)編寫一個cython接口。 我遇到了一些問題,因為我以前沒有C或cython的經驗。 按照pymumps包的例子,我能夠獲得真正的代碼版本(dmumps)。
我相信我的問題是指向ZMUMPS_COMPLEX結構的指針。 為了
zmumps_c.pxd:
from libc.string cimport strncpy
cdef extern from "mumps_c_types.h":
ctypedef struct ZMUMPS_COMPLEX "ZMUMPS_COMPLEX":
double r
double i
cdef extern from "zmumps_c.h":
ctypedef int MUMPS_INT
ctypedef struct c_ZMUMPS_STRUC_C "ZMUMPS_STRUC_C":
MUMPS_INT sym, par, job
MUMPS_INT comm_fortran # Fortran communicator
MUMPS_INT n
# Assembled entry
MUMPS_INT nz
MUMPS_INT *irn
MUMPS_INT *jcn
ZMUMPS_COMPLEX *a
# RHS and statistics
ZMUMPS_COMPLEX *rhs
MUMPS_INT infog[40]
void c_zmumps_c "zmumps_c" (c_ZMUMPS_STRUC_C *)
zmumps_c.pyx
cdef class ZMUMPS_STRUC_C:
cdef c_ZMUMPS_STRUC_C ob
property sym:
def __get__(self): return self.ob.sym
def __set__(self, value): self.ob.sym = value
property par:
def __get__(self): return self.ob.par
def __set__(self, value): self.ob.par = value
property job:
def __get__(self): return self.ob.job
def __set__(self, value): self.ob.job = value
property comm_fortran:
def __get__(self): return self.ob.comm_fortran
def __set__(self, value): self.ob.comm_fortran = value
property n:
def __get__(self): return self.ob.n
def __set__(self, value): self.ob.n = value
property nz:
def __get__(self): return self.ob.nz
def __set__(self, value): self.ob.nz = value
property irn:
def __get__(self): return <long> self.ob.irn
def __set__(self, long value): self.ob.irn = <MUMPS_INT*> value
property jcn:
def __get__(self): return <long> self.ob.jcn
def __set__(self, long value): self.ob.jcn = <MUMPS_INT*> value
property a:
def __get__(self): return <long> self.ob.a
def __set__(self, long value): self.ob.a = <ZMUMPS_COMPLEX*> value
property rhs:
def __get__(self): return <long> self.ob.rhs
def __set__(self, long value): self.ob.rhs = <ZMUMPS_COMPLEX*> value
property infog:
def __get__(self):
cdef MUMPS_INT[:] view = self.ob.infog
return view
def zmumps_c(ZMUMPS_STRUC_C s not None):
c_zmumps_c(&s.ob)
在我的python代碼中,我能夠設置irn和jcn使用
import zmumps_c
import numpy as np
MUMPS_STRUC_C = staticmethod(zmumps_c.ZMUMPS_STRUC_C)
id = MUMPS_STRUC_C()
x = np.r_[1:10]
id.irn = x.__array_interface__['data'][0]
但是,我不知道如何設置a或rhs的值。 任何幫助將不勝感激。
這可能有所幫助:
以下示例允許您獲取Python內置“復雜”對象的C級成員:
cdef extern from "complexobject.h":
struct Py_complex:
double real
double imag
ctypedef class __builtin__.complex [object PyComplexObject]:
cdef Py_complex cval
# A function which uses the above type
def spam(complex c):
print "Real:", c.cval.real
print "Imag:", c.cval.imag
從這里抓起來。
由於ZMUMPS_COMPLEX
和內置的Py_complex
結構具有完全相同的結構,您應該能夠通過在這兩種類型之間創建橋接(使用typedef和/或cast或將Py_complex轉換為ZMUMPS_COMPLEX的函數)來實現這一目的...
我想幫助更多,但我目前沒有安裝腮腺炎......
實現這一目標的方法不止一種 - 這是一種方法。
下面的代碼定義了ZMUMPS_COMPLEX
的包裝器。 然后它為ZMUMPS_STRUC_C
定義了一個包裝器, rhs
屬性使用__get__
和__set__
方法,允許它接受ZMUMPS_COMPLEX
包裝器。
zmumps_c.pyx
cdef class ZMUMPS_COMPLEX:
'''A wrapper for the ZMUMPS_COMPLEX struct'''
cdef c_ZMUMPS_COMPLEX c_zm
def __init__(self, double real, double imag=0):
self.c_zm.r = real
self.c_zm.i = imag
property r:
def __get__(self):
return self.c_zm.r
def __set__(self, value):
self.c_zm.r = value
property i:
def __get__(self):
return self.c_zm.i
def __set__(self, value):
self.c_zm.i = value
def __repr__(self):
return '({real}{imag:+}j)'.format(real=self.c_zm.r, imag=self.c_zm.i)
cdef class ZMUMPS_STRUC_C:
'''A wrapper for the ZMUMPS_STRUC_C struct'''
cdef c_ZMUMPS_STRUC_C ob
cdef object _rhs
property rhs:
def __get__(self):
return self._rhs
def __set__(self, ZMUMPS_COMPLEX c):
self._rhs = c
self.ob.rhs = &c.c_zm
def test(self):
return (self.ob.rhs[0].r, self.ob.rhs[0].i,)
def main():
z = ZMUMPS_STRUC_C()
c = ZMUMPS_COMPLEX(-3.5, 2.0)
z.rhs = c
print z.rhs
print z.test()
c.r = 42.0
print z.rhs
z.rhs.i = -5.0
print z.rhs
main()
函數演示了兩個對象的行為。 輸出應如下所示:
(-3.5+2.0j)
(-3.5, 2.0)
(42.0+2.0j)
(42.0-5.0j)
我沒有安裝庫,所以我使用下面的虛擬定義測試了這個:
zmumps_c.pxd
cdef struct c_ZMUMPS_COMPLEX "ZMUMPS_COMPLEX":
double r
double i
cdef struct c_ZMUMPS_STRUC_C "ZMUMPS_STRUC_C":
c_ZMUMPS_COMPLEX *rhs
setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("example.pyx")
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.