多元异维拟合
Multivariant different dimensional fit
我正在尝试使用 scipy curve_fit 进行 3 维三次多项式拟合,但由于我对 python 曲线拟合工具的经验不多,我'我在这样做时遇到了一些麻烦。
我有一个函数的两个参数,它们是向量,一个矩阵表示每个点的值。我正在尝试对每个参数进行 3 次多项式拟合,但我遇到了一些麻烦。我正在尝试使用 curve_fit 函数,因为那是我在网上找到的,如果有更好的建议,如 polyfit,我会很乐意听取他们的意见。这是我的代码:
import numpy as np
from scipy.optimize import curve_fit
def polyfit(data,a1,a2,a3,a4,a5,a6,a7):
return a1*np.power(data[0],3) + a2*np.power(data[0],2) + a3*data[0] \
+ a4*np.power(data[1],3) + a5*np.power(data[1],2) + a6*data[1] + a7
xtemp = np.array([10,25,35,45,55])
yexpT = np.array([1,5,10,100,500,1000,5000,7500])
dataMat = np.array([[1475,1475,1478,1528,1776,2086,4588,6146] ,
[1575,1575,1578,1728,1976,2086,6588,7146],
[1675,1675,1778,1928,2176,2586,7588,9146],
[2575,2575,2578,2728,2976,3086,9588,11146],
[3575,3575,3578,3728,4976,8086,12588,15146]])
ymesh,xmesh = np.meshgrid(yexpT,xtemp)
popt,pcov = curve_fit(polyfit,[xmesh,ymesh],dataMat)
如您所见,xtemp 是行数,yexpT 是列数。
我试图在以下 link 中寻求帮助,例如:
还是没用。
提前感谢任何能够提供帮助的人。
这是 least_squares
的简单解决方案:
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import numpy as np
from scipy.optimize import least_squares
def poly( x, y,
c0,
a1, a2, a3,
b1, b2, b3
):
"non-mixing test plynomial"
out = c0
out += a1 * x**1 + a2 * x**2 + a3 * x**3
out += b1 * y**1 + b2 * y**2 + b3 * y**3
return out
### test grid
xL = np.linspace( -2, 5, 17 )
yL = np.linspace( -0, 6, 16 )
XX, YY = np.meshgrid( xL, yL )
### test data
ZZ = poly(
XX, YY,
1.1,
2.2, -0.55, 0.09,
-3.1, +0.75, -0.071
)
### test noise
znoise = np.random.normal( size=( len(xL) * len(yL) ), scale=0.5 )
znoise.resize( len(yL), len(xL) )
ZZ += znoise
### residual finction, i.e. the important stuff
def res( params, X, Y, Z ):
th = poly( X, Y, *params )
diff = Z - th
return np.concatenate( diff )
### fit
sol = least_squares( res, x0=7*[0], args=( XX, YY, ZZ ) )
print( sol.x )
### plot it
fig = plt.figure( )
ax = fig.add_subplot( 1, 1, 1, projection="3d" )
ax.scatter( XX, YY, ZZ, color='r' )
ax.plot_surface( XX, YY, poly( XX, YY, *(sol.x) ) )
plt.show()
顺便说一句,这当然是纯线性拟合。所以根据我的另一个 post 的定义,可以这样做:
### fitting:
X = np.concatenate( XX )
Y = np.concatenate( YY )
Z = np.concatenate( ZZ )
VT = np.array( [
np.ones( len(xL) * len(yL) ),
X, X**2, X**3,
Y, Y**2, Y**3
] )
V = np.transpose( VT )
eta = np.dot( VT, Z )
A = np.dot( VT, V )
sol = np.linalg.solve( A, eta )
print( sol )
### plot it
fig = plt.figure( )
ax = fig.add_subplot( 1, 1, 1, projection="3d" )
ax.scatter( XX, YY, ZZ, color='r' )
ax.plot_surface( XX, YY, poly( XX, YY, *(sol) ) )
plt.show()
我在 here
中添加了更多信息
我正在尝试使用 scipy curve_fit 进行 3 维三次多项式拟合,但由于我对 python 曲线拟合工具的经验不多,我'我在这样做时遇到了一些麻烦。
我有一个函数的两个参数,它们是向量,一个矩阵表示每个点的值。我正在尝试对每个参数进行 3 次多项式拟合,但我遇到了一些麻烦。我正在尝试使用 curve_fit 函数,因为那是我在网上找到的,如果有更好的建议,如 polyfit,我会很乐意听取他们的意见。这是我的代码:
import numpy as np
from scipy.optimize import curve_fit
def polyfit(data,a1,a2,a3,a4,a5,a6,a7):
return a1*np.power(data[0],3) + a2*np.power(data[0],2) + a3*data[0] \
+ a4*np.power(data[1],3) + a5*np.power(data[1],2) + a6*data[1] + a7
xtemp = np.array([10,25,35,45,55])
yexpT = np.array([1,5,10,100,500,1000,5000,7500])
dataMat = np.array([[1475,1475,1478,1528,1776,2086,4588,6146] ,
[1575,1575,1578,1728,1976,2086,6588,7146],
[1675,1675,1778,1928,2176,2586,7588,9146],
[2575,2575,2578,2728,2976,3086,9588,11146],
[3575,3575,3578,3728,4976,8086,12588,15146]])
ymesh,xmesh = np.meshgrid(yexpT,xtemp)
popt,pcov = curve_fit(polyfit,[xmesh,ymesh],dataMat)
如您所见,xtemp 是行数,yexpT 是列数。
我试图在以下 link 中寻求帮助,例如:
提前感谢任何能够提供帮助的人。
这是 least_squares
的简单解决方案:
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import numpy as np
from scipy.optimize import least_squares
def poly( x, y,
c0,
a1, a2, a3,
b1, b2, b3
):
"non-mixing test plynomial"
out = c0
out += a1 * x**1 + a2 * x**2 + a3 * x**3
out += b1 * y**1 + b2 * y**2 + b3 * y**3
return out
### test grid
xL = np.linspace( -2, 5, 17 )
yL = np.linspace( -0, 6, 16 )
XX, YY = np.meshgrid( xL, yL )
### test data
ZZ = poly(
XX, YY,
1.1,
2.2, -0.55, 0.09,
-3.1, +0.75, -0.071
)
### test noise
znoise = np.random.normal( size=( len(xL) * len(yL) ), scale=0.5 )
znoise.resize( len(yL), len(xL) )
ZZ += znoise
### residual finction, i.e. the important stuff
def res( params, X, Y, Z ):
th = poly( X, Y, *params )
diff = Z - th
return np.concatenate( diff )
### fit
sol = least_squares( res, x0=7*[0], args=( XX, YY, ZZ ) )
print( sol.x )
### plot it
fig = plt.figure( )
ax = fig.add_subplot( 1, 1, 1, projection="3d" )
ax.scatter( XX, YY, ZZ, color='r' )
ax.plot_surface( XX, YY, poly( XX, YY, *(sol.x) ) )
plt.show()
顺便说一句,这当然是纯线性拟合。所以根据我的另一个 post 的定义,可以这样做:
### fitting:
X = np.concatenate( XX )
Y = np.concatenate( YY )
Z = np.concatenate( ZZ )
VT = np.array( [
np.ones( len(xL) * len(yL) ),
X, X**2, X**3,
Y, Y**2, Y**3
] )
V = np.transpose( VT )
eta = np.dot( VT, Z )
A = np.dot( VT, V )
sol = np.linalg.solve( A, eta )
print( sol )
### plot it
fig = plt.figure( )
ax = fig.add_subplot( 1, 1, 1, projection="3d" )
ax.scatter( XX, YY, ZZ, color='r' )
ax.plot_surface( XX, YY, poly( XX, YY, *(sol) ) )
plt.show()
我在 here
中添加了更多信息