//Rosenbrock's parabolic valley

unit uactor2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Math, xMatDefs, matreal,
  ubibfun_onl, udescripcionproblema_onl;

var
   my_idvar, my_ivae, my_ires : NInt;
   x_opt, mi_func_opt : NReal;

procedure opt_nvers(var ivar, ivae, ires: NInt);
procedure opt_cargue(p: TProblema_onl);
procedure opt_fijarRestriccionesDeCaja(p: TProblema_onl);
procedure opt_LeerSolucion(p: TProblema_onl);

implementation

procedure opt_nvers(var ivar, ivae, ires: NInt);
begin
     //guardo donde comienzan mis variables
     my_idvar := ivar;
     my_ivae := ivae;
     my_ires := ires;

     ivar := ivar + 2;   //agrego dos variables
end;

function rosenbrock(x: TVectR): NReal;
var
   x1, x2: NReal;
begin
     x1:=x.e(my_idvar);
     x2:=x.e(my_idvar+1);

     Result := 100*(x2-x1*x1)**2 + (1 - x1)**2;
end;

function d_rosenbrock_x1 ( x: TVectR; k: NInt): NReal;
var
   x1, x2: NReal;
begin
     x1:=x.e(my_idvar);
     x2:=x.e(my_idvar+1);

     Result := 100*(4*x1*x1*x1 - 4*x2*x1) + (2*x1 - 2);
end;

function d_rosenbrock_x2 ( x: TVectR; k: NInt): NReal;
var
   x1, x2: NReal;
begin
     x1:=x.e(my_idvar);
     x2:=x.e(my_idvar+1);

     Result := 100*(2*x2-2*x1*x1);
end;


procedure opt_cargue(p: Tproblema_onl);
var
   mf : TFunc_UD;
   idv: TDAOfNInt;
begin
     mf := TFunc_UD.Create_Init(2);
     setlength(idv, 2); idv[0]:=my_idvar; idv[1]:=my_idvar+1;
     mf.setIdVars(idv);
     mf.InscribirEcuacion(@rosenbrock);
     mf.InscribirDerivada(@d_rosenbrock_x1, 1);
     mf.InscribirDerivada(@d_rosenbrock_x2, 2);

     p.AgregarFObjetivo(mf);
end;

procedure opt_fijarRestriccionesDeCaja(p: TProblema_onl);
begin
    //sin terminar
end;

procedure opt_LeerSolucion(p: TProblema_onl);
begin
     x_opt := p.xval(my_idvar);
     mi_func_opt := p.fval();
end;


end.

