unit uadminestadossobremuestreado;

{$mode delphi}

interface

uses
  Classes, SysUtils, xmatdefs,  uestados;

  type

  // Esta clase es para usar durante la simulación de una sala
  // colgada de una CF calculada durante una optimización de mayor
  // duración de paso de tiempo de integración. Por ejemplo, la Optimización
  // corresponde a la programación semanal con paso horario, mientras que la
  // simulación corresponde a una simulación de 72h con paso diezminutal (o horario)

  // Esta clase NO SE REGISTRA para tener persistencia, pues no se GUARDA
  // Cuando se crea lo hace en base a otro CF previamente guardado.
  { TAdminEstados_sobremuestreado }

  TAdminEstados_sobremuestreado = class(TAdminEstados)
    EsclavoCF: TAdminEstados;

    Sala_dtIni, Sala_dtFin: TDateTime;
    Sala_HorasDelPaso: NReal;
    Inicios_DeltaHoras: NReal;

    // auxiliares modificadas en cada cálculo
    kPuntoT1, kPuntoT2: integer;
    Peso1, Peso2: NReal;

    constructor CreateLoadFromArchi_(const archi: string;
      Sala_dtIni, Sala_dtFin: TdateTime; Sala_HorasDelPaso: NReal);

    function CreateParasito: TAdminEstados; override;
    procedure FreeParasito; override;
    procedure ClonarInfoadParasito( res: TAdminEstados ); override;


    function CalcAprox_kPuntosT(Sala_kPuntoT: integer): integer;

    function costoEstrella(kpuntoT: integer): NReal; override;
    function costoContinuo(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; kpuntoT: integer;
      out dCdx_Inc, dCdx_Dec: NReal); override;

    procedure devxr_continuo_20(irx: integer; kpuntoT: integer;
      out dCdx_Inc, dCdx_Dec: NReal); override;

    procedure devxr_estrella_(irx: integer; kpuntoT: integer;
      out dCdx_Inc, dCdx_Dec: NReal; out resCod: integer); override;

    procedure devxr_continuo(irx: integer; 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_(ird: integer; kpuntoT: integer;
      delta_xd: integer): NReal; override;
    function deltaCosto_vxd_continuo(ird: integer; kpuntoT: integer;
      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;


    destructor destroy; override;
  end;



implementation




constructor TAdminEstados_sobremuestreado.CreateLoadFromArchi_(
  const archi: string; Sala_dtIni, Sala_dtFin: TdateTime; Sala_HorasDelPaso: NReal);
begin
  EsclavoCF:= TAdminEstados.CreateReadFromArchi( archi );
  inherited Create( EsclavoCF.nVarsContinuas, EsclavoCF.nVarsDiscretas, EsclavoCF.nPuntosT-2 );

  EsclavoCF.ClonarCursorParasito( self );
  self.Sala_dtIni := Sala_dtIni;
  self.Sala_dtFin := Sala_dtFin;
  self.Sala_HorasDelPaso := Sala_HorasDelPaso;
  Inicios_DeltaHoras := (Sala_dtIni - EsclavoCF.fechaIni.dt) * 24.0;
end;

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

procedure TAdminEstados_sobremuestreado.FreeParasito;
begin
  EsclavoCF.FreeParasito;
  EsclavoCF:= nil;
  inherited FreeParasito;
end;

procedure TAdminEstados_sobremuestreado.ClonarInfoadParasito(res: TAdminEstados
  );
var
  resx: TAdminEstados_sobremuestreado;
begin
  resx:= res as TAdminEstados_sobremuestreado;
  resx.EsclavoCF:= EsclavoCF.CreateParasito;
  resx.Sala_dtIni:= Sala_dtIni;
  resx.Sala_dtFin:= Sala_dtFin;
  resx.Sala_HorasDelPaso:= Sala_HorasDelPaso;
  resx.Inicios_DeltaHoras:= Inicios_DeltaHoras;
end;


function TAdminEstados_sobremuestreado.CalcAprox_kPuntosT(
  Sala_kPuntoT: integer): integer;

var
  dh: NReal;
  kr: NReal;
begin
  dh := Inicios_DeltaHoras + (Sala_kPuntoT - 1) * Sala_HorasDelPaso;
  kr := dh / horasDelPaso;
  kPuntoT1 := trunc(kr) + 1;
  Peso2 := frac(kr);
  Peso1 := 1 - Peso2;
  kPuntoT2 := kPuntoT1 + 1;

  if Peso1 < 0.1 then
    Result := 2
  else if Peso2 < 0.1 then
    Result := 1
  else
    Result := 0;

  //  writeln( Sala_KPuntoT, ', ', kPuntoT1,', ', kPUntoT2 );

end;

function TAdminEstados_sobremuestreado.costoEstrella(kpuntoT: integer): NReal;
var
  c1, c2: NReal;
  rescod: integer;
begin
  rescod := CalcAprox_kPuntosT(kpuntoT);
  case rescod of
    0:
    begin
      c1 := EsclavoCF.CostoEstrella(kPuntoT1);
      c2 := EsclavoCF.CostoEstrella(kPuntoT2);
      Result := peso1 * c1 + peso2 * c2;
    end;
    1: Result := EsclavoCF.CostoEstrella(kPuntoT1);
    2: Result := EsclavoCF.CostoEstrella(kPuntoT2);
  end;
end;


function TAdminEstados_sobremuestreado.costoContinuo(kPuntoT: integer): NReal;
var
  c1, c2: NReal;
  rescod: integer;
begin
  rescod := CalcAprox_kPuntosT(kpuntoT);
  case rescod of
    0:
    begin
      c1 := EsclavoCF.CostoContinuo(kPuntoT1);
      c2 := EsclavoCF.CostoContinuo(kPuntoT2);
      Result := peso1 * c1 + peso2 * c2;
    end;
    1: Result := EsclavoCF.CostoContinuo(kPuntoT1);
    2: Result := EsclavoCF.CostoContinuo(kPuntoT2);
  end;
end;


// 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 TAdminEstados_sobremuestreado.devxr_estrella_20_(irx: integer;
  kpuntoT: integer; out dCdx_Inc, dCdx_Dec: NReal);
var
  dCdx_Inc1, dCdx_Inc2: NReal;
  dCdx_Dec1, dCdx_Dec2: NReal;

  rescod: integer;
begin
  rescod := CalcAprox_kPuntosT(kpuntoT);
  case rescod of
    0:
    begin
      EsclavoCF.devxr_estrella_20_(irx, kPuntoT1, dCdx_Inc1, dCdx_Dec1);
      EsclavoCF.devxr_estrella_20_(irx, kPuntoT2, dCdx_Inc2, dCdx_Dec2);
      dCdX_Inc := peso1 * dCdX_Inc1 + peso2 * dCdX_Inc2;
      dCdX_Dec := peso1 * dCdX_Dec1 + peso2 * dCdX_Dec2;
    end;
    1: EsclavoCF.devxr_estrella_20_(irx, kPuntoT1, dCdx_Inc, dCdx_Dec);
    2: EsclavoCF.devxr_estrella_20_(irx, kPuntoT2, dCdx_Inc, dCdx_Dec);
  end;
end;


procedure TAdminEstados_sobremuestreado.devxr_continuo_20(irx: integer;
  kpuntoT: integer; out dCdx_Inc, dCdx_Dec: NReal);
var
  dCdx_Inc1, dCdx_Inc2: NReal;
  dCdx_Dec1, dCdx_Dec2: NReal;
  rescod: integer;
begin
  rescod := CalcAprox_kPuntosT(kpuntoT);
  case rescod of
    0:
    begin
      EsclavoCF.devxr_continuo_20(irx, kPuntoT1, dCdx_Inc1, dCdx_Dec1);
      EsclavoCF.devxr_continuo_20(irx, kPuntoT2, dCdx_Inc2, dCdx_Dec2);
      dCdX_Inc := peso1 * dCdX_Inc1 + peso2 * dCdX_Inc2;
      dCdX_Dec := peso1 * dCdX_Dec1 + peso2 * dCdX_Dec2;
    end;
    1: EsclavoCF.devxr_continuo_20(irx, kPuntoT1, dCdx_Inc, dCdx_Dec);
    2: EsclavoCF.devxr_continuo_20(irx, kPuntoT2, dCdx_Inc, dCdx_Dec);
  end;
end;


procedure TAdminEstados_sobremuestreado.devxr_estrella_(irx: integer;
  kpuntoT: integer; out dCdx_Inc, dCdx_Dec: NReal; out resCod: integer);
var
  dCdx_Inc1, dCdx_Inc2: NReal;
  dCdx_Dec1, dCdx_Dec2: NReal;
  rrescod: integer;
begin
  rrescod := CalcAprox_kPuntosT(kpuntoT);
  case rrescod of
    0:
    begin
      EsclavoCF.devxr_estrella_(irx, kPuntoT1, dCdx_Inc1, dCdx_Dec1, resCod);
      EsclavoCF.devxr_estrella_(irx, kPuntoT2, dCdx_Inc2, dCdx_Dec2, resCod);
      dCdX_Inc := peso1 * dCdX_Inc1 + peso2 * dCdX_Inc2;
      dCdX_Dec := peso1 * dCdX_Dec1 + peso2 * dCdX_Dec2;
    end;
    1: EsclavoCF.devxr_estrella_(irx, kPuntoT1, dCdx_Inc, dCdx_Dec, resCod);
    2: EsclavoCF.devxr_estrella_(irx, kPuntoT2, dCdx_Inc, dCdx_Dec, resCod);
  end;
end;


procedure TAdminEstados_sobremuestreado.devxr_continuo(irx: integer;
  kpuntoT: integer; out dCdx_Inc, dCdx_Dec: NReal; out resCod: integer; out
  xrpos: NReal);

var
  dCdx_Inc1, dCdx_Inc2: NReal;
  dCdx_Dec1, dCdx_Dec2: NReal;
  rrescod: integer;
begin

  rrescod := CalcAprox_kPuntosT(kpuntoT);
  case rrescod of
    0:
    begin
      EsclavoCF.devxr_continuo(irx, kPuntoT1, dCdx_Inc1, dCdx_Dec1, resCod, xrpos);
      EsclavoCF.devxr_continuo(irx, kPuntoT2, dCdx_Inc2, dCdx_Dec2, resCod, xrpos);
      dCdX_Inc := peso1 * dCdX_Inc1 + peso2 * dCdX_Inc2;
      dCdX_Dec := peso1 * dCdX_Dec1 + peso2 * dCdX_Dec2;
    end;
    1: EsclavoCF.devxr_continuo(irx, kPuntoT1, dCdx_Inc, dCdx_Dec, resCod, xrpos);
    2: EsclavoCF.devxr_continuo(irx, kPuntoT2, dCdx_Inc, dCdx_Dec, resCod, xrpos);
  end;
end;


// Calcula la variación del costo por un incremento delta_xd en la variable ird
// en el punto de tiempo kpuntoT
function TAdminEstados_sobremuestreado.deltaCosto_vxd_estrella_(ird: integer;
  kpuntoT: integer; delta_xd: integer): NReal;
var
  c1, c2: NReal;
  rescod: integer;
begin
  rescod := CalcAprox_kPuntosT(kpuntoT);
  case rescod of
    0:
    begin
      c1 := EsclavoCF.deltaCosto_vxd_estrella_(ird, kPuntoT1, delta_xd);
      c2 := EsclavoCF.deltaCosto_vxd_estrella_(ird, kPuntoT2, delta_xd);
      Result := peso1 * c1 + peso2 * c2;
    end;
    1: Result := EsclavoCF.deltaCosto_vxd_estrella_(ird, kPuntoT1, delta_xd);
    2: Result := EsclavoCF.deltaCosto_vxd_estrella_(ird, kPuntoT2, delta_xd);
    else
      raise Exception.Create('rescod invalido' );
  end;
end;

function TAdminEstados_sobremuestreado.deltaCosto_vxd_continuo(ird: integer;
  kpuntoT: integer; delta_xd: integer): NReal;
var
  c1, c2: NReal;
  rescod: integer;
begin
  rescod := CalcAprox_kPuntosT(kpuntoT);
  case rescod of
    0:
    begin
      c1 := EsclavoCF.deltaCosto_vxd_continuo(ird, kPuntoT1, delta_xd);
      c2 := EsclavoCF.deltaCosto_vxd_continuo(ird, kPuntoT2, delta_xd);
      Result := peso1 * c1 + peso2 * c2;
    end;
    1: Result := EsclavoCF.deltaCosto_vxd_continuo(ird, kPuntoT1, delta_xd);
    2: Result := EsclavoCF.deltaCosto_vxd_continuo(ird, kPuntoT2, delta_xd);
    else
      raise Exception.Create('rescod invalido' );

  end;
end;


function TAdminEstados_sobremuestreado.deltaCosto_vxr_continuo_DosEstados_UTE(
  irx, irx2, kpuntoT: integer; delta_xr, delta_xr2: NReal): NReal;
  // delta costo sobre una coordenada real
var
  c1, c2: NReal;
  rescod: integer;
begin
  rescod := CalcAprox_kPuntosT(kpuntoT);
  case rescod of
    0:
    begin
      c1 := EsclavoCF.deltaCosto_vxr_continuo_DosEstados_UTE(
        irx, irx2, kPuntoT1, delta_xr, delta_xr2);
      c2 := EsclavoCF.deltaCosto_vxr_continuo_DosEstados_UTE(
        irx, irx2, kPuntoT2, delta_xr, delta_xr2);
      Result := peso1 * c1 + peso2 * c2;
    end;
    1: Result := EsclavoCF.deltaCosto_vxr_continuo_DosEstados_UTE(
        irx, irx2, kPuntoT1, delta_xr, delta_xr2);
    2: Result := EsclavoCF.deltaCosto_vxr_continuo_DosEstados_UTE(
        irx, irx2, kPuntoT2, delta_xr, delta_xr2);
    else
      raise Exception.Create('rescod invalido' );

  end;
end;


function TAdminEstados_sobremuestreado.deltaCosto_vxr_continuo(irx: integer;
  kpuntoT: integer; delta_xr: NReal): NReal;
var
  c1, c2: NReal;
  rescod: integer;
begin
  rescod := CalcAprox_kPuntosT(kpuntoT);
  case rescod of
    0:
    begin
      c1 := EsclavoCF.deltaCosto_vxr_continuo(irx, kPuntoT1, delta_xr);
      c2 := EsclavoCF.deltaCosto_vxr_continuo(irx, kPuntoT2, delta_xr);
      Result := peso1 * c1 + peso2 * c2;
    end;
    1: Result := EsclavoCF.deltaCosto_vxr_continuo(irx, kPuntoT1, delta_xr);
    2: Result := EsclavoCF.deltaCosto_vxr_continuo(irx, kPuntoT2, delta_xr);
    else
      raise Exception.Create('rescod invalido' );

  end;
end;

destructor TAdminEstados_sobremuestreado.destroy;
begin
  if EsclavoCF <> nil then
    EsclavoCF.Free;
  inherited destroy;
end;


end.

