/**
 *  Auteur : MACHIZAUD Andr�a
 *  TD 02 - Heuristique
 *  Sujet : M�thode de Newton
 *  Fonction objectif pour l'optimisation d�terministe : f(x) = sin(x) - \frac{x^{4}}{4}
 *  D�riv� 1 : f'(x) = cos(x) - x^{3}
 *  D�riv� 2 : f''(x) = -sin(x) - 3x^{2}
 */
#include <math.h>

#include "newton.h"

static double solution = 0.865474033101;

double error(double value)
{
    return fabs(solution - value);
}

double power(double x, int pow)
{
    int i;
    double result = x;
    for(i=2;i<=pow;i++)
        result *= x;
    return result;
}

double g(double x)
{
    return sin(x) - (power(x,4)/4.0);
}

double g_1(double x)
{
    return cos(x) - power(x,3);
}

double g_2(double x)
{
    return - sin(x) - 3 * power(x,2);
}

double resolveByNewton(double x0, double epsilon, int max_iter)
{
    double old_error = -1, current_error;
    double current_iteration, old_iteration, diff;
    int counter = 0,i;

    old_iteration = x0;
//    printf("\n Valeur initiale : %f", old_iteration);

    do
    {
        // Calcul it�ration
//        printf("\n\nCalcul : x+1 = x - (f'(x)/f''(x)) -> %f - ( %f / %f )", old_iteration,g_1(old_iteration),g_2(old_iteration));
        current_iteration = old_iteration - ( g_1(old_iteration) / g_2(old_iteration) );
//        printf("\nCurrent iteration : %f\n", current_iteration);

        // Calcul de la diff�rence entre les deux vecteurs
        diff = fabs(current_iteration - old_iteration);
//        printf("\n\t->Difference : %f", diff);

        //Calcul de l'erreur
        current_error = error(current_iteration);

        printf("\n Erreur : %f",current_error);
        if(old_error != -1)
            printf(" [ difference ( %f ) ]",abs(current_error - old_error));

        // Pr�paration prochaine it�ration
        old_iteration = current_iteration;

        // Actualisation statistique sur l'erreur
        old_error = current_error;

        // Condition d'arr�t
//        printf("\n\t Diff > Epsilon ? (%f) > (%f) = %d",diff, epsilon,(diff > epsilon));
//        printf("\n\t Counter < max_iter ? (%d) > (%f) = %d",(counter+1), max_iter,((counter+1) < max_iter));
    }
    while( diff > epsilon && ++counter < max_iter );

    // Info Debug
    printf("\nCounter value : %d",counter);
    printf("\nDifference : %f",diff);
    printf("\nVecteur optimum : %f",current_iteration);
    printf("\nFunction value for x : %f",g(current_iteration));

    return current_iteration;
}
