2015-05-28 22 views
2

我有兩個類別,即PositionsDmakemock其被定義爲如下:設置爲了固定後一類的屬性,以避免繁瑣的計算

import numpy as np 
cdef class PositionsD(object): 

    property x: 
     def __get__(self): 
      return np.array(self._x) 
     def __set__(self, x): 
      self._x = x 

    property y: 
     def __get__(self): 
      return np.array(self._y) 
     def __set__(self, y): 
      self._y = y 
def __init__(self, positions): 
    self._x = positions[:,0] 
    self._y = positions[:,1] 

class makemock(object): 
    def __init__(self): 
     self.scale = 0.238 
     self.arcsec2rad = np.pi/180./60./60. 
     self.g1 = None 
     self.g2 = None 
     self.source_pos = None 
     self.z = None 
     self.h_pos = None 
     self.h_z = None 

    def get_pos(self): 
     return PositionsD(self.source_pos) 
    pos = property(get_shear_pos) 

    def get_center(self): 
     return PositionsD(self.h_pos) 
    center = property(get_center) 

    def get_dist(self): 
     dx_mpc = (self.pos.x-self.center.x)*self.arcsec2rad*self.scale 
     dy_mpc = (self.pos.y-self.center.y)*self.arcsec2rad*self.scale 
     return np.vectorize(complex)(dx_mpc, dy_mpc) 
    dist = property(get_dist) 

    def get_r(self): 
     return abs(self.dist) 
    r = property(get_r) 

    def get_norm(self): 
     return -self.dist/np.conjugate(self.dist) 
    norm = property(get_norm) 


    def get_gabs(self): 
     return np.sqrt(self.g1**2 + self.g2**2) 
    gabs = property(get_gabs) 

    def get_g(self): 
     phiell=np.arctan2(self.g2, self.g1) /2. 
     phipos=np.arctan2((self.pos.y-self.center.y), (self.pos.x-self.center.x)) 
     et = -self.gabs * np.cos(2*(phiell-phipos)) 
     ec = -self.gabs * np.sin(2*(phiell-phipos)) 
     return np.vectorize(complex)(et, ec) 
    obs_g = property(get_g) 

    def data2model(self,params): 
     rs = params 
     x = self.r/rs 
     P = len(self.r) 
     gamma = np.zeros((P,), dtype=np.float64, order='C') 
     kappa = np.zeros((P,), dtype=np.float64, order='C') 
     farcth = np.zeros((P,), dtype=np.float64, order='C') 

     m1 = np.where(x < 1.0)[0] 
     kappa[m1] = 2/(x[m1]**2 - 1) * \ 
      (1 - np.log((1 + ((1 - x[m1])/(x[m1] + 1))**0.5)/(1 - ((1 - x[m1])/(x[m1] + 1))**0.5))/(1 - x[m1]**2)**0.5) 

     farcth[m1]=0.5*np.log((1.+((1.-x[m1])/(x[m1]+1.))**0.5)/(1.-((1.-x[m1])/(x[m1]+1.))**0.5))/(1-x[m1]**2)**0.5 

     gamma[m1] = 4*(np.log(x[m1]/2) + 2*farcth[m1]) * x[m1]**(-2) - kappa[m1] 
     model_g = self.norm* gamma /(1. - kappa) 
     e = (self.obs_g+model_g)/(1+np.conjugate(model_g)*self.obs_g) 
     mask=(abs(model_g)>1.) 
     if (np.sum(mask)>0): 
     e[mask]=1./np.conjugate(e[mask]) 
     return e 

我的問題是:

我需要在makemock環路中運行data2model方法,以獲得不同的值params。我認爲這個過程非常緩慢,而且似乎每次都會在每次迭代中計算一個類的循環屬性,例如rdist,obs_g。有沒有辦法設置它們一次,以增加循環的速度?

+0

您是否嘗試過創建對象,然後訪問timeit循環中的各種屬性?如果是這樣,比別人花更長的時間?另外,如果計算單個值,而不是大數組,那麼'math.sin'可能比'np.sin'快。等這些屬性可以在創建對象後更改,還是固定?如果修復,您可能需要製作屬性而不是屬性。 – hpaulj

+0

@hpaulj我發佈了一條消息。您如何看待這種節省時間和加速代碼的方式? – Dalek

回答

1

在找出初始化一些實例的方法並避免在每個函數的每次迭代中計算它們之後,我發現最好使用dict並在此字典中保留每個實例的值和update他們在初始化實例結束時。這是我的解決方案:

class makemock(object): 
    def __init__(self, g1, g2, source_pos, z, h_pos, h_z, **kw): 
     self.scale = 0.238 
     self.arcsec2rad = np.pi/180./60./60. 
     self.g1 = g1 
     self.g2 = g2 
     self.source_pos = source_pos 
     self.z = z 
     self.h_pos = h_pos 
     self.h_z = h_z 
     pos= PositionsD(self.source_pos) 
     center=PositionsD(self.h_pos) 
     dx_mpc = (pos.x-center.x)*self.arcsec2rad*self.scale 
     dy_mpc = (pos.y-center.y)*self.arcsec2rad*self.scale 
     dist= np.vectorize(complex)(dx_mpc, dy_mpc) 
     r= abs(dist) 
     norm= -dist/np.conjugate(dist) 
     gabs= np.sqrt(self.g1**2 + self.g2**2) 

     phiell=np.arctan2(self.g2, self.g1) /2. 
     phipos=np.arctan2((pos.y-center.y), (pos.x-center.x)) 
     et = -gabs * np.cos(2*(phiell-phipos)) 
     ec = -gabs * np.sin(2*(phiell-phipos)) 
     obs_g=np.vectorize(complex)(et, ec) 
     self.__dict__.update(kw) 
     del kw 
     self.__dict__.update(locals()) 
     del self.self 
    def dump(self): 
     print repr(self.__dict__) 


    def data2model(self,params): 
     rs = params 
     x = self.r/rs 
     P = len(self.r) 
     gamma = np.zeros((P,), dtype=np.float64, order='C') 
     kappa = np.zeros((P,), dtype=np.float64, order='C') 
     farcth = np.zeros((P,), dtype=np.float64, order='C') 

     m1 = np.where(x < 1.0)[0] 
     kappa[m1] = 2/(x[m1]**2 - 1) * \ 
      (1 - np.log((1 + ((1 - x[m1])/(x[m1] + 1))**0.5)/(1 - ((1 - x[m1])/(x[m1] + 1))**0.5))/(1 - x[m1]**2)**0.5) 

     farcth[m1]=0.5*np.log((1.+((1.-x[m1])/(x[m1]+1.))**0.5)/(1.-((1.-x[m1])/(x[m1]+1.))**0.5))/(1-x[m1]**2)**0.5 

     gamma[m1] = 4*(np.log(x[m1]/2) + 2*farcth[m1]) * x[m1]**(-2) - kappa[m1] 
     model_g = self.norm* gamma /(1. - kappa) 
     e = (self.obs_g+model_g)/(1+np.conjugate(model_g)*self.obs_g) 
     mask=(abs(model_g)>1.) 
     if (np.sum(mask)>0): 
     e[mask]=1./np.conjugate(e[mask]) 
     return e 
相關問題