# python------牛顿法求解

—编程用牛顿法解方程 x*e**x-1=0,初始点和终止准则等自行选择。

#---编程用牛顿法解方程 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
    #f=7*x**5-13*x**4-21*x**3-12*x**2+58*x+3
    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}))   #ds1fza---导数1赋值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)
#nd_method(1,2,1.5,1e-8,fun,ds_judge)


        
        


    

    
    

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牛顿法是一种数值优化方法,可以用于求解非线性回归。它的基本思想是利用二阶泰勒展开来近似目标函数,然后求解近似函数的极值点。在非线性回归问题中,目标函数通常是似然函数或者残差平方和,其中包含了未知参数。通过牛顿法求解非线性回归,可以得到最优的参数估计。 下面是一个使用牛顿法求解非线性回归的示例代码: ```python import numpy as np # 定义目标函数,这里使用的是一个简单的非线性回归模型 def f(x, a, b): return a * x + b * x ** 2 # 定义求导函数,这里使用的是目标函数的一阶和二阶导数 def df(x, a, b): return np.array([a + 2 * b * x, 2 * b * np.ones_like(x)]) # 定义牛顿法求解函数 def newton_method(x0, f, df, max_iter=100, tol=1e-6): x = x0 for i in range(max_iter): # 计算当前点的一阶和二阶导数 grad = df(x[0], *x[1:]) hess = np.diag(df(x[0], *x[1:])) # 计算牛顿方向和步长 d = -np.linalg.solve(hess, grad) alpha = 1.0 # 进行线搜索,找到最优的步长 while f(x[0] + alpha * d[0], *x[1:]) > f(x[0], *x[1:]) + alpha * 0.5 * grad.dot(d): alpha *= 0.5 # 更新参数估计值 x_new = x + np.hstack((alpha * d[0], d[1:])) # 判断是否满足收敛条件 if np.linalg.norm(x_new - x) < tol: break x = x_new return x # 生成样本数据 np.random.seed(0) x = np.linspace(-5, 5, 100) y = f(x, 2, 3) + np.random.normal(scale=0.5, size=100) # 利用牛顿法求解非线性回归问题 x0 = np.array([0, 1, 1]) params = newton_method(x0, lambda a, b, c: np.sum((y - f(x, a, b)) ** 2), lambda a, b, c: np.array([2 * np.sum(y - f(x, a, b)), -2 * np.sum((y - f(x, a, b)) * x), -2 * np.sum((y - f(x, a, b)) * x ** 2)])) print(params) ``` 在上述代码中,首先定义了目标函数 `f` 和求导函数 `df`。然后,定义了牛顿法求解函数 `newton_method`,其中包括了计算一阶和二阶导数、计算牛顿方向和步长、进行线搜索、更新参数值等步骤。最后,利用样本数据和牛顿法求解函数,得到了最优的参数估计。 需要注意的是,牛顿法有可能会出现收敛不稳定的情况,因此在实际应用中需要进行一定的调参和验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值