非线性方程组求解方法及python代码实现

前言

工作中,遇到工程上的一个四元的非线性方程组需要求解,经过各路大神的协助,终将该问题解决,在此进行记录,同时也写给需要的你们。

一、问题描述

在这里插入图片描述

二、求解算法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、代码实现
import numpy as np
from sympy import symbols, diff
from scipy import linalg
import pandas as pd

def fun(x, points):
    """
    求方程组(值表示)在点x处的值
    :param x: 数值解点
    :param points: 给定点(和值,测试时用)
    :return:
    """
    f = np.zeros(4, dtype=float)
    f[0] = x[0] * (x[1] + points['t1']) ** x[3] - points['u1']
    f[1] = x[0] * (x[1] + points['t1'] + x[2]) ** x[3] - points['u2']
    f[2] = x[0] * (x[1] + points['t2']) ** x[3] - points['u3']
    f[3] = x[0] * (x[1] + points['t2'] + x[2]) ** x[3] - points['u4']

    return f

def fun_dfun(x, points):
    """
    方程组和jacobi矩阵(符号表示)及其在点x处的值
    :param x: 分量分别是未知数的一组值
    :param points: 给定点(和值,测试时用)
    :return: 方程组
    """
    # 未知数符号
    G = symbols('G')
    R = symbols('R')
    N = symbols('N')
    alpha = symbols('alpha')

    # 非线性方程组(符号表示)
    f = []
    f.append(G * (R + points['t1']) ** alpha - points['u1'])
    f.append(G * (R + points['t1'] + N) ** alpha - points['u2'])
    f.append(G * (R + points['t2']) ** alpha - points['u3'])
    f.append(G * (R + points['t2'] + N) ** alpha - points['u4'])

    # 求Jacobi矩阵(符号表示形式)
    df = []
    for i in range(4):
        df.append([diff(f[i], G), diff(f[i], R), diff(f[i], N), diff(f[i], alpha)])

    f_x, df_x = np.zeros(4, dtype=float), np.zeros((4, 4), dtype=float)
    # 方程组和Jacobi矩阵的值
    for i in range(4):
        f_x[i] = float(f[i].evalf(subs={G: x[0], R: x[1], N: x[2], alpha: x[3]}))  # 值代入方程中
    for i in range(4):
        for j in range(4):
            df_x[i][j] = float(df[i][j].evalf(subs={G: x[0], R: x[1], N: x[2], alpha: x[3]}))  # 值带入Jacobi矩阵中
    # df_1x = np.linalg.inv(np.array(df_x))   # Jacobi矩阵得逆, 太耗时

    return f_x, df_x

def newton(x, points):
    """
    用牛顿迭代法求解最优值
    :param x: 初始值
    :param points: 给定点(和值,测试时用)
    :return: 最优值
    """

    count = 1
    while count < 1000:
        f_x, df_x = fun_dfun(x, points)
        delta_x = linalg.solve(df_x, -f_x)  # 求解线性方程组
        x1 = x + delta_x
        error = np.sum(np.square(fun(x1, points)))  # 迭代中两次值得欧氏距离
        if error > 1e-8:
            x = x1
            count += 1
        else:
            break
    if count < 1000:
        print("迭代次数为:      ", count)
        print("G的最优解为:    ", x[0])
        print("R的最优解为:    ", x[1])
        print("N的最优解为:    ", x[2])
        print("alpha的最优解为:", x[3])
    else:
        print("迭代失败")

    return x
四、测试
def main():
    # 测试用例
    t = [1, 2, 4, 5]
    u = [2 * (4 + i) ** 0.7 for i in t]   # G: 2, N: 1, R:3, alpha:0.7
    points = {}
    points['t1'] = t[0]
    points['t2'] = t[2]
    points['u1'] = u[0]
    points['u2'] = u[1]
    points['u3'] = u[2]
    points['u4'] = u[3]

    x = np.ones(4, dtype=float)  # 初值
    a = newton(x, points)
    print(a)

测试结果如下:
在这里插入图片描述

END
参考资料

-(需要补)

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值