'*'的操作数类型无效(double [:: 1]; double [:: 1])

时间:2015-04-19 23:08:31

标签: python cython memoryview

我在我的课程中实例化了记忆视图,如下所示:

from __future__ import division
import numpy as np
import pylab as plt
cimport numpy as np
cimport cython
cdef class fit(object):
     cdef public double[::1] shear_g1, shear_g2, shear_z, halo_pos_arcsec
     cdef public double[:,::1] shear_pos_arcsec, source_zpdf

     cdef char* path
     cdef double omega_m, omega_l, h, sigma_g

     @cython.boundscheck(False)
     @cython.cdivision(True)
     @cython.wraparound(False)
     @cython.nonecheck(False)
     def __init__(self, shear_g1, shear_g2, shear_pos_arcsec, shear_z, halo_pos_arcsec, double halo_z, source_zpdf, sigma_g, path=None, omega_m=None, omega_l=None, h=None ):

         self.shear_g1 = shear_g1
         self.shear_g2 = shear_g2
         self.shear_pos_arcsec = shear_pos_arcsec
         self.shear_z  = shear_z
         self.halo_pos_arcsec  = halo_pos_arcsec
         self.halo_z    = halo_z
         self.sigma_g   = sigma_g
         self.shear_zpdf= source_zpdf
         if path is None:
            raise ValueError("Could not find a path to the file which contains the table of angular diameter distances")
         self.path     = path
         self.n_model_evals = 0
         self.gaussian_prior_theta = [{'mean' : 14, 'std': 0.5}]
         if omega_m is None:
            self.omega_m=0.3

         if omega_l is None:
            self.omega_l=1-self.omega_m
         if h is None:                
            self.h=1.


     def plot(self, g1, g2):

         emag=np.sqrt(g1**2+g2**2)
         ephi=0.5*np.arctan2(g2,g1)              

         nuse=1
         quiver_scale=10
         plt.quiver(self.shear_pos_arcsec[::nuse,0], self.shear_pos_arcsec[::nuse,1], emag[::nuse]*np.cos(ephi)[::nuse], emag[::nuse]*np.sin(ephi)[::nuse], linewidths=0.001, headwidth=0., headlength=0., headaxislength=0., pivot='mid', color='r', label='original', scale=quiver_scale)

         plt.xlim([min(self.shear_pos_arcsec[::nuse,0]),max(self.shear_pos_arcsec[::nuse,0])])
         plt.ylim([min(self.shear_pos_arcsec[::nuse,1]),max(self.shear_pos_arcsec[::nuse,1])])
         plt.axis('equal')


     def plot_res(self, model_g1, model_g2, show=False):

         res1 , res2 = self.shear_g1 - model_g1, self.shear_g2 - model_g2

         emag_data=np.sqrt(self.shear_g1*self.shear_g1+self.shear_g2*self.shear_g1)
         ephi_data=0.5*np.arctan2(self.shear_g2,self.shear_g1)              

         emag_res=np.sqrt(res1**2+res2**2)
         ephi_res=0.5*np.arctan2(res2,res1)              

         emag_model=np.sqrt(model_g1**2+model_g2**2)
         ephi_model=0.5*np.arctan2(model_g2,model_g1)              
         plt.figure()
         plt.subplot(3,1,1)
         self.plot(self.shear_g1,self.shear_g2)
         plt.subplot(3,1,2)
         self.plot(model_g1,model_g2)
         plt.subplot(3,1,3)
         self.plot(res1 , res2)

         if show:
            plt.show()

但是我收到了有关内存视图操作的错误消息。

Error compiling Cython file:
------------------------------------------------------------
...

     def plot_res(self, model_g1, model_g2, show=False):

         res1 , res2 = self.shear_g1 - model_g1, self.shear_g2 - model_g2

         emag_data=np.sqrt(self.shear_g1*self.shear_g1+self.shear_g2*self.shear_g1)
                                       ^
------------------------------------------------------------

model.pyx:90:40: Invalid operand types for '*' (double[::1]; double[::1])

我想知道我应该如何对记忆视图进行数学运算?

1 个答案:

答案 0 :(得分:2)

如评论中所述,您可以使用np.asarray()临时将内存视图转换为数组,而无需复制,但会增加一些开销。一个非常快速的解决方案是执行循环并在内存视图中按元素操作。