뻘코드 - 수치 미분

요즘 글리젠이 적길래 과제로 작성했던 코드 하나 올려봅니다.

수치해석 교수님이 c를 워낙에 좋아하셔서 c로 작성된 수치미분 코드인데요.

각각 전방, 후방, 중앙 차분이고 위에서부터 O(h) 정확도, O(h^2) 정확도로 함수와 x값을 받아 수치미분을 계산하는 간단한 코드입니다.

dfunc 함수는 원래 미분값과 얼마나 비슷한지 보려고 만든거니, func 함수만 변경하면 구하고자 하는 수치미분값을 구할 수 있습니다.

솔직히 너무 간단한 코드라 그냥 복붙해서 돌려보고 오 진짜 나오네?? 하고 지나가심 되겠습니다…

#include <stdio.h>

double ForwardExpansion1(double (*f)(double), double x){
    double h=0.25;
    return (f(x+h)-f(x))/h;
}

double BackwardExpansion1(double (*f)(double), double x){
    double h=0.25;
    return (f(x)-f(x-h))/h;
}

double CentralExpansion1(double (*f)(double), double x){
    double h=0.25;
    return (f(x+h)-f(x-h))/(2*h);
}

double ForwardExpansion2(double (*f)(double), double x){
    double h=0.25;
    return (0.5/h)*(-f(x+2*h)+4*f(x+h)-3*f(x));
}

double BackwardExpansion2(double (*f)(double), double x){
    double h=0.25;
    return (0.5/h)*(3*f(x)-4*f(x-h)+f(x-2*h));
}

double CentralExpansion2(double (*f)(double), double x){
    double h=0.25;
    return ((1.0/12.0)/h)*(-f(x+2*h)+8*f(x+h)-8*f(x-h)+f(x-2*h));
}

double func(double x){
    return -0.1*x*x*x*x -0.15*x*x*x -0.5*x*x -0.25*x +1.25;
}

double dfunc(double x){
    return -0.4*x*x*x -0.45*x*x -x -0.25;
}

int main(void){
    double x=0.5;
    printf("differential  value: %lf\n", dfunc(x));
    printf("forward  expansion1: %lf\n", ForwardExpansion1(func, x));
    printf("backward expansion1: %lf\n", BackwardExpansion1(func, x));
    printf("central  expansion1: %lf\n", CentralExpansion1(func, x));
    printf("forward  expansion2: %lf\n", ForwardExpansion2(func, x));
    printf("backward expansion2: %lf\n", BackwardExpansion2(func, x));
    printf("central  expansion2: %lf\n", CentralExpansion2(func, x));
    return 0;
}

흠… h가 많이 거슬립니다

음… 확실히 h는 매개변수를 받는 쪽으로 바꾸는 게 낫겠군요

아니요. 바뀌지도 안는 걸 매번 선언하고… 상수로 빼고, 관련 계산들도 동적인게 하나도 없어요. 다 정적으로 빼요. 왜 매번 같은계산을 반복하는 건가요.

const double h=0.25;

double ForwardExpansion1(double (*f)(double), double x){
    return (f(x+h)-f(x))/h;
}

이런 식으로 상수화 하는 걸 말씀하시는 건가요?
아직 말씀하시는 요지를 잘 모르겠습니다.

관련 계산들도 동적인 게 없다는 것도 원래 설계도 함수와 x값을 받아 미분값을 리턴하려는 의도여서 뭘 더 고치면 좋을지 감이 안 잡히네요.

ㅇㅇ 그렇죠. 정적인 계산이라는건 (2*h) 같은걸 말하는겁니다. 그냥 구지 저걸 런타임에 비싼 곱하기를 매번 할 필요가 없잖아요? h가 바뀌는거도 아니고, 그냥 계산된 상수를 가져다 쓰면 되는거죠.

뭐… 별건 아닌데, DRY 한게 좋은거죠 :slight_smile:

사실 이런걸 따질만한 코드가 아니긴한데, 이런 부분들을 보는 연습을 해 두시면, 나중에 더 복잡한 코드들을 짤때도 도움이 될거라고 생각합니다.

3 Likes