Evaluar Aproximaciones de Diferencias Finitas en C

CBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderás a evaluar aproximaciones de diferencias finitas de derivadas en C. El laboratorio cubre los siguientes pasos:

  1. Definir una función matemática f(x) y establecer el tamaño del paso h para las aproximaciones de diferencias finitas.
  2. Calcular las aproximaciones de diferencias finitas hacia adelante y hacia atrás de la derivada de f(x) en un punto de evaluación dado x.
  3. Imprimir las aproximaciones calculadas y compararlas con la derivada verdadera.

Al final de este laboratorio, tendrás una sólida comprensión de cómo implementar métodos de diferencias finitas en C y evaluar la precisión de las aproximaciones.

Definir f(x) y el tamaño de paso h

En este paso, aprenderás a definir una función matemática y a configurar el tamaño del paso para aproximaciones de diferencias finitas en C.

Primero, crea un nuevo archivo C para tu programa de aproximación de diferencias finitas:

cd ~/project
nano finite_difference.c

Ahora, agrega el siguiente código para definir la función y el tamaño del paso:

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

// Define la función f(x)
double f(double x) {
    return x * x;  // Función de ejemplo: f(x) = x^2
}

int main() {
    // Define el tamaño del paso h
    double h = 0.0001;  // Tamaño de paso pequeño para una aproximación precisa

    // Punto en el que evaluar la derivada
    double x = 2.0;

    printf("Función: f(x) = x^2\n");
    printf("Tamaño de paso h: %f\n", h);
    printf("Punto de evaluación x: %f\n", x);

    return 0;
}

Salida de ejemplo:

Función: f(x) = x^2
Tamaño de paso h: 0.000100
Punto de evaluación x: 2.000000

Desglose de los componentes clave:

  1. Función f(x): Hemos definido una función cuadrática simple f(x) = x^2. Puedes modificar esta función para representar cualquier función matemática que desees aproximar.

  2. Tamaño de paso h: Este es un valor pequeño utilizado en las aproximaciones de diferencias finitas. Un h más pequeño generalmente proporciona resultados más precisos, pero valores extremadamente pequeños pueden llevar a problemas de precisión numérica.

  3. Punto de evaluación x: Este es el punto en el que calcularemos la aproximación de la derivada.

Compila el programa para asegurarte de que funciona:

gcc -o finite_difference finite_difference.c -lm
./finite_difference

Salida de ejemplo:

Función: f(x) = x^2
Tamaño de paso h: 0.000100
Punto de evaluación x: 2.000000

Calcular diferencias hacia adelante/atrás

En este paso, aprenderás a calcular aproximaciones de diferencias finitas hacia adelante y hacia atrás de derivadas.

Abre el archivo anterior y modifica el código para incluir los métodos de aproximación de derivadas:

cd ~/project
nano finite_difference.c

Actualiza el código con los cálculos de diferencias hacia adelante y hacia atrás:

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

// Define la función f(x)
double f(double x) {
    return x * x;  // Función de ejemplo: f(x) = x^2
}

int main() {
    // Define el tamaño del paso h
    double h = 0.0001;  // Tamaño de paso pequeño para una aproximación precisa

    // Punto en el que evaluar la derivada
    double x = 2.0;

    // Aproximación de diferencia hacia adelante
    double forward_diff = (f(x + h) - f(x)) / h;

    // Aproximación de diferencia hacia atrás
    double backward_diff = (f(x) - f(x - h)) / h;

    printf("Aproximación de diferencia hacia adelante: %f\n", forward_diff);
    printf("Aproximación de diferencia hacia atrás: %f\n", backward_diff);

    return 0;
}

Compila y ejecuta el programa:

gcc -o finite_difference finite_difference.c -lm
./finite_difference

Salida de ejemplo:

Aproximación de diferencia hacia adelante: 4.000100
Aproximación de diferencia hacia atrás: 3.999900

Desglose de las aproximaciones de diferencias finitas:

  1. Diferencia hacia adelante: Calcula la derivada utilizando el punto siguiente a x.

    • Fórmula: (f(x + h) - f(x)) / h
    • Aproxima la tasa de cambio moviéndose hacia adelante.
  2. Diferencia hacia atrás: Calcula la derivada utilizando el punto anterior a x.

    • Fórmula: (f(x) - f(x - h)) / h
    • Aproxima la tasa de cambio moviéndose hacia atrás.

Ten en cuenta que para la función f(x) = x^2, la derivada verdadera es 2x (que es 4 en x = 2). Las aproximaciones están muy cerca del valor real de la derivada.

Imprimir las aproximaciones

En este paso, mejorarás el programa para imprimir resultados de aproximación detallados y compararlos con la derivada real.

Abre el archivo anterior y modifica el código para incluir una salida completa:

cd ~/project
nano finite_difference.c

Actualiza el código con la impresión detallada de las aproximaciones:

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

// Define la función f(x)
double f(double x) {
    return x * x;  // Función de ejemplo: f(x) = x^2
}

// Función de la derivada real
double actual_derivative(double x) {
    return 2 * x;  // Derivada de x^2 es 2x
}

int main() {
    // Define varios tamaños de paso para la comparación
    double step_sizes[] = {0.1, 0.01, 0.001, 0.0001};
    int num_steps = sizeof(step_sizes) / sizeof(step_sizes[0]);

    // Punto en el que evaluar la derivada
    double x = 2.0;

    // Valor de la derivada real
    double true_derivative = actual_derivative(x);

    printf("Análisis de la aproximación de la derivada\n");
    printf("-----------------------------------------\n");
    printf("Función: f(x) = x^2\n");
    printf("Punto de evaluación: x = %f\n", x);
    printf("Derivada real: %f\n\n", true_derivative);

    printf("Tamaño de paso | Diferencia hacia adelante | Diferencia hacia atrás | Error hacia adelante | Error hacia atrás\n");
    printf("-----------------------------------------------------------------------------------------------------\n");

    // Calcula e imprime las aproximaciones para diferentes tamaños de paso
    for (int i = 0; i < num_steps; i++) {
        double h = step_sizes[i];

        // Aproximación de diferencia hacia adelante
        double forward_diff = (f(x + h) - f(x)) / h;

        // Aproximación de diferencia hacia atrás
        double backward_diff = (f(x) - f(x - h)) / h;

        // Calcula los errores absolutos
        double forward_error = fabs(forward_diff - true_derivative);
        double backward_error = fabs(backward_diff - true_derivative);

        printf("%9f | %11f | %12f | %11f | %12f\n",
               h, forward_diff, backward_diff, forward_error, backward_error);
    }

    return 0;
}

Compila y ejecuta el programa:

gcc -o finite_difference finite_difference.c -lm
./finite_difference

Salida de ejemplo:

Análisis de la aproximación de la derivada
-----------------------------------------
Función: f(x) = x^2
Punto de evaluación: x = 2.000000
Derivada real: 4.000000

Tamaño de paso | Diferencia hacia adelante | Diferencia hacia atrás | Error hacia adelante | Error hacia atrás
-----------------------------------------------------------------------------------------------------
    0.100000 |     4.100000 |      3.900000 |      0.100000 |       0.100000
    0.010000 |     4.010000 |      3.990000 |      0.010000 |       0.010000
    0.001000 |     4.001000 |      3.999000 |      0.001000 |       0.001000
    0.000100 |     4.000100 |      3.999900 |      0.000100 |       0.000100

Observaciones clave:

  1. A medida que el tamaño del paso h disminuye, la aproximación se vuelve más precisa.
  2. Las diferencias hacia adelante y hacia atrás convergen a la derivada real.
  3. El error disminuye con tamaños de paso más pequeños.

Resumen

En este laboratorio, aprendiste a definir una función matemática y a establecer el tamaño del paso para aproximaciones de diferencias finitas en C. También aprendiste a calcular aproximaciones de diferencias finitas hacia adelante y hacia atrás de derivadas. Los pasos clave cubiertos incluyen la definición de la función f(x) y el tamaño del paso h, así como la implementación de los métodos de diferencia hacia adelante y hacia atrás para aproximar la derivada en un punto de evaluación dado x. Esto proporciona una base para comprender e implementar técnicas de diferencias finitas en el análisis numérico y la computación científica.