#include <stdio.h> /* for input/output */
#include <math.h> /* for maths */
#define Accuracy 0.0001
#define NODEBUG

/* Newton-Raphson 
   
   loop
     d = f(x)/f'(x);
     x = x+d;
   until d is negligible;
   
*/

/* define f, f'. */

float Function(float x) { 
  return (x+1)*(x+0)*(x-1)*(x-2); 
  /*  return pow(x,3)+1; */
}

float Derivative(float x) { 
  return 4*pow(x,3)-6*pow(x,2)-2*x+2; 
  /*  return 3*pow(x,2); */
}

/* Perform Newton-Raphson */

main() {
  float CurrentGuess, CurrentFunction, CurrentDerivative, Delta;

  printf("Very Poor Newton-Raphson Implementation\nBy Ian Hickson\nRecompile code to change equation.\n");
  printf("Please select an initial guess: ");
  scanf("%f", &CurrentGuess);
  
  CurrentFunction = Function(CurrentGuess); /* cache current function result */
  CurrentDerivative = Derivative(CurrentGuess); /* cache current function derivative result */

  if (CurrentDerivative != 0) {
    do { 
      Delta = -CurrentFunction/CurrentDerivative;      
      CurrentGuess += Delta;
      CurrentFunction = Function(CurrentGuess); /* cache current function result */
      CurrentDerivative = Derivative(CurrentGuess); /* cache current function derivative result */
    } while ((CurrentDerivative != 0) && ((Delta > Accuracy) || (Delta < -Accuracy)));
  }

  if (CurrentFunction == 0) {
    printf ("%f is an exact root.\n", CurrentGuess);
  } else {
    if (CurrentDerivative == 0) {
      printf ("Derivative at %f is zero, could not continue.\n", CurrentGuess);
    } else {
      printf ("Best guess at root is %f. Last Delta was %f.\n", CurrentGuess, Delta);
    }
  }

}

/* KNOWN BUGS: 
    + Doesn't cope with a runaway function. 
    + Abs is not done as a function 
*/

