2011-12-03 4 views
1

저는 MATLAB을 처음 사용하는 사람입니다. Newton-Raphson 방법을 사용하여 f(x) = 0이되는 값을 찾고 싶습니다. 코드를 작성하려고했지만 Newton-Raphson 메서드를 구현하기가 어렵습니다. 이것은 내가 지금까지 무엇을 가지고 :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); 
+1

그럼, 무엇이 문제입니까? 당신은 단지 코드를 보여줍니다 ... – Oli

+0

나는 그것이 작동하도록 코드를 고쳐야합니다. – user1079331

+0

어떤 종류의 출력을 얻고 있습니까? 'fzero()'와 함께 작동하지 않는 것처럼 보이는 함수는 무엇입니까? – jblock

답변

3

문제는 특히 명확하지 않다. 그러나 스스로 루트를 구현해야합니까? 그렇지 않다면 Matlab에 내장 된 함수 fzero (Newton-Raphson을 기반으로하지 않음)을 사용하십시오.

Newton-Raphson 방법을 직접 구현해야하는 경우 Newton Raphsons method in Matlab?에 대한 답변 중 하나를 시작점으로 사용하는 것이 좋습니다.

편집 : 다음은 질문에 답하지 않고 코딩 스타일에 대한 참고 사항입니다.

프로그램을 재사용 가능한 청크로 분할하는 것이 유용합니다. 이 경우 루트 찾기는 함수 작성과 분리되어야합니다. 저는 여러분의 Newton-Raphson 방법을 별도의 파일에 작성하고 함수와 파생 함수를 정의하는 스크립트에서 이것을 호출하는 것이 좋습니다. 당신이 기능을 사용하면 (fdfdx)를 정의 처리 인수로 걸리는 뉴턴 - 랩슨 방법의 구현을 것

% 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에서 : 귀하의 소스는 다음과 같은 몇 가지 일을 보일 것이다. 질문에 주어진 코드를 사용하면 다음과 비슷한 형태가됩니다.

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 

무한 루프 사용을 피했는지 확인하십시오.

+0

나는 fzero를 시도했지만 방정식에 복잡한 입력이 있기 때문에 작동하지 않습니다. 또한 내가 제안한 링크의 답변을 본 적이 있지만이 코드를 수정해야합니다. – user1079331

+0

@ user1079331 입력 방정식을 실수 및 허수 부로 분해 할 수 있습니까? 또한 문제 (당신이 사용하고있는 방정식)를 철자하고 코드에서 코드 코드를 정리하는 것이 도움이 될 수 있습니다 (예를 들어, while 루프의 'end'는 어디에 있습니까?). – Chris

+0

저는 입력 방정식을 실수 부와 허수 부로 분해하지 않습니다. – user1079331

관련 문제