Dan*_*sen 7 python optimization cython spectrum
我正在尝试使用Cython优化我的代码.它正在做一个功率谱,而不是使用FFT,因为这是我们在课堂上被告知要做的事情.我曾尝试在Cython中编写代码,但没有看到任何区别.这是我的代码
#! /usr/bin/env python
# -*- coding: utf8 -*-
from __future__ import division
cimport numpy as np
import numpy as np
cimport cython
@cython.boundscheck(False)
def power_spectrum(time, data, double f_min, double f_max, double df,w=1 ):
cdef double com,f
cdef double s,c,sc,cc,ss
cdef np.ndarray[double, ndim=1] power
cdef np.ndarray[double, ndim=1] freq
alfa, beta = [],[]
m = np.mean(data)
data -= m
freq = np.arange( f_min,f_max,df )
for f in freq:
sft = np.sin(2*np.pi*f*time)
cft = np.cos(2*np.pi*f*time)
s = np.sum( w*data*sft )
c = np.sum( w*data*cft )
ss = np.sum( w*sft**2 )
cc = np.sum( w*cft**2 )
sc = np.sum( w*sft*cft )
alfa.append( ( s*cc-c*sc )/( ss*cc-sc**2 ))
beta.append( ( c*ss-s*sc )/( ss*cc-sc**2 ))
com = -(f-f_min)/(f_min-f_max)*100
print "%0.3f%% complete" %com
power = np.array(alfa)**2 + np.array(beta)**2
return freq,power,alfa,beta
Run Code Online (Sandbox Code Playgroud)
时间和数据通过numpy.loadtxt加载并发送到此函数.当我做
cython -a power_spectrum.pyx
Run Code Online (Sandbox Code Playgroud)
.html文件很黄,所以效率不高.特别是整个for-loop和电源的计算并返回一切.
我曾尝试阅读Cython的官方指南,但由于我从未用C语言编写,因此有点难以理解.
所有帮助都非常精确:)
Cython 可以根据此读取 numpy 数组,但它不会神奇地编译类似的东西np.sum- 您仍然只是调用 numpy 方法。
您需要做的是用纯 cython 重写内部循环,然后它可以为您编译它。因此,您将需要重新实现等np.sum。np.sin预分配aplfa和beta是一个好主意,这样您就不会使用append并尝试cdef尽可能多的变量。
编辑
这是一个完整的示例,显示了完全 C 编译的内部循环(无黄色)。我不知道代码是否正确,但它应该是一个很好的起点!特别注意cdef到处使用,打开 cdivision 以及从标准库导入sin和导入。cos
from __future__ import division
cimport numpy as np
import numpy as np
cimport cython
from math import pi
cdef extern from "math.h":
double cos(double theta)
double sin(double theta)
@cython.boundscheck(False)
@cython.cdivision(True)
def power_spectrum(np.ndarray[double, ndim=1] time, np.ndarray[double, ndim=1] data, double f_min, double f_max, double df, double w=1 ):
cdef double com,f
cdef double s,c,sc,cc,ss,t,d
cdef double twopi = 6.283185307179586
cdef np.ndarray[double, ndim=1] power
cdef np.ndarray[double, ndim=1] freq = np.arange( f_min,f_max,df )
cdef int n = len(freq)
cdef np.ndarray[double, ndim=1] alfa = np.zeros(n)
cdef np.ndarray[double, ndim=1] beta = np.zeros(n)
cdef int ndata = len(data)
cdef int i, j
m = np.mean(data)
data -= m
for i in range(ndata):
f = freq[i]
s = 0.0
c = 0.0
ss = 0.0
cc = 0.0
sc = 0.0
for j in range(n):
t = time[j]
d = data[j]
sf = sin(twopi*f*t)
cf = cos(twopi*f*t)
s += w*d*sf
c += w*d*cf
ss += w*sf**2
cc += w*cf**2
sc += w*sf*cf
alfa[i] = ( s*cc-c*sc )/( ss*cc-sc**2 )
beta[i] = ( c*ss-s*sc )/( ss*cc-sc**2 )
power = np.array(alfa)**2 + np.array(beta)**2
return freq,power,alfa,beta
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
767 次 |
| 最近记录: |