-1
我希望得到一些關於如何讓我的代碼變得更快的幫助。目前,它確實太慢了。它基本上產生兩個具有不同佔空比的方波,然後對其生成的方波應用特殊濾波器以從方波中提取頻率分量,並通過改變兩個方波的佔空比來嘗試將該頻率分量與值相匹配波浪。數值求解代碼走得更快(numpy/scipy)
import os
import numpy as np
from scipy import optimize, integrate, signal
import math
import cmath
PI = np.pi
def Goetrzel(x, target_frequency, sample_rate):
s_prev = 0
s_prev2 = 0
normalized_frequency = target_frequency/sample_rate
wr = np.cos(2.0 * np.pi * normalized_frequency)
wi = np.sin(2.0 * np.pi * normalized_frequency)
coeff = 2.0 * wr
for sample in x:
s = sample + coeff * s_prev - s_prev2
s_prev2 = s_prev
s_prev = s
XKreal = s_prev * wr - s_prev2
XKimag = s_prev * wi
XK = (XKreal + 1j*XKimag)/(len(x)/2.)
#power = s_prev2 * s_prev2 + s_prev * s_prev - coeff * s_prev * s_prev2 ;
return abs(XK), np.angle(XK)*180./PI
def equations(p, zcurr, z, k1, k2):
P = lambda z, D1, D2: \
signal.square(k1*z, duty=D1) * signal.square(k2*z, duty=D2)
K12 = lambda z: -np.cos(np.pi/2.*z/L)+1.
K32 = lambda z: -np.sin(np.pi/2.*z/L)+1.
D1, D2 = p
h = 0.01
eq1 = Goetrzel(P(np.arange(0.,10.,h),D1,D2), k1/(2.*PI), 1./h)[0] - K12(zcurr)
eq2 = Goetrzel(P(np.arange(0.,10.,h),D1,D2), k2/(2.*PI), 1./h)[0] - K32(zcurr)
return eq1**2 + eq2**2
def DutyCycleSolver(z, k1, k2, display=False):
D1 = np.empty([len(z)])
D1.fill(np.nan)
D2 = np.empty([len(z)])
D2.fill(np.nan)
Derr = np.empty([len(z)])
Derr.fill(np.inf)
D1_D2_guess = np.empty([len(z),2])
for i in range(len(z)):
solutionFound = False
for guessD1 in np.arange(0.8, 1., 0.1):
for guessD2 in np.arange(0.8, 1., 0.1):
temp = optimize.fmin(equations,
x0=(guessD1, guessD2),
args=(z[i],z,k1,k2,),
xtol=1e-6,
ftol=1e-6,
disp=False,
full_output=True)
if temp[0][0] < -1.e-8 or temp[0][1] < -1.e-8 or \
temp[0][0] > 1.+1.e-8 or temp[0][1] > 1.+1.e-8:
continue
DerrCur = temp[1]
if DerrCur <= 1.e-3:
D1[i], D2[i] = temp[0]
Derr[i] = temp[1]
D1_D2_guess[i] = [guessD1, guessD2]
solutionFound = True
break
elif DerrCur > 1.e-3 and DerrCur < Derr[i]:
D1[i], D2[i] = temp[0]
Derr[i] = temp[1]
D1_D2_guess[i] = [guessD1, guessD2]
if solutionFound is True:
if display:
print 'Solution found at', z[i]
print 'Using:', D1[i], D2[i]
print 'Found with guess:', D1_D2_guess[i]
print 'Error:', Derr[i]
print
break
if solutionFound is False and display:
print 'No solution found at', z[i]
print 'Using:', D1[i], D2[i]
print 'With guess:', D1_D2_guess[i]
print 'Error:', Derr[i]
print
h = 0.3
L = 2.e3
z = np.arange(0., L, h)
DutyCycleSolver(z, 3., 8., display=True)
你有關於找到熱點的資料嗎?你有沒有嘗試不同的min-finding算法?反正慢很慢? –
明顯的改進是刪除了for-cycles。我還沒有完全研究過你的代碼,但似乎你正試圖通過補充不同的開始條件和反覆解決來發揮解決者的作用。此外,你正在定義你的目標函數中應該有效果的東西。 – Martin
我將注意力放在加速'Goetrzel'函數上,特別是它內部的'sample'循環。有3個外部循環,但他們最終調用'optimize.fmin'。這是'外部化'外部循環的根本障礙。 – hpaulj