【牛顿迭代法求极小值】

牛顿迭代法求极小值

仅供参考

作业内容与要求

作业内容

作业要求

递交报告 + 代码

编程实现

计算偏导数

故上述非线性方程组的根可能为 f ( x , y ) f(x, y) f(x,y)的极值点,至于是极小值点还是极大值点鞍点,就需要使用微积分中的黑塞矩阵来判断了。

牛顿迭代法求解非线性方程组

带入即可

python编程实现

python 复制代码
# -*- coding: utf-8 -*- 
# 作者: @bushuo 
# 联系方式: **************@qq.com -->

"""
@File    :   main.py
@Time    :   2024/10/02 23:47:07
@Version :   
@Desc    :   数值分析第一次作业
"""

from math import sin, cos, exp

import numpy as np

# 定义匿名函数 fun(x, y)
f = lambda x,y: sin(x**2 + y**2) * exp(-0.1*(x**2 + y**2 + x*y + 2*x))
f1 = lambda x,y: x*cos(x**2 + y**2) - 0.1*(x + 0.5*y + 1)*sin(x**2 + y**2)
f2 = lambda x,y: y*cos(x**2 + y**2)-0.1*(y+0.5*x)*sin(x**2 + y**2)

f1_x = lambda x,y: -2*x**2*sin(x**2 + y**2) - 2*x*(0.1*x + 0.05*y + 0.1)*cos(x**2 + y**2) - 0.1*sin(x**2 + y**2) + cos(x**2 + y**2)
f1_y = lambda x,y: -2*x*y*sin(x**2 + y**2) - 2*y*(0.1*x + 0.05*y + 0.1)*cos(x**2 + y**2) - 0.05*sin(x**2 + y**2)
f2_x = lambda x,y: -2*x*y*sin(x**2 + y**2) - 2*x*(0.05*x + 0.1*y)*cos(x**2 + y**2) - 0.05*sin(x**2 + y**2)
f2_y = lambda x,y: -2*y**2*sin(x**2 + y**2) - 2*y*(0.05*x + 0.1*y)*cos(x**2 + y**2) - 0.1*sin(x**2 + y**2) + cos(x**2 + y**2)


# 定义二阶导

f_x = lambda x,y: 2*x*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*cos(x**2 + y**2) + (-0.2*x - 0.1*y - 0.2)*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2)
f_y = lambda x,y: 2*y*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*cos(x**2 + y**2) + (-0.1*x - 0.2*y)*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2)
f_xx = lambda x,y: -4*x**2*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2) + 4*x*(-0.2*x - 0.1*y - 0.2)*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*cos(x**2 + y**2) + (0.04*(-x - 0.5*y - 1)**2)*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2) - 0.2*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2) + 2*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*cos(x**2 + y**2)
f_xy = lambda x,y: -4*x*y*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2) + 2*x*(-0.1*x - 0.2*y)*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*cos(x**2 + y**2) + 2*y*(-0.2*x - 0.1*y - 0.2)*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*cos(x**2 + y**2) + (-0.1*x - 0.2*y)*(-0.2*x - 0.1*y - 0.2)*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2) - 0.1*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2)
f_yy = lambda x,y: -4*y**2*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2) + 4*y*(-0.1*x - 0.2*y)*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*cos(x**2 + y**2) + (0.04*(-0.5*x - y)**2)*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2) - 0.2*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*sin(x**2 + y**2) + 2*exp(-0.1*x**2 - 0.1*x*y - 0.2*x - 0.1*y**2)*cos(x**2 + y**2)



# 定义函数的雅可比矩阵

def jacobian(x, y):
    J = np.array([[f1_x(x, y), f1_y(x, y)], [f2_x(x, y), f2_y(x, y)]])
    return J


# 定义黑塞矩阵
def hessian(x, y):
    A = f_xx(x, y)
    B = f_xy(x, y)
    C = f_yy(x, y)

    Delta = A * C - B**2

    if Delta > 0:
        if A > 0:
            return "极小值"
        elif A < 0:
            return "极大值"
    elif Delta < 0:
        return "鞍点"
    else:
        return "无法确定"
    



# 牛顿迭代法

def newton_raphson_method(x0, y0, tol=1e-6, max_iter=50):
    x, y = x0, y0
    for i in range(max_iter):
        F1, F2 = f1(x, y), f2(x, y)             # 计算函数值
        J = jacobian(x, y)                      # 计算雅可比矩阵
        J_inv = np.linalg.inv(J)                # 计算雅可比矩阵的逆矩阵
        
        delta = np.dot(J_inv, [[-F1], [-F2]])   # 计算增量 x_{n+1} - x_{n}
        x, y = x + delta[0].item(), y + delta[1].item()       # 更新x, y

        if abs(x) > 2 or abs(y) > 2:
            print("超出求解范围")
            return x, y

        # 输出测试
        # print(f"The root is at x = {x}, y = {y}")

        # 检查收敛性
        if np.linalg.norm(delta) < tol:
            print(f"迭代次数{i + 1}")
            return x, y
        
    print("不收敛")
    return x, y


# 遍历寻找

for x in range(-2, 3):
    for y in range(-2, 3):
        x0, y0 = x, y
        # 执行牛顿迭代法
        root_x, root_y = newton_raphson_method(x0, y0)

        if abs(root_x) < 2 and abs(root_y) < 2:
            
            print(f"初值点({x0}, {y0})  根 x = {root_x}, y = {root_y}, f(x,y) = {f(root_x, root_y)}, {hessian(root_x, root_y)}")

运行结果

txt 复制代码
超出求解范围
超出求解范围
超出求解范围
迭代次数5
初值点(-2, 1)  根 x = -1.8600690102954842, y = 1.111837286123455, f(x,y) = -1.1152578722865378, 极小值
超出求解范围
超出求解范围
超出求解范围
迭代次数8
初值点(-1, 0)  根 x = -1.144748054074812, y = 0.520015824690015, f(x,y) = 1.1392169940140084, 极大值
迭代次数7
初值点(-1, 1)  根 x = -1.1447480540748116, y = 0.5200158246900156, f(x,y) = 1.1392169940140084, 极大值
迭代次数8
初值点(-1, 2)  根 x = -1.8600690102954045, y = 1.111837286123616, f(x,y) = -1.1152578722865376, 极小值
超出求解范围
超出求解范围
迭代次数1
初值点(0, 0)  根 x = 0.0, y = 0.0, f(x,y) = 0.0, 极小值
超出求解范围
超出求解范围
超出求解范围
超出求解范围
超出求解范围
超出求解范围
超出求解范围
超出求解范围
超出求解范围
超出求解范围
迭代次数6
初值点(2, 1)  根 x = 1.8305657416573173, y = 1.0858981122119593, f(x,y) = -0.3553658120767475, 鞍点
超出求解范围

结果

初值点 x y 极值点类型
(-2, 1) x = -1.8600690102954842 y = 1.111837286123455 极小值点
(-1, 0) x = -1.144748054074812 y = 0.520015824690015 极大值点
(-1, 1) x = -1.1447480540748116 y = 0.5200158246900156 极大值点
(-1, 2) x = -1.860069010295404 y = 1.111837286123616 极小值点
(0, 0) x = 0.0 y = 0.0 极小值点
(2, 1) x = 1.8305657416573173 y = 1.0858981122119593 鞍点

MATLAB 绘制函数图像


相关推荐
科雷软件测试32 分钟前
selenium:Select类操作复选框和下拉框(7)
python·selenium·测试工具·ui·自动化
.鱼子酱1 小时前
小猿口算脚本
python·adb·安卓
api茶飘香5 小时前
淘宝商品评论API返回值中的品牌忠诚度评价
开发语言·python·django·flask·virtualenv·pygame·tornado
CV-King6 小时前
openmmlab实现图像超分辨率重构
人工智能·python·深度学习·opencv·计算机视觉·重构
科雷软件测试7 小时前
selenium:ActionChains类模拟鼠标和键盘操作(6)
python·selenium·测试工具·ui·自动化
AI原吾8 小时前
探索未来:picows,Python的AI新宠
开发语言·python·ai·picows
Mr.D学长9 小时前
毕业设计 大数据电影数据分析与可视化系统
python·毕业设计·毕设
宇宙第一小趴菜9 小时前
Python编程:创意爱心表白代码集
python
攻城狮_Dream10 小时前
有哪些推荐的Python学习资源?
开发语言·python·学习
周周写不完的代码10 小时前
JUC-线程池
开发语言·网络·python