我目前正在把一些C代码翻译成Python。该代码正被用来帮助识别由射电天文学中使用的CLEAN算法引起的错误。为了分析强度图的傅里叶变换值,必须在特定像素值处找到Q-Stokes-Map和U-Stokes-Map(由ANT_-pix给出)。这些地图只是257*257数组。在
下面的代码用C运行需要几秒钟,而用Python运行则需要几个小时。我很确定它是非常优化的,因为我对Python的了解非常差。在
谢谢你的帮助。在
更新我的问题是,是否有更好的方法在Python中实现循环,从而加快速度。我在这里读了很多关于Python的问题的答案,这些问题建议尽可能避免在Python中嵌套for循环,我只是想知道是否有人知道一种好的方法来实现下面的Python代码,而不使用循环或使用更好的优化循环。我知道这可能是一个很高的要求!在
到目前为止,我一直在使用FFT,但我的主管想看看DFT会有什么不同。这是因为天线位置通常不会出现在精确的像素值处。使用FFT需要舍入到最接近的像素值。在
我用Python作为CASA,用来减少射电天文数据集的计算机程序是用Python编写的,用它实现Python脚本远比C简单得多
原始代码
def DFT_Vis(ANT_Pix="",IMap="",QMap="",UMap="", NMap="", Nvis=""):
UV=numpy.zeros([Nvis,6])
Offset=(NMap+1)/2
ANT=ANT_Pix+Offset;
i=0
l=0
k=0
SumI=0
SumRL=0
SumLR=0
z=0
RL=QMap+1j*UMap
LR=QMap-1j*UMap
Factor=[math.e**(-2j*math.pi*z/NMap) for z in range(NMap)]
for i in range(Nvis):
X=ANT[i,0]
Y=ANT[i,1]
for l in range(NMap):
for k in range(NMap):
Temp=Factor[int((X*l)%NMap)]*Factor[int((Y*k)%NMap)];
SumI+=IMap[l,k]*Temp
SumRL+=RL[l,k]*Temp
SumLR+=IMap[l,k]*Temp
k=1
UV[i,0]=SumI.real
UV[i,1]=SumI.imag
UV[i,2]=SumRL.real
UV[i,3]=SumRL.imag
UV[i,4]=SumLR.real
UV[i,5]=SumLR.imag
l=1
k=1
SumI=0
SumRL=0
SumLR=0
return(UV)
如果您对提高脚本的性能感兴趣,cython可能是一个选择。在
我不是FFT的专家,但我的理解是FFT只是一种快速计算DFT的方法。所以对我来说,你的问题听起来像是在尝试编写一个气泡排序算法,看看它是否比快速排序给出了更好的答案。它们都是排序算法,结果是一样的!在
所以我质疑你的基本前提。我想知道你是否可以改变你的数据四舍五入,从SciPy FFT代码得到同样的结果。在
另外,根据我的DSP教科书,FFT可以产生比计算DFT更精确的答案,这仅仅是因为浮点运算是不精确的,而且FFT在寻找正确答案的过程中调用的浮点运算更少。在
如果您有一些工作的C代码可以完成所需的计算,那么您可以始终包装C代码,以便从Python调用它。此处讨论:Wrapping a C library in Python: C, Cython or ctypes?
回答您的实际问题:正如@ZoZo123所指出的,从}将是一个巨大的胜利。使用
range()
更改为{range()
,Python必须构建一个数字列表,然后在完成后销毁该列表;使用xrange()
Python只需创建一个迭代器,每次生成一个数字。(但是请注意,在python3.x中,range()
生成一个迭代器,并且没有xrange()
。)另外,如果此代码不必与其余代码集成,则可以尝试在PyPy下运行此代码。这正是pypyy可以优化的代码类型。PyPy的问题是,当前您的项目必须是“纯”Python,而且看起来您使用的是NumPy。(有一些项目可以让NumPy和PyPy一起工作,但是还没有完成)http://pypy.org/
如果这段代码需要与其他代码集成,那么我认为您需要看看Cython(正如@Krzysztof Rosiêski所指出的)。在
您可能应该使用numpy的fourier变换代码,而不是自己编写:http://docs.scipy.org/doc/numpy/reference/routines.fft.html
相关问题 更多 >
编程相关推荐