unit ucfmpute;

{$mode delphi}

interface

uses
  Classes, SysUtils,
  xmatdefs,
  uauxiliares,
  uestados, uRecCFMP,
  ufechas, uodt_types;
(*** esta unidad es un intento de tener un administrador de estados capaz de leer
la salida del MP de UTE. No está probada **)

type

  { TAdminEstados_CFMPUTE }

  TAdminEstados_CFMPUTE = class(TAdminEstados)

    lstRecCFMP: TListaRecCFMP;
    constructor CreateLoadFromArchi(const archi_mus_, archi_pis: string;
      Sala_dtIni, Sala_dtFin: TFecha; Sala_HorasDelPaso: NReal);

    function CrearCF_AUX_para_enganaches_MPUTE(archi_mus, archi_pis: string;
      Sala_dtIni, Sala_dtFin: TFecha; Sala_HorasDelPaso: NReal): TAdminEstados_CFMPUTE;

    function CreateParasito: TAdminEstados; override;

    function costoEstrella({%H-}kpuntoT: integer): NReal; override;
    function costoContinuo({%H-}kPuntoT: integer): NReal; override;

    // calcula la derivadas respecto de la variabla cuyo índice es (irx) para
    // el punto de tiempo kpuntoT. La derivada dCdx_Inc es la calculada con
    // un incremento de x, la dCdx_Dec es calculada con un decremento.
    procedure devxr_estrella_20_(irx: integer; {%H-}kpuntoT: integer;
      out dCdx_Inc, dCdx_Dec: NReal); override;

    procedure devxr_continuo_20(irx: integer; {%H-}kpuntoT: integer;
      out dCdx_Inc, dCdx_Dec: NReal); override;

    procedure devxr_estrella_(irx: integer; {%H-}kpuntoT: integer;
      out dCdx_Inc, dCdx_Dec: NReal; out resCod: integer); override;

    procedure devxr_continuo(irx: integer; {%H-}kpuntoT: integer;
      out dCdx_Inc, dCdx_Dec: NReal; out resCod: integer;
    // -1 me fuir por abajo , 0 en la caja , 1 me fui por arriba
      out xrpos: NReal
    // Posición del punto en la cajita de paroximación en por unidad
      ); override;

    // Calcula la variación del costo por un incremento delta_xd en la variable ird
    // en el punto de tiempo kpuntoT
    function deltaCosto_vxd_estrella_({%H-}ird: integer; {%H-}kpuntoT: integer;
      {%H-}delta_xd: integer): NReal; override;
    function deltaCosto_vxd_continuo({%H-}ird: integer; {%H-}kpuntoT: integer;
      {%H-}delta_xd: integer): NReal; override;

    function deltaCosto_vxr_continuo_DosEstados_UTE(irx, irx2, kpuntoT: integer;
      delta_xr, delta_xr2: NReal): NReal; override;
    // delta costo sobre una coordenada real
    function deltaCosto_vxr_continuo(irx: integer; kpuntoT: integer;
      delta_xr: NReal): NReal; override;

  end;


implementation

function TAdminEstados_CFMPUTE.CrearCF_AUX_para_enganaches_MPUTE(archi_mus,
  archi_pis: string; Sala_dtIni, Sala_dtFin: TFecha; Sala_HorasDelPaso: NReal
  ): TAdminEstados_CFMPUTE;
var
  CFaux: TAdminEstados_CFMPUTE;
begin
  try
    CFaux := TAdminEstados_CFMPUTE.CreateLoadFromArchi(archi_mus,
      archi_pis, Sala_dtIni, Sala_dtFin, Sala_HorasDelPaso);
  except
    raise Exception.Create('Error al intentar leer CF_MP_UTE: ' +
      archi_mus + ' o ' + archi_pis);
  end;

  Result := CFaux;

end;



{ TAdminEstados_CFMPUTE }

constructor TAdminEstados_CFMPUTE.CreateLoadFromArchi(
  const archi_mus_, archi_pis: string; Sala_dtIni, Sala_dtFin: TFecha;
  Sala_HorasDelPaso: NReal);
var

  linea_pi: string;
  f_pi: TextFile;

  linea_mu: string;
  f_mu: TextFile;

  str_NIVEL_MU: string;
  str_MU: string;

  str_NIVEL_PI: string;
  str_ID_HIDRO: string;
  str_COTA: string;
  str_PI: string;

  xpi_bon: double;
  xpi_pal: double;
  xpi_sg: double;
  xpi_bay: double;

  xct_bon: double;
  xct_pal: double;
  xct_sg: double;
  xct_bay: double;

  rec: TRecCFMP;
  leer: boolean;
  i: integer;

  f: TextFile;
  r: TRecCFMP;
  CF0: double;
  CF: double;
  r1: TRecCFMP;

begin

  self.fechaIni := TFecha.Create_Clone(Sala_dtIni);
  self.fechaFin := TFecha.Create_Clone(Sala_dtFin);

  self.horasDelPaso := Sala_HorasDelPaso;
  nVarsContinuas := 3;
  nVarsDiscretas := 0;
  nPuntosT := 2;
  SetLength(xr_def, 3);
  xr_def[0] := TDefVarContinua.Create('Bonete_Vol', 'Hm3', 0, 100, 100);
  xr_def[1] := TDefVarContinua.Create('Palmar_Vol', 'Hm3', 0, 100, 100);
  xr_def[2] := TDefVarContinua.Create('SG_Vol', 'Hm3', 0, 100, 100);

  SetLength(xd_def, 0);
  constelacion_ := nil;
  SetLength(xr, 3);
  SetLength(xd, 0);


  SetLength(estrella_kr, 3);
  SetLength(estrella_kd, 0);

  ordinalEstrellaActual := 0;

  lstRecCFMP := TListaRecCFMP.Create;
  //Se abren los 2 archivos
  assignfile(f_mu, archi_mus_);
  {$I-}
  reset(f_mu);
  {$I+}
  if ioresult <> 0 then
    raise Exception.Create('No pude abrir archivo: ' + archi_mus_);

  assignfile(f_pi, archi_pis);
  {$I-}
  reset(f_pi);
  {$I+}
  if ioresult <> 0 then
    raise Exception.Create('No pude abrir archivo: ' + archi_pis);

  //Lee el encabezado
  readln(f_mu, linea_mu);
  //Lee los guiones
  readln(f_mu, linea_mu);
  //Lee el encabezado
  readln(f_pi, linea_pi);
  //Lee los guiones
  readln(f_pi, linea_pi);

  //Leo la primera fila de datos del achivo MU
  readln(f_mu, linea_mu);
  leer := True;
  while leer do
  begin

    //leo un nivel del archivo mu
    getPalHastaSep(str_NIVEL_MU, linea_mu, ' ');
    str_MU := trim(linea_mu);

    for i := 0 to 3 do
    begin
      readln(f_pi, linea_pi);
      getPalHastaSep(str_ID_HIDRO, linea_pi, ' ');
      getPalHastaSep(str_NIVEL_PI, linea_pi, ' ');
      getPalHastaSep(str_COTA, linea_pi, ' ');
      str_PI := trim(linea_pi);

      if str_ID_HIDRO = '1' then
      begin
        xpi_sg := StrToFloat(str_PI);
        xct_sg := StrToFloat(str_COTA);
      end;
      if str_ID_HIDRO = '2' then
      begin
        xpi_bon := StrToFloat(str_PI);
        xct_bon := StrToFloat(str_COTA);
      end;
      if str_ID_HIDRO = '3' then
      begin
        xpi_bay := StrToFloat(str_PI);
        xct_bay := StrToFloat(str_COTA);
      end;
      if str_ID_HIDRO = '4' then
      begin
        xpi_pal := StrToFloat(str_PI);
        xct_pal := StrToFloat(str_COTA);
      end;
    end;

    rec := TRecCFMP.Create(StrToInt(str_NIVEL_MU));
    rec.cargar_mu(StrToFloat(str_MU));
    rec.cargar_pi(xpi_bon, xpi_pal, xpi_sg, xpi_bay);
    rec.cargar_ct(xct_bon, xct_pal, xct_sg, xct_bay);

    lstRecCFMP.Add(rec);

    readln(f_mu, linea_mu);

    if ((linea_mu = '') or EOF(f_mu)) then
      leer := False;
  end;

  assignfile(f, 'C:\Users\fbarreto\Desktop\res.xlt');
  {$I-}
  Rewrite(f);
  {$I+}

  writeln(f, 'NIVEL' + #9 + 'ct_SG' + #9 + 'ct_bon' + #9 + 'ct_pal' +
    #9 + 'ct_bay' + #9 + 'V_sg_0' + #9 + 'V_bon_0' + #9 + 'V_pal_0' +
    #9 + 'V_bay_0' + #9 + 'mu' + #9 + 'pi_sg' + #9 + 'pi_bon' + #9 +
    'pi_pal' + #9 + 'pi_bay' + #9 + 'CF0' + #9 + 'CF' + #9 + 'CF-CF0' +
    #9 + 'nivelMax');


  for i := 0 to lstRecCFMP.Count - 1 do
  begin
    r := lstRecCFMP.Items[i];
    Write(f, r.nivel);
    Write(f, #9);

    Write(f, r.ct_sg);
    Write(f, #9);
    Write(f, r.ct_bon);
    Write(f, #9);
    Write(f, r.ct_pal);
    Write(f, #9);
    Write(f, r.ct_bay);
    Write(f, #9);

    Write(f, r.V_sg_0);
    Write(f, #9);
    Write(f, r.V_bon_0);
    Write(f, #9);
    Write(f, r.V_pal_0);
    Write(f, #9);
    Write(f, r.V_bay_0);
    Write(f, #9);

    Write(f, r.mu);
    Write(f, #9);

    Write(f, r.pi_sg);
    Write(f, #9);
    Write(f, r.pi_bon);
    Write(f, #9);
    Write(f, r.pi_pal);
    Write(f, #9);
    Write(f, r.pi_bay);
    Write(f, #9);

    CF0 := r.evalCF(r.V_bon_0, r.V_pal_0, r.V_sg_0, r.V_bay_0);
    Write(f, CF0);
    Write(f, #9);

    CF := lstRecCFMP.maxEvalRecCFMP(r.V_bon_0, r.V_pal_0, r.V_sg_0, r.V_bay_0, r1{%H-});
    Write(f, CF);
    Write(f, #9);

    Write(f, CF - CF0);
    Write(f, #9);
    writeln(f, r1.nivel);

  end;
  CloseFile(f);
end;

function TAdminEstados_CFMPUTE.CreateParasito: TAdminEstados;
var
  res: TAdminEstados_CFMPUTE;
begin
  res := TAdminEstados_CFMPUTE.Create(nVarsContinuas, nVarsDiscretas, nPuntosT );
  CompletarParasito( res );
  Result := res;
end;




function TAdminEstados_CFMPUTE.costoEstrella(kpuntoT: integer): NReal;
var
  c1: NReal;
  rec: TRecCFMP;

begin

  //c1:=lstRecCFMP.maxEvalRecCFMP(xr, xd);

  c1 := lstRecCFMP.maxEvalRecCFMP(xr[0], xr[1], xr[2] * 2, 0, rec);
  Result := c1;

end;

function TAdminEstados_CFMPUTE.costoContinuo(kPuntoT: integer): NReal;
var
  c1: NReal;
  rec: TRecCFMP;

begin

  //c1:=lstRecCFMP.maxEvalRecCFMP(xr, xd);

  c1 := lstRecCFMP.maxEvalRecCFMP(xr[0], xr[1], xr[2] * 2, 0, rec);
  Result := c1;

end;

procedure TAdminEstados_CFMPUTE.devxr_estrella_20_(irx: integer;
  kpuntoT: integer; out dCdx_Inc, dCdx_Dec: NReal);
var
  rec: TRecCFMP;

begin

  lstRecCFMP.maxEvalRecCFMP(xr[0], xr[1], xr[2] * 2, 0, rec);

  dCdx_Dec := rec.pi[irx];
  dCdx_Inc := dCdx_Dec;

end;

procedure TAdminEstados_CFMPUTE.devxr_continuo_20(irx: integer;
  kpuntoT: integer; out dCdx_Inc, dCdx_Dec: NReal);
var
  rec: TRecCFMP;

begin

  lstRecCFMP.maxEvalRecCFMP(xr[0], xr[1], xr[2] * 2, 0, rec);

  dCdx_Dec := rec.pi[irx];
  dCdx_Inc := dCdx_Dec;

end;

procedure TAdminEstados_CFMPUTE.devxr_estrella_(irx: integer; kpuntoT: integer;
  out dCdx_Inc, dCdx_Dec: NReal; out resCod: integer);
var
  rec: TRecCFMP;

begin

  lstRecCFMP.maxEvalRecCFMP(xr[0], xr[1], xr[2] * 2, 0, rec);

  dCdx_Dec := rec.pi[irx];
  dCdx_Inc := dCdx_Dec;
  resCod := 0;
end;

procedure TAdminEstados_CFMPUTE.devxr_continuo(irx: integer; kpuntoT: integer;
  out dCdx_Inc, dCdx_Dec: NReal; out resCod: integer; out xrpos: NReal);
var
  rec: TRecCFMP;

begin

  lstRecCFMP.maxEvalRecCFMP(xr[0], xr[1], xr[2] * 2, 0, rec);

  dCdx_Dec := rec.pi[irx];
  dCdx_Inc := dCdx_Dec;
  resCod := 0;
  xrpos := 0;

end;

function TAdminEstados_CFMPUTE.deltaCosto_vxd_estrella_(ird: integer;
  kpuntoT: integer; delta_xd: integer): NReal;
begin
  raise Exception.Create('Esta clase no soporta variables de estado discretas.');
  result:= 0;
end;

function TAdminEstados_CFMPUTE.deltaCosto_vxd_continuo(ird: integer;
  kpuntoT: integer; delta_xd: integer): NReal;
begin
  raise Exception.Create('Esta clase no soporta variables de estado discretas.');
  result:= 0;
end;

function TAdminEstados_CFMPUTE.deltaCosto_vxr_continuo_DosEstados_UTE(
  irx, irx2, kpuntoT: integer; delta_xr, delta_xr2: NReal): NReal;
var
  c1, c2, x1, x2: NReal;

begin
  c1 := costoContinuo(kpuntoT);
  x1 := xr[irx];
  x2 := xr[irx2];

  xr[irx] := xr[irx] + delta_xr;
  xr[irx2] := xr[irx2] + delta_xr2;

  c2 := costoContinuo(kpuntoT);

  xr[irx] := x1;
  xr[irx2] := x2;


  Result := c2 - c1;

end;

function TAdminEstados_CFMPUTE.deltaCosto_vxr_continuo(irx: integer;
  kpuntoT: integer; delta_xr: NReal): NReal;
var
  c1, c2, x1: NReal;

begin
  c1 := costoContinuo(kpuntoT);
  x1 := xr[irx];

  xr[irx] := xr[irx] + delta_xr;

  c2 := costoContinuo(kpuntoT);

  xr[irx] := x1;
  Result := c2 - c1;

end;


end.

