【问题标题】:How to use Newton-Raphson method in matlab to find an equation root?如何在matlab中使用Newton-Raphson方法找到方程根?
【发布时间】:2011-12-03 19:49:23
【问题描述】:

我是 MATLAB 的新用户。我想使用 Newton-Raphson 方法找到生成 f(x) = 0 的值。我曾尝试编写代码,但似乎很难实现 Newton-Raphson 方法。这是我目前所拥有的:

function x = newton(x0, tolerance)
    tolerance = 1.e-10;
    format short e;
    Params = load('saved_data.mat');
    theta = pi/2;
    zeta = cos(theta);
    I = eye(Params.n,Params.n);
    Q = zeta*I-Params.p*Params.p';

    % T is a matrix(5,5)
    Mroot = Params.M.^(1/2);  %optimization
    T = Mroot*Q*Mroot;

    % Find the eigenvalues
    E = real(eig(T));

    % Find the negative eigenvalues
    % Find the smallest negative eigenvalue
    gamma = min(E);  

    % Now solve for lambda
    M_inv = inv(Params.M);  %optimization
    zm = Params.zm;

    x = x0;
    err = (x - xPrev)/x;

    while abs(err) > tolerance
        xPrev = x;
        x = xPrev - f(xPrev)./dfdx(xPrev);

        % stop criterion: (f(x) - 0) < tolerance
        err = f(x);
   end 

   % stop criterion: change of x < tolerance % err = x - xPrev;

end

上面的函数是这样使用的:

% Calculate the functions
Winv = inv(M_inv+x.*Q);

f = @(x)( zm'*M_inv*Winv*M_inv*zm);

dfdx = @(x)(-zm'*M_inv*Winv*Q*M_inv*zm);

x0 = (-1/gamma)/2;

xRoot = newton(x0,1e-10);

【问题讨论】:

  • 那么,问题是什么?您只需显示您的代码...
  • 我需要修复代码以使其正常工作。
  • 你得到什么样的输出?您的哪些功能似乎不适用于fzero()
  • 它给出了以下错误:???错误使用 ==> fzero 区间端点处的函数值必须是有限且实数的“”。我认为这是因为等式中有复杂的条目。
  • @user1079331 你能告诉我们Params.nParams.pParams.M等是什么吗?那么我们更有可能帮助您调试您的问题。

标签: function matlab


【解决方案1】:

这个问题不是特别清楚。但是,您是否需要自己实现根查找?如果不是,那么只需使用 Matlab 的内置函数 fzero(不是基于 Newton-Raphson)。

如果您确实需要自己实现 Newton-Raphson 方法,那么我建议您使用Newton Raphsons method in Matlab? 的答案之一作为您的起点。

编辑:以下内容并未回答您的问题,只是对编码风格的说明。

将程序拆分为可重用的块很有用。在这种情况下,您的根发现应该与您的函数构造分开。我建议将您的 Newton-Raphson 方法编写在一个单独的文件中,并从定义函数及其派生的脚本中调用它。然后,您的来源将类似于:

% Define the function (and its derivative) to perform root finding on:
Params = load('saved_data.mat');
theta = pi/2;
zeta  = cos(theta);
I = eye(Params.n,Params.n);
Q = zeta*I-Params.p*Params.p';

Mroot = Params.M.^(1/2);
T = Mroot*Q*Mroot; %T is a matrix(5,5)

E = real(eig(T)); % Find the eigen-values

gamma = min(E);   % Find the smallest negative eigen value

% Now solve for lambda (what is lambda?)
M_inv = inv(Params.M);
zm = Params.zm;

Winv = inv(M_inv+x.*Q);

f = @(x)( zm'*M_inv*Winv*M_inv*zm);
dfdx = @(x)(-zm'*M_inv*Winv*Q*M_inv*zm);

x0 = (-1./gamma)/2.;

xRoot = newton(f, dfdx, x0, 1e-10);

newton.m 中,您将实现 Newton-Raphson 方法,该方法将您定义的函数句柄(fdfdx)作为参数。使用问题中给出的代码,这看起来像

function root = newton(f, df, x0, tol)

    root = x0; % Initial guess for the root

    MAXIT = 20; % Maximum number of iterations

    for j = 1:MAXIT;

        dx = f(root) / df(root);
        root = root - dx

        % Stop criterion:
        if abs(dx) < tolerance
            return
        end

    end

    % Raise error if maximum number of iterations reached.
    error('newton: maximum number of allowed iterations exceeded.')

end 

请注意,我避免使用无限循环。

【讨论】:

  • 我试过 fzero 但它不起作用,因为方程中有一个复杂的输入。我也看到了你建议的链接的答案,但我需要修复这个代码。
  • @user1079331 你能不能把你的输入方程分解成实部和虚部?此外,说明您的问题(您正在使用什么方程式)并清理 qeustion 中的代码(例如,end 到您的while 循环在哪里?)可能会有所帮助。
  • 我不会将输入方程分解为实部和虚部。
  • 我没有把输入方程分解成实部和虚部。函数是 Winv = inv(M_inv+lambda.*Q);牛顿 = zm'M_invWinvM_invzm;如您所见,Winv 只是方程中的一个参数,它包含变量 lambda,我们应该发现它的值使上述函数的导数为零。导数是:Winv = inv(M_inv+lambda.*Q) ;牛顿 = -zm'M_invWinvQM_inv*zm;
猜你喜欢
  • 1970-01-01
  • 2014-03-03
  • 2017-07-11
  • 1970-01-01
  • 1970-01-01
  • 2013-12-23
  • 2016-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多