自然な 3 次スプラインの最小値を見つけようとしています。自然な 3 次スプラインを見つけるために、次のコードを作成しました。(私はテスト データを受け取り、この方法が正しいことを確認しました。) 今、この関数の最小値を見つける方法がわかりません。
これがデータです
xdata = np.linspace(0.25, 2, 8)
ydata = 10**(-12) * np.array([1,2,1,2,3,1,1,2])
これが機能です
import scipy as sp
import numpy as np
import math
from numpy.linalg import inv
from scipy.optimize import fmin_slsqp
from scipy.optimize import minimize, rosen, rosen_der
def phi(x, xd,yd):
n = len(xd)
h = np.array(xd[1:n] - xd[0:n-1])
f = np.divide(yd[1:n] - yd[0:(n-1)],h)
q = [0]*(n-2)
for i in range(n-2):
q[i] = 3*(f[i+1] - f[i])
A = np.zeros(((n-2),(n-2)))
#define A for j=0
A[0,0] = 2*(h[0] + h[1])
A[0,1] = h[1]
#define A for j = n-2
A[-1,-2] = h[-2]
A[-1,-1] = 2*(h[-2] + h[-1])
#define A for in the middle
for j in range(1,(n-3)):
A[j,j-1] = h[j]
A[j,j] = 2*(h[j] + h[j+1])
A[j,j+1] = h[j+1]
Ainv = inv(A)
B = Ainv.dot(q)
b = (n)*[0]
b[1:(n-1)] = B
# now we find a, b, c and d
a = [0]*(n-1)
c = [0]*(n-1)
d = [0]*(n-1)
s = [0]*(n-1)
for r in range(n-1):
a[r] = 1/(3*h[r]) * (b[r + 1] - b[r])
c[r] = f[r] - h[r]*((2*b[r] + b[r+1])/3)
d[r] = yd[r]
#solution 1 start
for m in range(n-1):
if xd[m] <= x <= xd[m+1]:
s = a[m]*(x - xd[m])**3 + b[m]*(x-xd[m])**2 + c[m]*(x-xd[m]) + d[m]
return(s)
#solution 1 end
xdata のドメインで最小値を見つけたいので、そこで境界を定義できないため、fmin は機能しませんでした。fmin_slsqp と最小化の両方を試しました。phi
それらは私が書いた関数と互換性がないので、書き直しphi(x, xd,yd)
て phi が となるような変数を追加しましたphi(x, xd,yd, m)
。M は、解を計算しているスプラインのサブ関数 (x_m から x_m+1 まで) を示します。#solution 1
コードでは、次のように置き換えました
# solution 2 start
return(a[m]*(x - xd[m])**3 + b[m]*(x-xd[m])**2 + c[m]*(x-xd[m]) + d[m])
# solution 2 end
ドメイン x_m から x_(m+1) の最小値を見つけるには、次のコードを使用します: (m=0 のインスタンスを使用するため、x は 0.25 から 0.5 です。最初の推定値は 0.3 です)
fmin_slsqp(phi, x0 = 0.3, bounds=([(0.25,0.5)]), args=(xdata, ydata, 0))
私が次に行うことは(大まかであることはわかっています)、これを for ループで繰り返して、すべてのサブドメインの最小値を見つけてから、全体の最小値を取ります。ただし、関数fmin_slsqp
は常に初期推定を最小値として返します。そのため、修正方法がわからない問題があります。あなたが私を助けることができれば、これは大歓迎です。ここまで読んでくれてありがとう。