我在 cython 中实例化一个类。我想通过使用给定函数计算一个float
值数组的实例,并使用 c 函数将其保存在二进制文件中。对于我的类的进一步调用,如果输入文件已经存在,则通过从文件中读取数组来声明实例,否则它将再次计算它。
import numpy as np
cimport numpy as np
cimport cython
from libc.stdio cimport FILE, fopen, fwrite, fscanf, fclose, fseek, SEEK_END, ftell, stdout, stderr
cdef extern from "math.h":
double exp(double) nogil
double log(double) nogil
cdef class Hit(object):
cdef public double[::1] zs, Da
cdef char* path
def __cinit__(self, zs=None, path=None):
if path is None:
raise ValueError("Could not find a path to the file which contains the table of distances")
else:
self.path=path
if zs is None:
raise ValueError("You must give an array which contains the steps!")
self.zs=zs
cdef Py_ssize_t i, N
N=len(self.zs)
cdef FILE *ptr_fr
cdef FILE *ptr_fw
cdef double[::1] ptr_d = np.empty((N,))
ptr_fr = fopen(self.path, "rb")
ptr_fw = fopen(self.path, "wb")
if (ptr_fr==NULL):
print "I/O Error: cannot open file {}".format( self.path)
for i from N > i >= 0:
ptr_d[i]=log(self.zs[i]+1.) /(1- self.zs[i])**0.5
if (ptr_fw == NULL):
print "Unable to open file!\n"
else:
print "Opened file successfully for writing.\n"
fwrite(<void*>&ptr_d[0], sizeof(double), N, ptr_fw)
fclose(ptr_fw)
self.Da = ptr_d
else:
for i from N > i >= 0:
fscanf(ptr_fr,"%f", &ptr_d[i])
fclose(ptr_fr)
self.Da = ptr_d
当我第二次运行我的代码时,从读取文件返回到指针的值是正确的,但是我认为我将指针分配给内存视图的方式存在问题,因为{{1}中的所有值都是实例是零。有什么建议吗?!!
答案 0 :(得分:3)
我自己的问题的答案是:
import numpy as np
cimport numpy as np
cimport cython
from libc.stdio cimport FILE, fopen, fwrite, fscanf, fclose, fprintf, fseek, ftell, SEEK_END, rewind, fread
from numpy cimport float64_t
from libc.stdlib cimport malloc, free
cdef extern from "math.h":
double exp(double) nogil
double log(double) nogil
cdef class Hit(object):
cdef public double[::1] zs, Da
cdef char* path
@cython.boundscheck(False)
@cython.cdivision(True)
@cython.wraparound(False)
@cython.nonecheck(False)
def __cinit__(self, path=None, zs=None):
if path is None:
raise ValueError("Could not find a path to the file which contains the table of distances")
else:
self.path=path
if zs is None:
raise ValueError("You must give an array which contains the steps!")
self.zs=zs
cdef Py_ssize_t i, N, lSize
N=len(np.ascontiguousarray(self.zs))
print "Input file should have ",N
cdef FILE *ptr_fr
cdef FILE *ptr_fw
cdef size_t result
cdef double *ptr_d= <double *>malloc(N * sizeof(double))
ptr_fr = fopen(self.path, "rb")
if (ptr_fr==NULL):
print "I/O Error: cannot open file {}".format( self.path)
for i from N > i >= 0:
ptr_d[i]=log(self.zs[i])
print ptr_d[i]
ptr_fw = fopen(self.path, "wb")
if (ptr_fw == NULL):
print "Unable to open file!\n"
else:
print "Opened file successfully for writing.\n"
fwrite(ptr_d, sizeof(double), N, ptr_fw)
fclose(ptr_fw)
self.Da = np.asarray(<double[:N]>ptr_d)
else:
fseek (ptr_fr , 0 , SEEK_END)
lSize = ftell (ptr_fr)
print lSize
rewind (ptr_fr)
result=fread(ptr_d,sizeof(double),lSize ,ptr_fr )
for i from N > i >= 0:
print ptr_d[i]
fclose(ptr_fr)
self.Da = np.asarray(<double[:N]>ptr_d)
print np.ascontiguousarray(self.Da)
free(ptr_d)