# -*- coding: UTF-8 -*-
from math import *
import numpy as np
##########################################
# 多項式近似(関数の最小値)
# x0 : 初期値
# d0 : 初期ステップ
# eps : 許容誤差
# val : 間数値
# ind : 計算状況
# >= 0 : 正常終了(収束回数)
# = -1 : 収束せず
# max : 最大試行回数
# fun : 関数値を計算する関数の名前
# return : 結果
# coded by Y.Suganuma
##########################################
def approx(x0, d0, eps, val, ind, max, fun) :
x = np.empty(4, np.float)
f = np.empty(4, np.float)
xx = 0.0
k = 0
count = 0
d = d0
x[1] = x0
f[1] = fun(x0)
ind[0] = -1
while count < max and ind[0] < 0 :
x[3] = x[1] + d
f[3] = fun(x[3])
while k < max and f[3] <= f[1] :
k += 1
d *= 2.0
x[0] = x[1]
f[0] = f[1]
x[1] = x[3]
f[1] = f[3]
x[3] = x[1] + d
f[3] = fun(x[3])
# 初期値が不適当
if k >= max :
count = max
else :
# 3点の選択
sw = 0
if k > 0 :
x[2] = x[3] - 0.5 * d
f[2] = fun(x[2])
min = -1
for i1 in range(0, 4) :
if min < 0 or f[i1] < f[min] :
min = i1
if min >= 2 :
for i1 in range(0, 3) :
x[i1] = x[i1+1]
f[i1] = f[i1+1]
sw = 1
else :
x[0] = x[1] - d0
f[0] = fun(x[0])
if f[0] > f[1] :
x[2] = x[3]
f[2] = f[3]
sw = 1
else :
x[1] = x[0]
f[1] = f[0]
d0 = -d0
d = 2.0 * d0
k = 1
# 収束?
if sw > 0 :
count += 1
dl = 0.5 * d * (f[2] - f[0]) / (f[0] - 2.0 * f[1] + f[2])
xx = x[1] - dl
val[0] = fun(xx)
if abs(dl) < eps :
ind[0] = count
else :
k = 0
d0 = 0.5 * d
d = d0
if val[0] < f[1] :
x[1] = xx
f[1] = val[0]
return xx
----------------------------------
# -*- coding: UTF-8 -*-
import numpy as np
import sys
from math import *
from function import approx
############################################
# 多項式近似によるy=x^4+3x^3+2x^2+1の最小値
# coded by Y.Suganuma
############################################
###############
# 関数値の計算
###############
def snx(x) :
return x * x * x * x + 3.0 * x * x * x + 2.0 * x * x + 1.0
# 設定と実行
x = -3.0
d = 0.1
eps = 1.0e-7
max = 100
val = np.empty(1, np.float)
ind = np.empty(1, np.int)
x = approx(x, d, eps, val, ind, max, snx)
print("x " + str(x) + " val " + str(val[0]) + " ind " + str(ind[0]))