—编程用牛顿法解方程 x*e**x-1=0,初始点和终止准则等自行选择。
import numpy as np
from numpy import sign
import sympy as sp
import easygui as g
def fun(x):
f=x*sp.exp(x)-1
return f
m=0
def ds_judge(a,b,fun):
global m
x=sp.symbols("x")
ds1=fun(x).diff(x)
ds2=sp.diff(ds1,x)
ds1fza=float(ds1.evalf(subs={x:a}))
ds1fzb=float(ds1.evalf(subs={x:b}))
ds2fza=float(ds2.evalf(subs={x:a}))
ds2fzb=float(ds2.evalf(subs={x:b}))
if (ds1fza * ds2fza) >0 and (ds1fzb * ds2fzb) >0 :
m=1
print("在[%f,%f]内任选的初值可以使牛顿法生成的数列收敛到区间内的解,是一个严格递减有下界的数列。"%(a,b))
elif (ds1fza * ds2fza) <0 and (ds1fzb * ds2fzb) <0 :
m=1
print("在[%f,%f]内任选的初值可以使牛顿法生成的数列收敛到区间内的解,是一个严格递减有上届的数列。"%(a,b))
else:
m=2
print("不能断定在[%f,%f]内任选的初值可以使牛顿法生成的数列收敛到区间内的解,可以考虑缩小定义域。"%(a,b))
def nd_method(a,b,x0,esp,fun,ds_judge):
"""
a<b
x0为选定的初值
esp为所选定的误差限
fun为初始的函数
ds_judge为导数判断和区间的判断
"""
flag=0
n=0
x=sp.symbols("x")
if sign(fun(a)) ==0: return a
if sign(fun(b)) ==0: return b
if sign(fun(a))*sign(fun(b))>0: return print("该区间内没有根,请重新换区间!")
ds_judge(a,b,fun)
if m==1:
flag=1
if m==2: return print("请重新更换区间!")
while flag:
n +=1
ds1=fun(x).diff(x)
ds1fz=float(ds1.evalf(subs={x:x0}))
y=x0-(fun(x0) / ds1fz)
if abs(y-x0)<esp:
break
x0=y
result="{0:.8f}".format(y)
return g.msgbox("该函数的解为:%s,共迭代 %d次" %(result,n),"牛顿法","No Problem!")
nd_method(0,0.6,0.6,1e-8,fun,ds_judge)