Create scipy curve fitting definitions for fourier series dynamically

荒凉一梦 提交于 2019-11-30 21:03:39

I would approach this by defining a single function fourier that accepts a variable number of arguments, using a loop through the cosines to evaluate the function for each of your input points:

def fourier(x, *a):
    ret = a[0] * np.cos(np.pi / tau * x)
    for deg in range(1, len(a)):
        ret += a[deg] * np.cos((deg+1) * np.pi / tau * x)
    return ret

Because this function takes a variable number of arguments, you need to provide a starting position of the correct dimensionality as a hint to the curve_fit function so it knows the number of cosines to use. In the example you provide with 8 cosines:

popt, pcov = curve_fit(fourier, z, Ua, [1.0] * 8)

Now, the use case you're asking about (fitting with 15 harmonics and plotting the first three) can be accomplished with:

# Fit with 15 harmonics
popt, pcov = curve_fit(fourier, z, Ua, [1.0] * 15)

# Plot data, 15 harmonics, and first 3 harmonics
fig = plt.figure()
ax1 = fig.add_subplot(111)
p1, = plt.plot(z,Ua)
p2, = plt.plot(z, fourier(z, *popt))
p3, = plt.plot(z, fourier(z, popt[0], popt[1], popt[2]))
plt.show()

YIY

based on this thread.

Passing additional arguments using scipy.optimize.curve_fit?

# import and filename
filename = 'data.txt'
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

z, Ua = np.loadtxt(filename,delimiter=',', unpack=True)
tau = 0.045

def make_fourier(na, nb):
    def fourier(x, *a):
        ret = 0.0
        for deg in range(0, na):
            ret += a[deg] * np.cos((deg+1) * np.pi / tau * x)
        for deg in range(na, na+nb):
            ret += a[deg] * np.sin((deg+1) * np.pi / tau * x)
        return ret
    return fourier

popt, pcov = curve_fit(make_fourier(15,15), z, Ua, [0.0]*30)

# Plot data, 15 harmonics, and first 3 harmonics
fig = plt.figure()
ax1 = fig.add_subplot(111)
p1, = plt.plot(z,Ua)
p2, = plt.plot(z, (make_fourier(15,15))(z, *popt))
#p3, = plt.plot(z, (make_fourier(8,8))(z, popt[0], popt[1], popt[2]))
plt.show()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!