用Python实现内推外插法
"""
Author: Z
Date: 2015-12-3
"""
import numpy as np
class node(object):
def __init__(self):
self.power = []
self.a = []
def set(self,ar,p):
for i in xrange(len(ar)):
self.a.append(ar[i])
self.power.append(p[i])
def printf(self):
print 'a[] is: ',
for i in xrange(np.array(self.a).shape[0]):
print self.a[i],
print ' '
print 'power[] is: ',
for i in xrange(np.array(self.power).shape[0]):
print self.power[i],
print ' '
>>>>>#### base function area >>>>#
def parse(self,string):
"""
parse str "string" into list "a" and "power"
"a" means the factor of x
"power" means the index of x
"""
self.power = []
self.a = []
string = place(' ','')
eq = string.find('=')
new_string = string[(eq+1):]
index = new_string.find('x')
while(index != -1):
if new_string[index-1]=='*' and new_string[index-2].isdigit():
i = index-2
num = ""
while i>=0 and new_string[i].isdigit():
num = new_string[i] + num
i = i - 1
if i>=0 and new_string[i] == '-':
num = '-' + num
self.a.append(float(num))
else:
self.a.append(1.)
if new_string[index+1] == '^':
num = 0.
i = index + 2
while i<len(new_string) and new_string[i].isdigit():
num = 10*num + float(new_string[i])
i = i + 1
self.power.append(num)
else:
self.power.append(1.)
index = new_string.find('x',index+1)
if new_string[-1] != 'x':
ll = len(new_string) - 1
num = ""
while ll>=0 and new_string[ll].isdigit():
num = new_string[ll] + num
ll = ll - 1
if ll >= 0 and new_string[ll] == '-':
num = '-' + num
self.a.append(float(num))
self.power.append(0.)
def get_fun_value(self,num):
ret = 0.
for i in xrange(np.array(self.a).shape[0]):
ret += self.a[i] * pow(num,self.power[i])
return ret
>>>>### tool function area >>####
def Min_push_forward(self,start,step):
_fun_value(start) < _fun_value(start + step):
step_len = -1*step
x1 = start
x2 = start + step
y2 = _fun_value(x2)
while True:
x3 = x2 + step
y3 = _fun_value(x3)
if y2 > y3:
x1 = x2
x2 = x3
else:
break
return x1,x3
def Min_insert_forword(self,lef,rig,max_epochs,min_error):
epoch = 0
while True:
mid1 = (3.*lef - rig)/2.
mid2 = (lef + rig)/2.
y1 = _fun_value(mid1)
y2 = _fun_value(lef)
y3 = _fun_value(mid2)
y4 = _fun_value(rig)
if y1 <=y2 and y1 <=y3 and y1<=y4:
lef = mid1
rig = lef
elif y2<=y1 and y2<=y3 and y2<=y4:
lef = mid1
rig = mid2
elif y3<=y4 and y3<=y1 and y3<=y2:
lef = lef
rig = rig
else:
lef = mid2
rig = rig
epoch += 1
if epoch >= max_epochs or (rig-lef)<=min_error:
break
x = (lef + rig)/2.
y = _fun_value(x)
return x,y
def Max_push_forward(self,start,step):
_fun_value(start) > _fun_value(start + step):
step_len = -1*step
x1 = start
x2 = start + step
y2 = _fun_value(x2)
while True:
x3 = x2 + step
y3 = _fun_value(x3)
if y2 < y3:
x1 = x2
x2 = x3
else:
break
return x1,x3
def Max_insert_forword(self,lef,rig,max_epochs,min_error):
epoch = 0
while True:
mid1 = (3.*lef - rig)/2.
mid2 = (lef + rig)/2.
y1 = _fun_value(mid1)
y2 = _fun_value(lef)
y3 = _fun_value(mid2)
y4 = _fun_value(rig)
if y1>=y2 and y1>=y3 and y1>=y4:
lef = mid1
error parse new rig = lef
elif y2>=y1 and y2>=y3 and y2>=y4:
lef = mid1
rig = mid2
elif y3>=y4 and y3>=y1 and y3>=y2:
lef = lef
rig = rig
else:
lef = mid2
rig = rig
epoch += 1
if epoch >= max_epochs or (rig-lef)<=min_error:
break
x = (lef + rig)/2.
y = _fun_value(x)
return x,y
def min_fun(self,start,step,max_epochs,min_error):
[lef,rig] = self.Min_push_forward(start,step)
x,y = self.Min_insert_forword(lef,rig,max_epochs,min_error)
print 'x: ',x
print 'y: ',y
def max_fun(self,start,step,max_epochs,min_error):
[lef,rig] = self.Max_push_forward(start,step)
x,y = self.Max_insert_forword(lef,rig,max_epochs,min_error)
print 'x: ',x
print 'y: ',y
if __name__ == '__main__':
ss = 'f(x) = x^3 - 2*x + 1'
a = node()
a.parse(ss)
a.printf()
max_epochs = 1000
min_error = 0.001
start = 0.0
step = 0.2
a.min_fun(start,step,max_epochs,min_error)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
vant实现select效果,单选和多选
« 上一篇
发表评论