Matlab 用Newton-Raphson和Gauss-Seidel求解非线性系统

Matlab 用Newton-Raphson和Gauss-Seidel求解非线性系统,matlab,Matlab,我需要帮助了解如何结合牛顿-拉斐逊和高斯-赛德尔方法在Matlab中求解非线性方程组。这是我的逻辑: 通过求方程的导数将系统线性化,并放入矩阵中。转移系统,使我们有[偏导数矩阵][H]=[原始系统],其中H是我要求解的。H是步长 首先将对x的初始猜测插入到第一个和最后一个矩阵中,然后每次解H时,我都会将该步长添加到对x的先前猜测中,以创建一个新的x。然后我将插入更新的x,找到另一个h,并继续这个过程 每次迭代在新旧猜测之间都有一个错误。当误差小于公差时,报告值 我以前对牛顿-拉斐逊法和高斯-赛德

我需要帮助了解如何结合牛顿-拉斐逊和高斯-赛德尔方法在Matlab中求解非线性方程组。这是我的逻辑:

  • 通过求方程的导数将系统线性化,并放入矩阵中。转移系统,使我们有[偏导数矩阵][H]=[原始系统],其中H是我要求解的。H是步长
  • 首先将对x的初始猜测插入到第一个和最后一个矩阵中,然后每次解H时,我都会将该步长添加到对x的先前猜测中,以创建一个新的x。然后我将插入更新的x,找到另一个h,并继续这个过程
  • 每次迭代在新旧猜测之间都有一个错误。当误差小于公差时,报告值 我以前对牛顿-拉斐逊法和高斯-赛德尔法分别进行过编码。 我的主要困惑来自于如何准确地将两个不同的变量组合在一起。首先,我想知道我的逻辑是否正确,对于这种设置的psedoocode将非常有用


    我试着编写代码,我相信矩阵是正确的,我认为Gauss-Seidel函数是正确的,但是我对如何正确地更新猜测感到非常困惑。现在,一旦我消除了错误,它就会输出一个0的迭代。我被告知对线性方程做一个[0,0]的猜测,对非线性方程做一个[2,2]的猜测。基本上,我不知道如何将牛顿·拉斐逊融入其中。我以前编写过NR方法,但只使用了1个变量,因此我不知道如何将此逻辑转换为此代码。下面是我的单独的牛顿-拉斐逊代码:

    您的思路是正确的,但是我们可以在代码中改进一些地方:

  • 首先,请注意,牛顿-拉夫森法和高斯-赛德尔法都是求解方程组的数值方法。不惜一切代价避免使用符号变量。它不仅速度慢得多,而且不能解决所有的数值问题
  • 使用和滥用MATLAB语法来处理矩阵和向量
  • 您的问题是将牛顿-拉斐逊和高斯-赛德尔解算器耦合起来。我不会解决整个问题,正如你所说的,你的高斯赛德尔似乎在工作

    我还将稍微更改您提供的一些符号,以便您能够充分了解MATLAB易于使用的语法


    非线性方程组:

    所提供的数据可以矢量形式书写为:

    function fx = F(x)
        fx = zeros(2,1); % pre-allocate to create a column-vector
        fx(1) = x(1)-x(2)+1;
        fx(2) = x(1)^2+x(2)^2-4;
    end
    
    这将创建列向量函数
    F
    ,作为变量
    x1
    (x)和
    x2
    (y)的函数

    Newton-Raphson算法需要。你需要计算这些导数。这些功能很简单,因此您可以手动执行。创建一个函数以计算作为变量函数的雅可比矩阵

    function J = jacob(x)
        J = zeros(2,2);
        J(1,1) = 1; % df/dx
        J(1,2) = -1; % df/dy
        J(2,1) = 2*x(1); % dg/dx
        J(2,2) = 2*x(2); % dgdy
    end
    
    你对牛顿-拉斐逊的逻辑是正确的。让我们用它来编码我们的牛顿·拉斐逊:

    function x = newton(fun,jacobian,x0)
        % This function uses the Newton-Raphson method to find a root for the
        % nonlinear system of equations F, with jacobian J, given an initial
        % estimate x0.
    
        % Here we take advantage of MATLAB syntax to easily implement our
        % routine. fun and jacobian are function handles to the equations and 
        % its derivatives. So it is computationally much more efficient to use
        % it instead of working with symbolic variables.
    
        % Following the steps you provided and the Newton-Raphson for one variable:
        TOL = 0.00001;
        MAXITER = 100;
    
        err = 1;
        iter = 0;
        x = x0;
        while err>TOL && iter<MAXITER % repeat until error is smaller than tolerance
            % step 1: linearize the system
            fx = fun(x);
            J = jacobian(x);
            % notice that the system is already in matrix form.
    
            % ********************************************* %
            % step 1.2: solve for stepsize H              * %
            H = -J\fx; % SOLVE LINEAR SYSTEM OF EQUATIONS * %
            % ********************************************* %
    
            % step 2: add stepsize to the previous guess of x
            x = x+H;
    
            % step 3: calculate error
            err = norm(H);
        end
    end
    
    我们的函数与MATLAB的内置函数之间的差异非常小。看来该功能可以正常工作

    请注意上面突出显示的步骤1.2。这是重要的一步。在这一步中,我使用MATLAB齿隙操作符来求解线性系统Ax=b。以下语句具有相同的功能():

    如果你必须使用高斯-赛德尔方法来求解线性方程组,我将把这些修改留给你去做。在步骤1.2中,您将更改Gauss-Seidel函数的齿隙运算符:

    H = -J\fx;
    H = gaussSeidel(-J,fx);
    
    function x = gaussSeidel(A,b)
        % Solves the system of linear equations Ax=b by the Gauss-Seidel
        % method.
        %
        % ...
        %
    end
    
    并正确编写
    gausseidel
    函数(在函数中转换代码):


    这应该可以解决问题。

    如果您以前编写过代码,那么将其全部放在一起应该不会太难。你可以向我们提供你所做的一切。基本上,Newton-Raphson方法设置迭代[J]*{DeltaX}=-{F}。必须提供雅可比矩阵(矩阵o偏导数)和函数[原始系统]。这形成了Ax=b型线性方程组。要求解线性系统,请调用Gauss-Seidel例程以迭代方式求解。伪代码看起来不错。试着把它们放在一起,给我们一个看似完美的开场白。@Thales我照你说的做了,并用我尝试过的代码更新了我的帖子,它成功了!非常感谢你!我真的很感激。有一点,我有点困惑,为什么在Jacob函数的J(2,2)中加上y。我把它改成了x(2),让它为我工作。除此之外,谢谢你的评论。它真的帮助我理解了如何有效地使用Matlab:)对不起,错别字了,只是把它修好了!
    x = A\B
    x = mldivide(A,B)
    
    H = -J\fx;
    H = gaussSeidel(-J,fx);
    
    function x = gaussSeidel(A,b)
        % Solves the system of linear equations Ax=b by the Gauss-Seidel
        % method.
        %
        % ...
        %
    end