Função para Cálculo pelo Método Newton para Gretl - Blog do Estudante de Atuariais

quinta-feira, 18 de abril de 2019

Função para Cálculo pelo Método Newton para Gretl


function [x,norma_Fx,k,info]=newton(Func,x_0,tau_r,tau_a,kmax)
    // [x,norma_Fx,k,info]=newton(F,x_0,tau_r,tau_a,kmax)
    // Calcula uma aproximação para a solução do sistema de equações não-lineares F(x)=0,
    // usando o método de Newton, com estimativa inicial x_0=[(x_0)_1...(x_0)_n],
    // sujeita a ||F(x)||<tau_r||F(x_0)||+tau_a, desde que não exceda a "kmax" iterações.
    // A solução do sistema jacobiano é feita através de eliminação gaussiana.
    // F deve ser transmitida como um vetor de "strings", cada uma contendo a função escrita de
    // acordo com a sintaxe do Scilab. P.ex., para o sistema de equações não-lineares
    // {x^2-y^2 = 1,y = e^x}, escreve-se: ["x(1)^2-x(2)^2-1";"exp(x(1))-x(2)"].
    // Se info=0, localizou uma raiz se info=-1, a matriz jacobiana de F(x_k) tornou-se singular na iteração k.
    // Baseada em C.T.Kelley, "Iterative Methods for Linear and Nonlinear Equations", pp.71ff
    // (C) Rudnei Dias da Cunha 2011
    info = 0
    x = x_0
    n = max(size(x))
    s = "v=["
    for i=1:n-1
        s = s+Func(i)+";"
    end
    s = s+Func(n)+"]"
    deff('[v]=F(x)',s)
    // Calcula a função F
    Fx = F(x)
    norma_Fx=norm(Fx,'fro');
    barreira=norma_Fx/sqrt(n)*tau_r+tau_a;
    norma_h = sqrt(number_properties('huge'))
    for k=1:kmax
        // Calcula o jacobiano
        J = jacobiano(Func,x)
        // Calcula a correção h
        h = J\(-Fx)
        norma_h0 = norma_h
        norma_h = norm(h,'fro')
        dh = abs(norma_h-norma_h0)
        if (or(isinf(h))) // testa se o sistema é singular
            info = -1
            break
        end
        // Corrige X
        x = x+h
        // Calcula a função F
        Fx = F(x)
        // Testa a convergência
        norma_Fx = norm(Fx,'fro')
        mprintf('k=%g ||F(x)||=%g x=\n',k,norma_Fx)
        disp(x)
        if norma_Fx/sqrt(n)<barreira | norma_h<tau_r | dh<tau_r then
            break
        end
    end
endfunction

Nenhum comentário:

Postar um comentário