相位的三次样条插值 Space 图
Cublic Spline Interpolation of Phase Space Plot
我正在创建一个阶段-space电压对电压的一阶导数图:
我想对情节进行插值,使其平滑。到目前为止,我已经通过分别随时间对电压和电压的一阶导数进行插值来解决这个问题,然后生成相位 space 图。
Python代码(玩具数据示例)
import numpy as np
import scipy.interpolate
interp_factor = 100
n = 12
time = np.linspace(0, 10, n)
voltage = np.array([0, 1, 2, 10, 30, 70, 140, 150, 140, 80, 40, 10])
voltage_diff = np.diff(voltage)
voltage = voltage[:-1]
time = time[:-1]
interp_function_voltage = scipy.interpolate.interp1d(time, voltage, kind="cubic")
interp_function_voltage_diff = scipy.interpolate.interp1d(time, voltage_diff, kind="cubic")
new_sample_num = interp_factor * (n - 1) + 1
new_time = np.linspace(np.min(time), np.max(time), new_sample_num)
interp_voltage = interp_function_voltage(new_time)
interp_voltage_diff = interp_function_voltage_diff(new_time)
我想问:
a) 实施的方法是否合理?
b) 直接在phase-space中插值有没有更好的方法?例如用电压作为 x 和 voltage_diff 作为 y 进行插值?我认为这没有意义,因为电压值不是统一的 spaced 并且可能存在重复的电压值。我还尝试了 scipy 参数插值方法(例如 scipy.interpolate.splprep),但这些方法引发了输入值错误。我希望(澄清这一点会很好)因为这是原始数据,而不是表现良好的参数函数。
我想更一般地说,我想知道以某种方式在相位 space 中进行插值是否有意义,以利用电压和 voltage_diff 之间的直接关系进行插值/平滑.
非常感谢
这是合理的,但你的差异会有偏差,也许差异的最佳近似值可能是 (v[i+1] - v[i-1])/(2*dt)
另一种方法是使用傅里叶变换平滑
def smoother_phase_space(y, sps=1, T=1):
Y = np.fft.rfft(y)
yu = np.fft.irfft(Y, len(y)*sps).real * sps
dyu = np.fft.irfft(Y * (2j * np.pi * np.fft.rfftfreq(len(y))), len(y)*sps).real
k = np.arange(len(yu)+2) % len(yu)
return yu[k], dyu[k] * sps / T
v, dv = smoother_phase_space(voltage, sps=1)
plt.plot(v, dv, '-ob')
v, dv = smoother_phase_space(voltage, sps=4)
plt.plot(v, dv, '-r')
plt.plot(v[::4], dv[::4], 'or')
v, dv = smoother_phase_space(voltage, sps=32)
plt.plot(v, dv, '-g')
plt.plot(v[::32], dv[::32], 'og')
try: # the data computed in the original post
plt.plot(interp_voltage, interp_voltage_diff, '--')
except:
pass
我正在创建一个阶段-space电压对电压的一阶导数图:
我想对情节进行插值,使其平滑。到目前为止,我已经通过分别随时间对电压和电压的一阶导数进行插值来解决这个问题,然后生成相位 space 图。
Python代码(玩具数据示例)
import numpy as np
import scipy.interpolate
interp_factor = 100
n = 12
time = np.linspace(0, 10, n)
voltage = np.array([0, 1, 2, 10, 30, 70, 140, 150, 140, 80, 40, 10])
voltage_diff = np.diff(voltage)
voltage = voltage[:-1]
time = time[:-1]
interp_function_voltage = scipy.interpolate.interp1d(time, voltage, kind="cubic")
interp_function_voltage_diff = scipy.interpolate.interp1d(time, voltage_diff, kind="cubic")
new_sample_num = interp_factor * (n - 1) + 1
new_time = np.linspace(np.min(time), np.max(time), new_sample_num)
interp_voltage = interp_function_voltage(new_time)
interp_voltage_diff = interp_function_voltage_diff(new_time)
我想问:
a) 实施的方法是否合理?
b) 直接在phase-space中插值有没有更好的方法?例如用电压作为 x 和 voltage_diff 作为 y 进行插值?我认为这没有意义,因为电压值不是统一的 spaced 并且可能存在重复的电压值。我还尝试了 scipy 参数插值方法(例如 scipy.interpolate.splprep),但这些方法引发了输入值错误。我希望(澄清这一点会很好)因为这是原始数据,而不是表现良好的参数函数。
我想更一般地说,我想知道以某种方式在相位 space 中进行插值是否有意义,以利用电压和 voltage_diff 之间的直接关系进行插值/平滑.
非常感谢
这是合理的,但你的差异会有偏差,也许差异的最佳近似值可能是 (v[i+1] - v[i-1])/(2*dt)
另一种方法是使用傅里叶变换平滑
def smoother_phase_space(y, sps=1, T=1):
Y = np.fft.rfft(y)
yu = np.fft.irfft(Y, len(y)*sps).real * sps
dyu = np.fft.irfft(Y * (2j * np.pi * np.fft.rfftfreq(len(y))), len(y)*sps).real
k = np.arange(len(yu)+2) % len(yu)
return yu[k], dyu[k] * sps / T
v, dv = smoother_phase_space(voltage, sps=1)
plt.plot(v, dv, '-ob')
v, dv = smoother_phase_space(voltage, sps=4)
plt.plot(v, dv, '-r')
plt.plot(v[::4], dv[::4], 'or')
v, dv = smoother_phase_space(voltage, sps=32)
plt.plot(v, dv, '-g')
plt.plot(v[::32], dv[::32], 'og')
try: # the data computed in the original post
plt.plot(interp_voltage, interp_voltage_diff, '--')
except:
pass