Aproximação de Raízes Usando o Método de Newton em C

CBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá a aproximar as raízes de uma função usando o método de Newton em C. O laboratório cobre os seguintes passos:

Primeiro, você definirá a função f(x) e sua derivada f'(x). Em seguida, implementará a fórmula iterativa do método de Newton para calcular a raiz aproximada. Finalmente, imprimirá a raiz aproximada resultante.

Este laboratório fornece um exemplo prático da aplicação de métodos numéricos para resolver problemas matemáticos usando programação em C. Ao final do laboratório, você terá uma compreensão melhor de como usar o método de Newton para encontrar as raízes de uma função.

Definir f(x) e f'(x)

Neste passo, definiremos a função matemática f(x) e sua derivada f'(x) para implementar o método de Newton e aproximar as raízes.

Primeiro, crie um novo arquivo C no diretório ~/project:

cd ~/project
nano newton_method.c

Agora, escreva o código inicial para definir nossa função e sua derivada:

#include <stdio.h>
#include <math.h>

// Define a função f(x)
double f(double x) {
    return x * x - 4;  // Função de exemplo: f(x) = x^2 - 4
}

// Define a derivada f'(x)
double f_derivative(double x) {
    return 2 * x;  // Derivada de f(x) = 2x
}

int main() {
    printf("Função f(x) = x^2 - 4\n");
    printf("Derivada f'(x) = 2x\n");
    return 0;
}

Saída de exemplo:

Função f(x) = x^2 - 4
Derivada f'(x) = 2x

Vamos analisar o código:

  • f(x) é definida como x^2 - 4, que possui raízes em x = 2 e x = -2
  • f_derivative(x) é a derivada de f(x), que é 2x
  • Usaremos essas funções nos próximos passos para implementar o método de Newton

Compile o código para verificar:

gcc -o newton_method newton_method.c -lm
./newton_method

Iterar x_{n+1}=x_n - f(x_n)/f'(x_n)

Neste passo, implementaremos a fórmula iterativa do método de Newton para aproximar a raiz da nossa função.

Abra o arquivo newton_method.c anterior:

cd ~/project
nano newton_method.c

Atualize o código para incluir a iteração do método de Newton:

#include <stdio.h>
#include <math.h>

// As definições de função anteriores permanecem as mesmas
double f(double x) {
    return x * x - 4;
}

double f_derivative(double x) {
    return 2 * x;
}

// Implementação do método de Newton
double newton_method(double initial_guess, int max_iterations, double tolerance) {
    double x = initial_guess;

    for (int i = 0; i < max_iterations; i++) {
        double fx = f(x);
        double fpx = f_derivative(x);

        // Verifica divisão por zero
        if (fabs(fpx) < tolerance) {
            printf("Derivada muito próxima de zero. Não é possível continuar.\n");
            return x;
        }

        // Fórmula de iteração do método de Newton
        double x_next = x - fx / fpx;

        printf("Iteração %d: x = %f\n", i + 1, x_next);

        // Verifica convergência
        if (fabs(x_next - x) < tolerance) {
            return x_next;
        }

        x = x_next;
    }

    printf("Número máximo de iterações atingido.\n");
    return x;
}

int main() {
    double initial_guess = 1.0;
    int max_iterations = 10;
    double tolerance = 1e-6;

    double root = newton_method(initial_guess, max_iterations, tolerance);

    printf("\nRaiz aproximada: %f\n", root);
    printf("f(raiz) = %f\n", f(root));

    return 0;
}

Compile e execute o código:

gcc -o newton_method newton_method.c -lm
./newton_method

Saída de exemplo:

Iteração 1: x = 2.500000
Iteração 2: x = 2.050000
Iteração 3: x = 2.000610
Iteração 4: x = 2.000000
Iteração 5: x = 2.000000

Raiz aproximada: 2.000000
f(raiz) = 0.000000

Pontos-chave da implementação:

  • newton_method() recebe uma estimativa inicial, número máximo de iterações e tolerância
  • Implementa a fórmula de iteração do método de Newton: x_{n+1} = x_n - f(x_n) / f'(x_n)
  • Verifica convergência e divisão por zero
  • Imprime iterações intermediárias para mostrar o processo de aproximação

Imprimir a Raiz Aproximada

Neste passo, melhoraremos a implementação do método de Newton para fornecer um resultado mais detalhado sobre a aproximação da raiz.

Abra o arquivo newton_method.c anterior:

cd ~/project
nano newton_method.c

Atualize o código para melhorar a saída da aproximação da raiz:

#include <stdio.h>
#include <math.h>

// As definições de função e método anteriores permanecem as mesmas
double f(double x) {
    return x * x - 4;
}

double f_derivative(double x) {
    return 2 * x;
}

double newton_method(double initial_guess, int max_iterations, double tolerance) {
    double x = initial_guess;

    printf("Aproximação da Raiz pelo Método de Newton\n");
    printf("-------------------------------------------\n");
    printf("Estimativa Inicial: %f\n", x);
    printf("Tolerância: %e\n", tolerance);
    printf("Número Máximo de Iterações: %d\n\n", max_iterations);

    for (int i = 0; i < max_iterations; i++) {
        double fx = f(x);
        double fpx = f_derivative(x);

        if (fabs(fpx) < tolerance) {
            printf("Erro: Derivada muito próxima de zero.\n");
            return x;
        }

        double x_next = x - fx / fpx;

        printf("Iteração %d:\n", i + 1);
        printf("  x Atual: %f\n", x_next);
        printf("  f(x): %f\n", f(x_next));
        printf("  |x_próximo - x|: %e\n\n", fabs(x_next - x));

        if (fabs(x_next - x) < tolerance) {
            printf("Convergência alcançada!\n");
            return x_next;
        }

        x = x_next;
    }

    printf("Número máximo de iterações atingido.\n");
    return x;
}

int main() {
    double initial_guess = 1.0;
    int max_iterations = 10;
    double tolerance = 1e-6;

    double root = newton_method(initial_guess, max_iterations, tolerance);

    printf("Resultados Finais:\n");
    printf("-----------------\n");
    printf("Raiz Aproximada: %f\n", root);
    printf("f(raiz): %f\n", f(root));
    printf("Erro Absoluto: %e\n", fabs(f(root)));

    return 0;
}

Compile e execute o código:

gcc -o newton_method newton_method.c -lm
./newton_method

Saída de exemplo:

Aproximação da Raiz pelo Método de Newton
-------------------------------------------
Estimativa Inicial: 1.000000
Tolerância: 1.000000e-06
Número Máximo de Iterações: 10

Iteração 1:
  x Atual: 2.500000
  f(x): 2.250000
  |x_próximo - x|: 1.500000e+00

Iteração 2:
  x Atual: 2.050000
  f(x): 0.202500
  |x_próximo - x|: 4.500000e-01

... (mais iterações)

Convergência alcançada!

Resultados Finais:
-----------------
Raiz Aproximada: 2.000000
f(raiz): 0.000000
Erro Absoluto: 0.000000e+00

Melhorias-chave:

  • Informações detalhadas sobre as iterações adicionadas
  • Parâmetros iniciais exibidos
  • Progresso da convergência mostrado
  • Resultados finais impressos com erro absoluto

Resumo

Neste laboratório, primeiro definimos a função matemática f(x) e sua derivada f'(x) para implementar o método de Newton para aproximar raízes. Em seguida, implementamos a fórmula iterativa x_{n+1} = x_n - f(x_n)/f'(x_n) para realizar a aproximação da raiz. Finalmente, imprimiremos a raiz aproximada obtida por este processo.

Os passos-chave abordados neste laboratório são a definição da função-alvo e sua derivada, e, em seguida, a aplicação iterativa da fórmula do método de Newton para convergir para a raiz. Esta abordagem permite encontrar eficientemente as raízes de várias funções matemáticas usando a programação em C.