2017-06-14 83 views
2

如何在Python中生成梯形波?Python中的梯形波

我查看了諸如SciPy和NumPy等模塊,但徒勞無功。是否有像scipy.signal.gaussian這樣的模塊返回表示高斯函數波的數值數組?

Enter image description here

我生成此使用的Astropy梯形內核, Trapezoid1DKernel(30,斜率= 1.0) 。我想在不使用Astropy的情況下在Python中實現它。

+0

貴trapezodial波有哪些參數? –

+0

只是寬度和坡度。 –

回答

1

雖然寬度和斜率足以限定的三角形波信號,就需要爲梯形信號的第三參數:幅值。

使用這三個參數,您可以輕鬆調整scipy.signal.sawtooth函數,通過截斷和偏移三角形函數來爲您提供梯形形狀。

from scipy import signal 
import matplotlib.pyplot as plt 
import numpy as np 


def trapzoid_signal(t, width=2., slope=1., amp=1., offs=0): 
    a = slope*width*signal.sawtooth(2*np.pi*t/width, width=0.5)/4. 
    a[a>amp/2.] = amp/2. 
    a[a<-amp/2.] = -amp/2. 
    return a + amp/2. + offs 

t = np.linspace(0, 6, 501) 
plt.plot(t,trapzoid_signal(t, width=2, slope=2, amp=1.), label="width=2, slope=2, amp=1") 
plt.plot(t,trapzoid_signal(t, width=4, slope=1, amp=0.6), label="width=4, slope=1, amp=0.6") 

plt.legend(loc=(0.25,1.015)) 
plt.show() 

enter image description here

注意,你可能也想定義一個階段,depeding於使用情況。

爲了定義單個脈衝,您可能需要修改該功能並提供一個範圍超過[0,width]的數組。

from scipy import signal 
import matplotlib.pyplot as plt 
import numpy as np 

def trapzoid_signal(t, width=2., slope=1., amp=1., offs=0): 
    a = slope*width*signal.sawtooth(2*np.pi*t/width, width=0.5)/4. 
    a += slope*width/4. 
    a[a>amp] = amp 
    return a + offs 

for w,s,a in zip([2,5], [2,1], [1,0.6]): 
    t = np.linspace(0, w, 501) 
    l = "width={}, slope={}, amp={}".format(w,s,a) 
    plt.plot(t,trapzoid_signal(t, width=w, slope=s, amp=a), label=l) 

plt.legend(loc="upper right") 
plt.show() 

enter image description here

+0

這看起來很方便。你可以告訴我如何產生一個特定寬度的單脈衝。我想實現我在問題中附加的圖像。謝謝 –

+0

我更新了答案。 – ImportanceOfBeingErnest

+0

非常感謝。做了一些編輯並最終完成了。 –

2

SciPy website它看起來像這不包括(他們目前有sawtoothsquare,但不是梯形)。作爲the C例程的通用版本,下面將做你想做的,

import numpy as np 
import matplotlib.pyplot as plt 

def trapezoidalWave(xin, width=1., slope=1.): 
    x = xin%(4*width) 
    if (x <= width): 
     # Ascending line 
     return x*slope; 
    elif (x <= 2.*width): 
     # Top horizontal line 
     return width*slope 
    elif (x <= 3.*width): 
     # Descending line 
     return 3.*width*slope - x*slope 
    elif (x <= 4*width): 
     # Bottom horizontal line 
     return 0. 


x = np.linspace(0.,20,1000) 
for i in x: 
    plt.plot(i, trapezoidalWave(i), 'k.') 
    plt.plot(i, trapezoidalWave(i, 1.5, 2.), 'r.') 
plt.show() 

它看起來像,

Enter image description here

這可以更優雅與亥功能,使用戶使用來完成NumPy陣列,

import numpy as np 
import matplotlib.pyplot as plt 

def H(x): 
    return 0.5 * (np.sign(x) + 1) 

def trapWave(xin, width=1., slope=1.): 
    x = xin%(4*width) 
    y = ((H(x)-H(x-width))*x*slope + 
     (H(x-width)-H(x-2.*width))*width*slope + 
     (H(x-2.*width)-H(x-3.*width))*(3.*width*slope - x*slope)) 
    return y 

x = np.linspace(0.,20,1000) 
plt.plot(x, trapWave(x)) 
plt.plot(x, trapWave(x, 1.5, 2.)) 
plt.show() 

對於這個例子,Heaviside版本快了20倍!

2

下面的例子顯示瞭如何做到這一點,以獲得積分和顯示範圍。

方程基於答覆:Equation for trapezoidal wave equation

import math 
import numpy as np 
import matplotlib.pyplot as plt 


def get_wave_point(x, a, m, l, c): 
    # Equation from: https://stackoverflow.com/questions/11041498/equation-for-trapezoidal-wave-equation 
    # a/pi(arcsin(sin((pi/m)x+l))+arccos(cos((pi/m)x+l)))-a/2+c 
    # a is the amplitude 
    # m is the period 
    # l is the horizontal transition 
    # c is the vertical transition 

    point = a/math.pi*(math.asin(math.sin((math.pi/m)*x+l))+math.acos(math.cos((math.pi/m)*x+l)))-a/2+c 
    return point 

print('Testing wave') 

x = np.linspace(0., 10, 1000) 
listofpoints = [] 
for i in x: 
    plt.plot(i, get_wave_point(i, 5, 2, 50, 20), 'k.') 
    listofpoints.append(get_wave_point(i, 5, 2, 50, 20)) 
print('List of points : {} '.format(listofpoints)) 
plt.show() 
0

全歸功於@ImportanceOfBeingErnest。我只是修改了他剛剛創建我的一天的代碼。

from scipy import signal 
import matplotlib.pyplot as plt 
from matplotlib import style 
import numpy as np 

def trapzoid_signal(t, width=2., slope=1., amp=1., offs=0): 
    a = slope*width*signal.sawtooth(2*np.pi*t/width, width=0.5)/4. 
    a += slope*width/4. 
    a[a>amp] = amp 
    return a + offs 

for w,s,a in zip([32],[1],[0.0322]): 
    t = np.linspace(0, w, 34) 

    plt.plot(t,trapzoid_signal(t, width=w, slope=s, amp=a)) 


plt.show() 

結果:enter image description here