/*
   newton.c
   ========

   Determina uma aproximacao para uma raiz da equacao 

   f(x) = 0.

   Usa o metodo de Newton (tambem conhecido como
   Newton-Raphson).
 */

#include <stdio.h>
#include <math.h>

/**************************************************/

double f(double x);
double ff(double x, double h);
double Newton(double x, double h, double epsilon, int n);

/**************************************************/

int main()
{
  double x, h, epsilon, z;
  int n;

  printf("x, h, epsilon, n: ");
  scanf("%lf %lf %lf %d", &x, &h, &epsilon, &n);

  z = Newton(x, h, epsilon, n);

  printf("Zero que encontrei: %.20g\n", z);
  printf("f(%g) = %.20g\n", z, f(z));

  return 0;
}

/**************************************************/

/* f(): implementa a funcao f(x) */
double f(double x)
{
  return sin(x) - log(x);
}

/* ff(): devolve uma aproximacao da derivada de f(x) */
double ff(double x, double h)
{
  return (f(x + h) - f(x)) / h;
}

/* Newton(): implementa o metodo de Newton */
double Newton(double x, double h, double epsilon, int n)
{
  double y = x, yy = x;

  while (n > 0) {
    yy = y - f(y) / ff(y, h);
    n--;
    if ((yy - y < epsilon) && (y - yy < epsilon))
      break;
    y = yy;
  }

  return yy;
}
