package optimizacion;

import operaciones.Matriz;

/**
 * <p>Title: Ejemplo de Aplicacion de la clase minimos basada en gradiente</p>
 * <p>Description: Minimiza la funcion f(x) </p>
 * <p>Copyright: Copyright (c) 2005</p>
 * <p>Company: UMSNH</p>
 * @author Dr. Felix Calderon Solorio
 * @version 1.0
 */

public class ejemplo_01 extends minimos {

    public static void main(String arg[])
    {
        ejemplo_01 aplica = new ejemplo_01();
        double x[] = {1,1};
        aplica.BFGS(new Matriz(x));
        aplica.Newton(new Matriz(x));
        aplica.Maximo_Descenso_Gradiente(new Matriz(x));
    }

    /**
     * Funcion a minimizar
     * @param x Matriz
     * @return double
     */

    public double funcion(Matriz x) {
        double f, x1 = x.obten(0, 0), x2 = x.obten(1, 0);

        f = (x1 - 2.0) * (x1 - 2.0) * (x1 - 2.0) * (x1 - 2.0) +
            (x1 - 2.0) * (x1 - 2.0) * x2 * x2 +
            (x2 + 1) * (x2 + 1);

        return f;
    }

    /**
     * Calcula el vector de primeras derivadas
     * @param x Matriz punto de evaluacion
     * @return Matriz vector gradiente
     */

    public Matriz Gradiente(Matriz x) {
        double x1, x2;
        double g[] = new double[2];

        x1 = x.obten(0, 0);
        x2 = x.obten(1, 0);

        g[0] = 4.0 * (x1 - 2.0) * (x1 - 2.0) * (x1 - 2.0) +
               2.0 * (x1 - 2.0) * x2 * x2;
        g[1] = 2.0 * (x1 - 2.0) * (x1 - 2.0) * x2 +
               2.0 * (x2 + 1);

        Matriz grad = new Matriz(g);
        return grad;
    }

    /**
     * Hessiano de la funci�n objetivo
     * @param x Matriz Punto de evaluaci�n
     * @return Matriz
     */

    public Matriz Hessiano(Matriz x) {
        double x1, x2;
        double h[][] = new double[2][2];

        x1 = x.obten(0, 0);
        x2 = x.obten(1, 0);

        h[0][0] = 12.0 * (x1 - 2.0) * (x1 - 2.0) + 2.0 * x2 * x2;
        h[0][1] = 4.0 * (x1 - 2.0) * x2;
        h[1][0] = 4.0 * (x1 - 2.0) * x2;
        h[1][1] = 2.0 * (x1 - 2.0) * (x1 - 2.0) + 2.0;

        Matriz hess = new Matriz(h);
        return hess;
    }
}
