C 언어로 뉴턴 방법을 이용한 근사 근 계산

CBeginner
지금 연습하기

소개

이 실험에서는 C 언어를 사용하여 뉴턴 방법을 이용하여 함수의 근을 근사하는 방법을 배우게 됩니다. 이 실험은 다음 단계를 포함합니다.

먼저, 함수 f(x) 와 그 도함수 f'(x) 를 정의합니다. 그런 다음, 뉴턴 방법의 반복 공식을 구현하여 근사 근을 계산합니다. 마지막으로, 결과 근사 근을 출력합니다.

이 실험은 C 프로그래밍을 사용하여 수학 문제를 해결하기 위한 수치적 방법을 적용하는 실제적인 예시를 제공합니다. 실험을 마치면 함수의 근을 찾기 위해 뉴턴 방법을 사용하는 방법에 대한 이해도가 높아질 것입니다.

f(x) 및 f'(x) 정의

이 단계에서는 뉴턴 방법을 사용하여 근을 근사하기 위해 수학 함수 f(x) 와 그 도함수 f'(x) 를 정의합니다.

먼저 ~/project 디렉토리에 새로운 C 파일을 생성합니다.

cd ~/project
nano newton_method.c

이제 함수와 그 도함수를 정의하는 초기 코드를 작성합니다.

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

// 함수 f(x) 를 정의합니다.
double f(double x) {
    return x * x - 4;  // 예시 함수: f(x) = x^2 - 4
}

// 도함수 f'(x) 를 정의합니다.
double f_derivative(double x) {
    return 2 * x;  // f(x) = 2x 의 도함수
}

int main() {
    printf("함수 f(x) = x^2 - 4\n");
    printf("도함수 f'(x) = 2x\n");
    return 0;
}

예시 출력:

함수 f(x) = x^2 - 4
도함수 f'(x) = 2x

코드를 분석해 보겠습니다.

  • f(x)x^2 - 4로 정의되어 있으며, x = 2 와 x = -2 에서 근을 갖습니다.
  • f_derivative(x)는 f(x) 의 도함수로 2x입니다.
  • 다음 단계에서 뉴턴 방법을 구현하기 위해 이 함수들을 사용할 것입니다.

코드를 확인하기 위해 컴파일합니다.

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

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

이 단계에서는 함수의 근을 근사하기 위해 뉴턴 방법의 반복 공식을 구현합니다.

이전 newton_method.c 파일을 엽니다.

cd ~/project
nano newton_method.c

뉴턴 방법 반복을 포함하도록 코드를 업데이트합니다.

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

// 이전 함수 정의는 동일하게 유지됩니다.
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;

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

        // 0 으로 나누는 것을 방지합니다.
        if (fabs(fpx) < tolerance) {
            printf("도함수가 0 에 너무 가까워 계속할 수 없습니다.\n");
            return x;
        }

        // 뉴턴 방법 반복 공식
        double x_next = x - fx / fpx;

        printf("반복 %d: x = %f\n", i + 1, x_next);

        // 수렴 여부 확인
        if (fabs(x_next - x) < tolerance) {
            return x_next;
        }

        x = x_next;
    }

    printf("최대 반복 횟수에 도달했습니다.\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("\n근사 근: %f\n", root);
    printf("f(근) = %f\n", f(root));

    return 0;
}

코드를 컴파일하고 실행합니다.

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

예시 출력:

반복 1: x = 2.500000
반복 2: x = 2.050000
반복 3: x = 2.000610
반복 4: x = 2.000000
반복 5: x = 2.000000

근사 근: 2.000000
f(근) = 0.000000

구현에 대한 주요 사항:

  • newton_method()는 초기 추측값, 최대 반복 횟수 및 허용 오차를 받습니다.
  • 뉴턴 방법 반복 공식: x_{n+1} = x_n - f(x_n) / f'(x_n) 을 구현합니다.
  • 수렴 여부와 0 으로 나누는 것을 방지합니다.
  • 근사 과정을 보여주기 위해 중간 반복 값을 출력합니다.

근사 근 출력

이 단계에서는 뉴턴 방법 구현을 개선하여 근사 근에 대한 자세한 출력을 제공합니다.

이전 newton_method.c 파일을 엽니다.

cd ~/project
nano newton_method.c

근사 근 출력을 개선하도록 코드를 업데이트합니다.

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

// 이전 함수 및 메서드 정의는 동일하게 유지됩니다.
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("뉴턴 방법 근사 근\n");
    printf("---------------------\n");
    printf("초기 추측값: %f\n", x);
    printf("허용 오차: %e\n", tolerance);
    printf("최대 반복 횟수: %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("오류: 도함수가 0 에 너무 가깝습니다.\n");
            return x;
        }

        double x_next = x - fx / fpx;

        printf("반복 %d:\n", i + 1);
        printf("  현재 x: %f\n", x_next);
        printf("  f(x): %f\n", f(x_next));
        printf("  |x_next - x|: %e\n\n", fabs(x_next - x));

        if (fabs(x_next - x) < tolerance) {
            printf("수렴 성공!\n");
            return x_next;
        }

        x = x_next;
    }

    printf("최대 반복 횟수에 도달했습니다.\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("최종 결과:\n");
    printf("---------\n");
    printf("근사 근: %f\n", root);
    printf("f(근): %f\n", f(root));
    printf("절대 오차: %e\n", fabs(f(root)));

    return 0;
}

코드를 컴파일하고 실행합니다.

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

예시 출력:

뉴턴 방법 근사 근
---------------------
초기 추측값: 1.000000
허용 오차: 1.000000e-06
최대 반복 횟수: 10

반복 1:
  현재 x: 2.500000
  f(x): 2.250000
  |x_next - x|: 1.500000e+00

반복 2:
  현재 x: 2.050000
  f(x): 0.202500
  |x_next - x|: 4.500000e-01

... (반복 횟수)

수렴 성공!

최종 결과:
---------
근사 근: 2.000000
f(근): 0.000000
절대 오차: 0.000000e+00

주요 개선 사항:

  • 자세한 반복 정보 추가
  • 초기 매개변수 표시
  • 수렴 진행 상황 표시
  • 최종 결과와 절대 오차 출력

요약

이 실험에서는 먼저 수학 함수 f(x)와 그 도함수 f'(x)를 정의하여 뉴턴 방법을 사용하여 근을 근사했습니다. 그런 다음 반복 공식 x_{n+1} = x_n - f(x_n)/f'(x_n)을 사용하여 근을 근사했습니다. 마지막으로 이 과정을 통해 얻은 근사 근을 출력합니다.

이 실험에서 다룬 주요 단계는 대상 함수와 그 도함수를 정의하고, 뉴턴 방법 공식을 반복적으로 적용하여 근에 수렴하는 것입니다. 이 접근 방식을 통해 C 프로그래밍을 사용하여 다양한 수학 함수의 근을 효율적으로 찾을 수 있습니다.