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

       最近一个哥们,是用牛顿迭代法求解一个四变量方程组的最优解问题,从网上找了代码去改进,但是总会有点不如意的地方,迭代的次数过多,但是却没有提高精度,真是令人揪心!

       经分析,发现是这个方程组中存在很多局部的极值点,是用牛顿迭代法不能不免进入局部极值的问题,更程序的初始值有关!

       发现自己好久没有是用Matlab了,顺便从网上查了查代码,自己来修改一下!

先普及一下牛顿迭代法:(来自百度百科)

       牛顿迭代法Newton's method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。多数方程不存在求根公式,因此求精确根非常困难,甚至不可能,从而寻找方程的近似根就显得特别重要。方法使用函数f(x)的泰勒级数的前面几项来寻找方程f(x) = 0的根。牛顿迭代法是求方程根的重要方法之一,其最大优点是在方程f(x) = 0的单根附近具有平方收敛,而且该法还可以用来求方程的重根、复根,此时线性收敛,但是可通过一些方法变成超线性收敛。另外该方法广泛用于计算机编程中。

        设r是f(x)=0的根。选取x0作为r的初始近似值,过点(x0,f(x0))做曲线的切线,求出该切线与x轴的交点,并求出该点的横坐标,称作x1是r的一次近似。如此就可以推导出牛顿迭代公式。

         已经证明,如果是连续的,并且待求的零点是孤立的,那么在零点周围存在一个区域,只要初始值位于这个邻近区域内,那么牛顿法必定收敛。 并且,如果不为0, 那么牛顿法将具有平方收敛的性能. 粗略的说,这意味着每迭代一次,牛顿法结果的有效数字将增加一倍。

        在网上查了一些代码,都是能指定某几个函数进行求导的,而且要是改变函数的个数,却又要对原始程序大动干戈。真的是揪心。

        找到了http://hi.baidu.com/aillieo/item/f4d2c4de85af6be954347f25 这个程序,貌似在Matlab上不能很好的运行,对于数据的返回值为空没有做处理,后来又找了一个网易朋友的博客,将他的代码拿过来跑跑,还可以,但是对于不同的函数方程组,以及变量个数就不同了,真的是揪心,这个就是程序设计和编码的问题了!

       自己就拿来改了改,可以支持多方程组和多变量了!下面附上我的代码!求大家指导!

 

function [r,n]=mulNewton(x0,funcMat,var,eps)
% x0为两个变量的起始值,funcMat是两个方程,var为两个方程的两个变量,eps控制精度
% 牛顿迭代法解二元非线性方程组
if nargin==0
    x0 = [0.2,0.6];
    funcMat=[sym('(15*x1+10*x2)-((40-30*x1-10*x2)^2*(15-15*x1))*5e-4')...
             sym('(15*x1+10*x2)-((40-30*x1-10*x2)*(10-10*x2))*4e-2')];
    var=[sym('x1') sym('x2')];
    eps=1.0e-4;
end

n_Var = size(var,2);%变量的个数
n_Func = size(funcMat,2);%函数的个数
n_X = size(x0,2);%变量的个数

if n_X ~= n_Var && n_X ~= n_Func
    fprintf('Expression Error!\n');
    exit(0);
end

r=x0-myf(x0, funcMat, var)*inv(dmyf(x0, funcMat, var));
n=0;
tol=1;
while tol>=eps
    x0=r;
    r=x0-myf(x0, funcMat, var)*inv(dmyf(x0, funcMat, var));
    tol=norm(r-x0);
    n=n+1;
    if(n>100000)
        disp('迭代步数太多,方程可能不收敛');
        return;
    end
end
end % end mulNewton


 

function f=myf(x,funcMat, varMat)
% 输入参数x为两个数值,func为1*2符号变量矩阵,var为1*2符号变量矩阵中的变量
% 返回值为1*2矩阵,内容为数值

n_X = size(x,2);%变量的个数
f_Val = zeros(1,n_X);
for i=1:n_X
    tmp_Var = cell(1,n_X);
    tmp_X = cell(1,n_X);
    for j=1:n_X
        tmp_Var{j} = varMat(1,j);
        tmp_X{j} = x(1,j);
    end
    f_Val(i) = subs(funcMat(1, i), tmp_Var, tmp_X);
end
f=f_Val;
end % end myf

function df_val=dmyf(x, funcMat, varMat)
% 返回值为2*2矩阵,内容为数值
%df=[df1/x1, df1/x2;
%    df2/x1. df2/x2];
n_X = size(x,2);%变量的个数
df =cell(n_X, n_X);
for i=1:n_X
    for j=1:n_X
        df{i,j} = diff(funcMat(1, i), varMat(1, j));
    end
end

df_val=zeros(n_X, n_X);

for i=1:n_X
    for j=1:n_X
        tmp_Var = cell(1,n_X);
        tmp_X = cell(1,n_X);
        for k=1:n_X
            tmp_Var{k} = varMat(1,k);
            tmp_X{k} = x(1,k);
        end
        df_val(i,j) = subs(df{i,j}, tmp_Var, tmp_X);
    end
end
end % end dmyf
  • 42
    点赞
  • 152
    收藏
    觉得还不错? 一键收藏
  • 44
    评论
### 回答1: 牛顿迭代法是一种求解线性方程组的方法,可以用于MATLAB编程。具体步骤如下: 1. 定义线性方程组,例如: f1 = @(x) x(1)^2 + x(2)^2 - 1; f2 = @(x) x(1) - x(2)^2; 2. 定义初始值和迭代次数: x = [1;1]; max_iter = 100; 3. 编写牛顿迭代法的主函数: function [x, iter] = newton(f, x, max_iter, tol) % f: 线性方程组 % x: 初始值 % max_iter: 最大迭代次数 % tol: 收敛精度 iter = ; x = x; while iter < max_iter iter = iter + 1; J = jacobian(f, x); % 计算雅可比矩阵 delta_x = -J\f(x); % 计算增量 x = x + delta_x; % 更新x if norm(delta_x) < tol % 判断是否收敛 break; end end 4. 调用主函数求解线性方程组: f = @(x) [x(1)^2 + x(2)^2 - 1; x(1) - x(2)^2]; [x, iter] = newton(f, x, max_iter, 1e-6); 其中,f为线性方程组,x为初始值,max_iter为最大迭代次数,1e-6为收敛精度。函数返回值x为方程组的解,iter为实际迭代次数。 ### 回答2: Matlab是一种强大的数学软件,在解决线性方程组的问题时,可以使用牛顿迭代法求解。下面是关于Matlab牛顿迭代法求解线性方程组的具体介绍。 牛顿迭代法是一种求解线性方程的方法,其主要思想是利用函数在某一点的一阶或二阶导数信息,来逼近方程的根。具体来说,牛顿迭代法需要从初始猜测点开始迭代,不断使用局部一阶或二阶泰勒展开式来定义下一个猜测点,直至收敛到方程的解。 下面介绍在Matlab中如何利用牛顿迭代法求解线性方程组。首先需要定义函数的符号表达式,在Matlab中可以使用以下命令进行定义: syms x y z f1 = x^2 + y^2 + z^2 - 25; f2 = x*y + x*z - 8; f3 = y*z - 3; 上述代码定义了三个未知数的线性方程组,其中f1、f2和f3是每个未知数对应的方程。 接下来需要定义初始的猜测点,以及迭代的最大次数和允许的收敛精度。在Matlab中可以使用以下代码进行定义: x0 = [1;1;1]; % 初始猜测点 n_max = 100; % 迭代最大次数 tol = 1e-6; % 允许的收敛精度 然后,我们需要定义牛顿迭代法的迭代公式。在Matlab中,请使用以下代码进行定义: F = [f1;f2;f3]; J = jacobian(F,[x y z]); % 求解雅可比矩阵 iter = 1; while iter < n_max Jn = double(subs(J,[x y z],x0.')); % 计算雅可比矩阵在当前猜测点的值 Fn = double(subs(F,[x y z],x0.')); % 计算函数向量在当前猜测点的值 xn = x0 - Jn\Fn; % 牛顿迭代公式 if norm(xn - x0) <= tol % 检查收敛精度 break; end x0 = xn; % 记录当前猜测点 iter = iter + 1; % 迭代次数加1 end 在上述代码中,首先使用subs函数将x、y和z替换为当前的猜测点,得到雅可比矩阵和函数值。然后使用牛顿迭代公式得到下一个猜测点,并在下一次迭代时继续执行。如果达到了最大迭代次数或者精度达到了要求,则终止迭代。 最后,我们可以使用以下代码来输出求解结果: if iter < n_max fprintf('Converged to solution after %d iterations:\n', iter); disp(xn); else fprintf('Failed to converge after %d iterations:\n', n_max); end 该代码将输出求解结果,并指示是否成功达到了要求的精度。 总结来说,Matlab可以很容易地实现牛顿迭代法求解线性方程组的问题。通过定义函数表达式、初始猜测点、迭代公式以及收敛精度,可以在Matlab中执行快速的线性方程组求解。 ### 回答3: matlab作为一种常用的数学软件,在求解线性方程组中有着广泛的应用。其中牛顿迭代法是解决线性方程组的一种常见方法。 牛顿迭代法是一种逐步逼近的迭代方法,其基本思想是利用函数在某一点的导数(或者偏导数)来构造一个逼近方程,然后根据逼近方程不断迭代,从而达到求解线性方程组的目的。 在使用matlab求解线性方程组时,可以利用matlab提供的牛顿迭代法函数进行计算。该函数的输入参数包括一个含有n个元素的初始猜测向量x,一个n×1的函数值向量f(x),一个n×n的雅可比矩阵J(x),以及一些其他的可选参数。其中,雅可比矩阵J(x)是对函数f(x)的一阶导数矩阵。 具体实现时,可以首先定义线性方程组的函数形式和雅可比矩阵,然后通过调用matlab中的牛顿迭代法函数进行求解。通过不断迭代,可以逐渐得到线性方程组的解,并可以控制精度和迭代次数等参数。 需要注意的是,在使用牛顿迭代法求解线性方程组时,函数必须是具有可导性的,否则无法计算函数的导数,从而无法迭代求解。此外,在实际应用中,由于牛顿迭代法存在收敛性的限制和局部最优解的问题,需要对结果进行验证和分析,以确保得到的解在实际应用中具有合理性和可行性。 总的来说,通过在matlab中使用牛顿迭代法求解线性方程组,可以方便、快捷地得到高精度的解,拓展了线性方程组求解的方法和途径,并在多个领域的应用中发挥了重要作用。
评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值