Matlab 用Newton-Raphson和Gauss-Seidel求解非线性系统
我需要帮助了解如何结合牛顿-拉斐逊和高斯-赛德尔方法在Matlab中求解非线性方程组。这是我的逻辑:Matlab 用Newton-Raphson和Gauss-Seidel求解非线性系统,matlab,Matlab,我需要帮助了解如何结合牛顿-拉斐逊和高斯-赛德尔方法在Matlab中求解非线性方程组。这是我的逻辑: 通过求方程的导数将系统线性化,并放入矩阵中。转移系统,使我们有[偏导数矩阵][H]=[原始系统],其中H是我要求解的。H是步长 首先将对x的初始猜测插入到第一个和最后一个矩阵中,然后每次解H时,我都会将该步长添加到对x的先前猜测中,以创建一个新的x。然后我将插入更新的x,找到另一个h,并继续这个过程 每次迭代在新旧猜测之间都有一个错误。当误差小于公差时,报告值 我以前对牛顿-拉斐逊法和高斯-赛德
我试着编写代码,我相信矩阵是正确的,我认为Gauss-Seidel函数是正确的,但是我对如何正确地更新猜测感到非常困惑。现在,一旦我消除了错误,它就会输出一个0的迭代。我被告知对线性方程做一个[0,0]的猜测,对非线性方程做一个[2,2]的猜测。基本上,我不知道如何将牛顿·拉斐逊融入其中。我以前编写过NR方法,但只使用了1个变量,因此我不知道如何将此逻辑转换为此代码。下面是我的单独的牛顿-拉斐逊代码:您的思路是正确的,但是我们可以在代码中改进一些地方:
非线性方程组: 所提供的数据可以矢量形式书写为:
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