Computer >> 컴퓨터 >  >> 프로그래밍 >> 프로그래밍

시컨트 방법(Secant Method)으로 비선형 방정식 풀기: 원리부터 C++ 구현까지

시컨트 방법이란?

시컨트 방법(Secant Method)은 비선형 방정식의 근을 구하는 대표적인 수치 해석 기법 중 하나입니다. 이 방법은 뉴턴-랩슨 방법(Newton-Raphson Method)과 매우 유사하지만, 한 가지 중요한 차이점이 있습니다. 바로 함수 f(x)의 도함수(미분계수)를 직접 구할 필요가 없다는 점입니다.

오직 f(x) 값만을 이용하여 뉴턴의 차분 공식(Divided Difference Formula)을 적용하면, f'(x)를 수치적으로 근사할 수 있습니다.

먼저 뉴턴-랩슨 공식은 다음과 같습니다.

시컨트 방법(Secant Method)으로 비선형 방정식 풀기: 원리부터 C++ 구현까지

여기에 차분 공식을 적용하면 다음과 같이 전개됩니다.

시컨트 방법(Secant Method)으로 비선형 방정식 풀기: 원리부터 C++ 구현까지시컨트 방법(Secant Method)으로 비선형 방정식 풀기: 원리부터 C++ 구현까지시컨트 방법(Secant Method)으로 비선형 방정식 풀기: 원리부터 C++ 구현까지

뉴턴-랩슨 공식의 f'(x)를 위에서 새롭게 구한 f'(x)로 대체하면, 비선형 방정식을 풀기 위한 최종적인 시컨트 공식을 얻을 수 있습니다.

시컨트 방법(Secant Method)으로 비선형 방정식 풀기: 원리부터 C++ 구현까지

참고: 시컨트 방법을 시작하려면 근에 대한 두 개의 초기 추측값(initial guess)이 반드시 필요합니다. 또한 두 초기값에서의 함수값이 같으면(f(x₁) = f(x₂)) 분모가 0이 되어 계산이 불가능해지므로, 초기값 선정에 주의해야 합니다. 참고로 시컨트 방법의 수렴 속도는 약 1.618(황금비)차 수렴으로, 이분법보다 빠르지만 뉴턴-랩슨 방법(2차 수렴)보다는 느린 편입니다.

입력 및 출력

입력:
함수 f(x) = (x*x) - (4*x) - 10
출력:
근은: -1.74166

알고리즘

secant(x1, x2)

입력: 근에 대한 두 개의 초기 추측값.

출력: 비선형 방정식 f(x)의 근사 근.

Begin
    f1 := f(x1)
    f2 := f(x2)
    x3 := ((f2*x1) – (f1*x2)) / (f2 – f1)
    while x3와 x2의 상대 오차가 허용 정밀도보다 클 때까지 반복, do
       x1 := x2
       f1 := f2
       x2 := x3
       f2 := f(x2)
       x3 := ((f2*x1) – (f1*x2)) / (f2 – f1)
    done
    root := x3
    return root
End

C++ 구현 예제

#include<iostream>
#include<cmath>
using namespace std;

double absolute(double value) {          // 값의 크기(절댓값)를 구하는 함수
    if(value < 0)
        return (-value);
    return value;
}

double f(double x) {         // 주어진 함수 x^2 - 4x - 10
    return ((x*x)-(4*x)-10);
}

double secant(double x1, double x2) {
    double x3, root;
    double f1, f2;
    f1 = f(x1);
    f2 = f(x2);
    x3 = (f2*x1-f1*x2)/(f2-f1);

    while(absolute((x3-x2)/x3) > 0.00001) {          // x3의 정확도 검사
        x1 = x2;          // x 값 갱신
        f1 = f2;
        x2 = x3;
        f2 = f(x2);                // 새로운 x2 계산
        x3 = (f2*x1-f1*x2)/(f2-f1);          // 새로운 x3 계산
    }

    root = x3;
    return root;              // 방정식의 근 반환
}

main() {
    double a, b, res;
    a = 0.5;
    b = 0.75;
    res = secant(a, b);
    cout << "The root is: " << res;
}

실행 결과

The root is: -1.74166

위 예제에서는 초기 추측값으로 0.5와 0.75를 사용했으며, 상대 오차가 0.00001보다 작아질 때까지 반복 계산을 수행하여 최종적으로 근 -1.74166을 얻었습니다. 이처럼 시컨트 방법은 미분 없이 함수값만으로 효율적으로 비선형 방정식의 근을 구할 수 있는 실용적인 방법입니다.