package ejemplos;

/**
 * <p>Title: Optimización
 * <p>Description: Se presentan varios métodos para minimizar una función</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: UMSNH</p>
 * @author Dr. Felix Calderon S.
 * @version 1.0
 */

public class ej031 {
  public static void main(String[] args) {
    //Seccion_Dorada();
    //Interpolacion_Cuadratica();
    Newton();
  }

  public static void Seccion_Dorada()
  {
    double xL, xU, x1, x2, fL, fU, f1, f2;
    double d, R = (Math.sqrt(5)-1.0)/2.0;
    int i = 0;

    xL = 0;
    xU = 4.0;

    System.out.println("i" + "\t" + "xL" + "\t" + "fL" + "\t" + "x2" + "\t" + "f2" +
                             "\t" + "x1" + "\t" + "f1" + "\t" + "xU" + "\t" + "fU" +
                             "\t" + "d");
    do
    {
      d  = R*(xU - xL);
      x1 = xL + d;
      x2 = xU - d;

      fU = funcion(xU);
      fL = funcion(xL);
      f1 = funcion(x1);
      f2 = funcion(x2);

      System.out.println(i++ + "\t" + xL + "\t" + fL + "\t" + x2 + "\t" + f2 +
                               "\t" + x1 + "\t" + f1 + "\t" + xU + "\t" + fU +
                               "\t" + d);

      if(f1 > f2) xL = x2;
      else xU = x1;


    }while(d > 0.001);

  }

  public static void Interpolacion_Cuadratica()
  {
    double x0, x1, x2, x3;
    double f0, f1, f2, num, den;

    int i = 0;

    x0 = 0;
    x1 = 1;
    x2 = 4;

    System.out.println("i" + "\t" + "x0" + "\t" + "f0" + "\t" + "x1" + "\t" + "f1" +
                             "\t" + "x2" + "\t" + "f2" + "\t" + "x3" + "\t" + "f3");
    do
    {
      f0 = funcion(x0);
      f1 = funcion(x1);
      f2 = funcion(x2);

      den = f0*(x1*x1 - x2*x2) + f1*(x2*x2 - x0*x0) + f2*(x0*x0 - x1*x1);
      num = f0*(x1 - x2) + f1*(x2 - x0) + f2*(x0 - x1);
      x3 = den/(2.0*num);


      System.out.println(i++ + "\t" + x0 + "\t" + f0 + "\t" + x1 + "\t" + f1 +
                               "\t" + x2 + "\t" + f2 + "\t" + x3 + "\t" + funcion(x3) );
      if(x0 <= x3 && x3 <= x1)
      {
        x2 = x1;
        x1 = x3;
      }
      else
      {
        x0 = x1;
        x1 = x3;
      }
    }while(x3-x0 >= 0.0001);
  }

  static public void Newton()
  {
    double x0 = 2.5, x;
    int i;

    System.out.println("i" + "\t" + "x0" + "\t" + "x1");
    for(i=1; i<1000; i++)
    {
      x = x0 - Df(x0)/DDf(x0);

      System.out.println(i + "\t" + x0 + "\t" + x);

      if(Math.abs(x-x0) <= 0.0001) break;
      else x0 = x;
    }
  }

  public static double funcion(double x)
  {
    return 2.0*Math.sin(x) - x*x/10.0;
  }

  public static double Df(double x)
  {
    return 2.0*Math.cos(x) - 2.0*x/10.0;
  }

  public static double DDf(double x)
  {
    return -2.0*Math.sin(x) - 2.0/10.0;
  }
}