#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "func_ptr.h"
#include "integral.h"

double f1(double x) {
    return pow(M_E, -x);
}

double f2(double x) {
    return x * f1(x);
}

#define PRINT_INTEGRALS(func, a, b, real) { \
    double _i; \
    PRINT_INTEGRAL(func, a, b, rectangle, (real)); \
    PRINT_INTEGRAL(func, a, b, trapezoidal, (real)); \
    PRINT_INTEGRAL(func, a, b, simpson, (real)); \
    PRINT_INTEGRAL(func, a, b, gauss, (real)); \
}

#define PRINT_INTEGRAL(func, a, b, method, real) { \
    _i = integral(&func, &method, a, b, atoi(argv[1])); \
    printf(#func " from " #a " to " #b " using %-19s %.12e (%.12e)\n", \
        #method " method:", _i, fabs((real - _i))); \
}

int main(int argc, char **argv) {
    if( argc != 2 ) {
        printf("Usage: %s SLICES\n", argv[0]);
        return -1;
    }

    PRINT_INTEGRALS(f1, 0, 1, (M_E - 1) / M_E);
    puts("");
    PRINT_INTEGRALS(f2, 0, 2, 1 - 3 / pow(M_E, 2));
    puts("");
    PRINT_INTEGRALS(f2, 0, 20, 1 - 21 / pow(M_E, 20));
    puts("");
    PRINT_INTEGRALS(f2, 0, 200, 1 - 201 / pow(M_E, 200));
    puts("");
    PRINT_INTEGRALS(sin, 0, 8 * M_PI, 0.0);

    return 0;
}
