将类的属性设置为固定一次,以避免繁琐的计算

2024-06-07 03:01:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个类,即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值。我认为这个过程相当缓慢,但似乎每次在循环中类的属性(如rdistobs_g)都会在每次迭代中计算出来。有没有办法设置一次,以提高环路的速度?你知道吗


Tags: posselfnonenormgetreturndistdef
1条回答
网友
1楼 · 发布于 2024-06-07 03:01:35

在开始的时候,为了找到一种方法来初始化一些实例,避免在每个函数的每次迭代中计算它们,我发现最好使用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

相关问题 更多 >