簡體   English   中英

為什么用Python進行數值微分會改變正弦波的原始信號幅度?

[英]Why does numerical differentiation with Python changes original signal amplitude for sine wave?

我用不同的方法計算了振幅為1的正弦波的數值導數。 盡管相位看起來不錯,但當我期望原始信號的幅度相同時(〜1),我得到的派生信號幅度為〜6。 對於理解為什么會發生的任何幫助,我將不勝感激。 這是我的代碼和帶有比例縮放比例而不是比例縮放比例的圖:

# -*- coding: utf-8 -*- 
from __future__ import division

import numpy as np
from scipy.interpolate import InterpolatedUnivariateSpline
import matplotlib.pyplot as plt
from scipy.interpolate import splrep, splder, splev

## Useful Links
## https://stackoverflow.com/questions/9876290/how-do-i-compute-derivative-using-numpy
## https://stackoverflow.com/questions/42197460/numpy-diff-and-scipy-fftpack-diff-giving-different-results-when-differentiat
## ## https://stackoverflow.com/questions/42197460/numpy-diff-and-scipy-fftpack-diff-giving-different-results-when-differentiat

x = np.linspace(0,1,361)

# Create sin wave values
sin = np.sin(np.radians(np.linspace(0,361,361)))

# Create cosine wave values
cos = np.cos(np.radians(np.linspace(0,361,361)))

# Create scale factor for derivative values
scale = 6

## Method 1
# Get a function that evaluates the linear spline at any x
f = InterpolatedUnivariateSpline(x, sin, k=3)

# Get a function that evaluates the derivative of the linear spline at any x
dfdx = f.derivative()

# Evaluate the derivative dydx at each x location...
dydx_1_no_scaled = dfdx(x)
dydx_1_scaled = dfdx(x)/scale

## Method 2
# Calculate time step
dx = x[1] - x[0]

# Gradient method :  central differences
dydx_2_no_scaled = (np.gradient(sin, dx))
dydx_2_scaled = (np.gradient(sin, dx))/6


## Method 3
# Approximations of derivatives
dydx_3_no_scaled = (np.diff(sin) / np.diff(x))
dydx_3_scaled = (np.diff(sin) / np.diff(x))/6

# Method 4 : Spline
time = np.linspace(0,1,361)

# Calculate signal spline func 'tck'
func = splrep(time, sin, s=0, k=3)

# Calculate derivative spline func 'tck'
der_func = splder(func, n=1)

# Calculate derivative values
dydx_4_no_scaled = splev(x, der_func, der=0, ext=0 )
dydx_4_scaled = splev(x, der_func, der=0, ext=0 )/6

plt.plot(sin)
plt.plot(cos)
plt.plot(dydx_1_no_scaled)
plt.plot(dydx_1_scaled)
plt.plot(dydx_2_no_scaled)
plt.plot(dydx_2_scaled)
plt.plot(dydx_3_no_scaled)
plt.plot(dydx_3_scaled)
plt.plot(dydx_4_no_scaled)
plt.plot(dydx_4_scaled)
plt.axvline(90)
plt.axvline(180)
plt.axvline(270)
plt.title('Sine Wave and respective derivative with 4 different methods')
plt.legend(['sin',
            'cos',
            'dydx_1_no_scaled', 'dydx_1_scaled',
            'dydx_2_no_scaled', 'dydx_2_scaled',
            'dydx_3_no_scaled', 'dydx_3_scaled',
            'dydx_4_no_scaled', 'dydx_4_scaled'])
plt.show()

謝謝你的幫助。 伊沃

數組sin包含一個完整周期的正弦函數,並且相應的x值范圍為0到1。因此,您計算出的函數為sin(2*pi*x) 因此,導數為2*pi*cos(2*pi*x) (注意〜6是〜2π。)

這是一個使用derivative()方法創建派生的插值器的腳本,即插值正弦函數。 內插器是在間隔[0,2π]上創建的,間隔為sin(x)的一個周期。

import numpy as np
from scipy.interpolate import InterpolatedUnivariateSpline
import matplotlib.pyplot as plt


num_samples = 250
x = np.linspace(0, 2*np.pi, num_samples)
y = np.sin(x)

f = InterpolatedUnivariateSpline(x, y, k=3)
dfdx = f.derivative()

print(np.max(np.abs(np.cos(x) - dfdx(x))))

plt.plot(x, dfdx(x), '--', label='dfdx(x)', linewidth=1)
plt.plot(x, np.cos(x), label='cos(x)', linewidth=4, alpha=0.25)
plt.legend(loc='lower left')
plt.xlabel('x')
plt.show()

程序打印7.05390776901e-08並生成以下圖:

情節

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM