我想计算这个积分$ \ frac {1} {L} \ int _ { - \ infty} ^ {t} H(t ^ {'})\ exp( - \ frac {R} {L}( tt ^ {'}))dt ^ {'} $使用numpy.convolution,其中$ H(t)$是较重的函数。我应该把它等于$ \ exp( - \ frac {R} {L} t)H(t)$ 以下是我的所作所为, 我通过改变变量乘以不同的H(t)将积分的限制改为-inf到+ inf然后我用它作为我的函数与H(t)(积分内的一个)卷积,但是输出图绝对不是exp函数,我也没有在我的代码中发现任何错误,请帮助,任何提示或建议都将不胜感激!
import numpy as np
import matplotlib.pyplot as plt
R = 1e3
L = 3.
delta = 1
Nf = 100
Nw = 200
k = np.arange(0,Nw,delta)
dt = 0.1e-3
tk = k*dt
Ng = Nf + Nw -2
n = np.arange(0,Nf+Nw-1,delta)
tn = n*dt
#define H
def H(n):
H = np.ones(n)
H[0] = 0.5
return H
#build ftns that get convoluted
f = H(Nf)
w = np.exp((-R/L)*tk)*H(Nw)
#return the value of I
It = np.convolve(w,f)/L
#return the value of Voutput, b(t)
b = H(Ng+1) - R*It
plt.plot(tn,b,'o')
plt.show()
答案 0 :(得分:2)
您的代码的问题不是编程,而是概念。将积分重写为积分[HeavisideTheta [t-t'] * Exp [-R / L * t'], - Inf,t](即Mathematica代码),经检查发现H(t-t')总是1在限制范围内(除了t'= t,这是积分限制......但这并不重要)。所以实际上你实际上并没有完成一个完整的卷积...你基本上只占了卷积的一半(或三分之一)。
如果你认为卷积是反转一个序列,然后一次转移并将其全部添加(参见http://en.wikipedia.org/wiki/Convolution#Derivations - 卷积的视觉解释)那么你想要的是中间的一半......即只有当它们重叠时。您不希望导入(第4个图表向下:http://en.wikipedia.org/wiki/File:Convolution3.svg)。你确实想要引出。
现在,修复代码的最简单方法是:
#build ftns that get convoluted
f = H(Nf)
w = np.exp((-R/L)*tk)*H(Nw)
#return the value of I
It = np.convolve(w,f)/L
max_ind = np.argmax(It)
print max_ind
It1 = It[max_ind:]
导入是唯一一次卷积积分(在我们的情况下技术上总和)增加...因此在导入完成后卷积积分跟随Exp [-x] ...所以你告诉python只有在达到最大值后才能取值。
#return the value of Voutput, b(t)
现在完美无缺!
注意:由于您需要引出线,因此无法使用np.convolve(a,b, mode = 'valid')
。
所以It1看起来像:
b(t)使用It1看起来像:
你无法将exp(-x)作为一般形式,因为b(t)的等式由1 - R * exp(-x)给出......它无法在数学上遵循exp(-x)形式。此时有三件事:
这些单位真的没有意义......检查一下。 Heaviside函数为1,R * It1约为10,000。我不确定这是一个问题,但为了以防万一,标准化曲线看起来像这样:
如果您使用b(t)= R * It1 - H(t),您可以获得exp(-x)表单...此处的代码在此处(您可能必须根据您的规范进行规范化)需要):
b = R*It1 - H(len(It1))
# print len(tn)
plt.plot(tn[:len(b)], b,'o')
plt.show()
情节如下:
答案 1 :(得分:0)
我认为这里有一些关于卷积的混淆。我们在时域中使用卷积来计算线性系统对任意输入的响应。为此,我们需要知道系统的脉冲响应。小心在连续和离散系统之间切换 - 参见例如http://en.wikipedia.org/wiki/Impulse_invariance
系统的(连续)脉冲响应(我假设为LR电路的电阻器电压)我为方便起见定义了时间t
:IR = lambda t: (R/L)*np.exp(-(R/L)*t) * H
。< / p>
我还假设您的输入是Heaviside阶跃函数,我在时间间隔[0,1]上定义了0.001秒的时间步长。
当我们(离散地)卷积时,我们有效地翻转一个函数并沿着另一个函数滑动它,乘以相应的值然后取总和。为了使用具有阶梯函数的连续脉冲响应,该阶跃函数实际上包括一系列Dirac delta函数,我们需要将连续脉冲响应乘以时间步长dt
,如上面关于脉冲不变性的Wikipedia链接中所述。注意 - 设置H[0] = 0.5
也很重要。
我们可以在下面看到这个操作。任何给定的红色标记代表给定时间t
的响应,并且是&#34; sum-product&#34;绿色输入和翻转的脉冲响应向右移动t
。我试图用一些灰色的脉冲反应来证明这一点。
进行计算的代码在这里。
import numpy as np
import matplotlib.pyplot as plt
R = 1e3 # Resistance
L = 3. #Inductance
dt = 0.001 # Millisecond timestep
# Define interval 1 second long, interval dt
t = np.arange(0, 1, dt)
# Define step function
H = np.ones_like(t)
H[0] = 0.5 # Correction for impulse invariance (cf http://en.wikipedia.org/wiki/Impulse_invariance)
# RL circuit - resistor voltage impulse response (cf http://en.wikipedia.org/wiki/RL_circuit)
IR = lambda t: (R/L)*np.exp(-(R/L)*t) * H # Don't really need to multiply by H as w is zero for t < 0
# Response of resistor voltage
response = np.convolve(H, IR(t)*dt, 'full')
制作情节的额外代码在这里:
# Define new, longer, time array for plotting response - must be same length as response, with step dt
tp = np.arange(len(response))* dt
plt.plot(0-t, IR(t), '-', label='Impulse response (flipped)')
for q in np.arange(0.01, 0.1, 0.01):
plt.plot(q-t, IR(t), 'o-', markersize=3, color=str(10*q))
t = np.arange(-1, 1, dt)
H = np.ones_like(t)
H[t<0] = 0.
plt.plot(t, H, 's', label='Unit step function')
plt.plot(tp, response, '-o', label='Response')
plt.tight_layout()
plt.grid()
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.legend()
plt.show()
最后,如果你仍然对卷积有一些困惑,我强烈推荐&#34;数字信号处理:工程师和科学家的实用指南&#34;作者:Steven W. Smith。