unit uexploradorCF;

{$MODE Delphi}


interface

uses
  SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls,
  xmatdefs, uEstados, ufechas, AlgebraC, MatReal, MatCPX, IntPoint,
  isocurvas, utrazosxy, usigmoide, uneuronas,
  utipos_xcf,
  uInicioYFinal,
  ufxgx, uresfxgx, uproblema,
  uescalacolores, uparseadorsupersimple, uauxiliares, Math,
  u_kml_map_util, uplot,
  u_latlon_utm, fddp, uparsimoniat,ulearningcfcerebros,
  uExcelFile, //ucolectorsr3,
  //u_ExcelFile,
  ugoogle_altitude, uPrintCronVars, uHistoVarsOps;

type

    { TProblema_Cerebro }

  TProblema_Cerebro = class(TProblema_m01)
    function Monitor(const X, Xs: TVectR; f, fs: NReal; paso_ok: boolean): boolean;
      override;
  end;


   { TArchivoXLT }

  TArchivoXLT = class( TMatR )
    id: string;
    archi: string;
    encabezado: TStringList;
    cols: TStringList;
    fechas: TVectR;
    constructor CreateFromXLT( id: string;  archi: string );
    destructor destroy; override;
    procedure ParseCols( r: string );
  end;

  { TForm1 }

  TForm1 = class(TForm)
    btAproxNeuron01: TButton;
    btBellmanParaOpergen: TButton;
    btCalcAproLin: TButton;
    btCFSelect: TButton;
    btCopiarYTranspornerUltima7Filas: TButton;
    btCrearCerebro: TButton;
    btDibujarNeuronas: TButton;
    bTest02: TButton;
    btIsoCurvas: TButton;
    btLoadCF: TButton;
    btTest01: TButton;
    btVer: TButton;
    bt_DumpToXlt: TButton;
    btScanAltitudes: TButton;
    Button1: TButton;
    btCompress16: TButton;
    btTestMX1overX: TButton;
    btAddNeurona: TButton;
    AproxN01ConPars: TButton;
    Button2: TButton;
    cbAuto: TCheckBox;
    cbOrdenarPorCF: TCheckBox;
    cbSaveCerebro: TCheckBox;
    cbTipoSaturacion: TComboBox;
    cbTipoSaturacionInternas: TComboBox;
    cbClearCanvas: TCheckBox;
    cbParsimonia: TCheckBox;
    cbBPconParsimonia: TCheckBox;
    cbMaxInBox: TCheckBox;
    eDimensionEspacioX: TLabeledEdit;
    eMomento: TEdit;
    ekPaso: TEdit;
    eFechaIni: TLabeledEdit;
    eFechaFin: TLabeledEdit;
    ekPasoT: TLabeledEdit;
    eFechaDelPasoT: TLabeledEdit;
    eNeuronasPorCapa: TLabeledEdit;
    eNPasosT: TLabeledEdit;
    eDimX: TLabeledEdit;
    ePaso: TEdit;
    eValCosto: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    memo_scanaltitudes: TMemo;
    nPuntosLon: TLabeledEdit;
    nPuntosLat: TLabeledEdit;
    Lon2: TLabeledEdit;
    Lat2: TLabeledEdit;
    Lon1: TLabeledEdit;
    Lat1: TLabeledEdit;
    Memo1: TMemo;
    mseval: TMemo;
    OpenDialog1: TOpenDialog;
    PageControl1: TPageControl;
    PaintBox1: TPaintBox;
    PaintBox2: TPaintBox;
    Panel1: TPanel;
    sbKPaso: TScrollBar;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    TabSheet4: TTabSheet;
    btConvertir178: TToggleBox;
    ToggleBox1: TToggleBox;
    procedure btAddNeuronaClick(Sender: TObject);
    procedure btAproxNeuron01Click(Sender: TObject);
    procedure btCalcAproLinClick(Sender: TObject);
    procedure btCFSelectClick(Sender: TObject);
    procedure btCompress16Click(Sender: TObject);
    procedure btConvertir178Change(Sender: TObject);
    procedure btCrearCerebroClick(Sender: TObject);
    procedure btDibujarNeuronasClick(Sender: TObject);
    procedure btIsoCurvasClick(Sender: TObject);
    procedure btScanAltitudesClick(Sender: TObject);
    procedure btTest01Click(Sender: TObject);
    procedure btVerClick(Sender: TObject);
    procedure bt_DumpToXltClick(Sender: TObject);
    procedure btBellmanParaOpergenClick(Sender: TObject);
    procedure btCopiarYTranspornerUltima7FilasClick(Sender: TObject);
    procedure bTest02Click(Sender: TObject);
    procedure btLoadCFClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure AproxN01ConParsClick(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure cbAutoChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure sbKPasoChange(Sender: TObject);
  private
    procedure PlotIsoCurvas(M: TMatR; vx, vy: TVectR; M2: TMatR;
      vx2, vy2: TVectR; niveles: array of NReal; etiquetas: array of string);
    { Private declarations }
  public
    { Public declarations }
    CF: TAdminEstados;
    kPasoT: integer;
    evaluador: TEvaluadorExpresionesSimples;
    mcf: TMatR;
    vx, vy: TVectR;
    mcf2: TMatR;
    vx2, vy2: TVectR;
    niveles: TDAOfNReal;
    etiquetas: TDAOfString;
    escalaColor: TEscalaColor;

    arrCntNeuronasPOrCapa: TDAofNInt;

    flgEscalado: boolean;

    // dimensiones del esapcio de estado del CF cargado.
    Dim_EspacioX: integer;
    Cerebro_: TCerebro;

    // Para exportar un KML
    aDoc_KML: TKML_Document;


    Cerebros, aCerebros: TDAOfCerebros;
    parsimonia: TParsimonia;
    XCF_: TMatOfRecXCF;

    paso: NReal;
    momento: NReal;

    maxCF: NReal;
    grad_ant, X: TVectR;
    CFX_fEntrenador: TCF_fCerebrosConParsimonia;

    PaintBox, ConExcel: Boolean;

    CronVarCF_aprox:TCronVar;
    probabilidadAisladas: TDAofNReal;
    xlt: TExcelFile;
    kIter_archi, nPR, nPP:Integer;

    function cargar( archi_nombre: string ): TArchivoXLT;

  end;






var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TArchivoXLT }

constructor TArchivoXLT.CreateFromXLT(id: string; archi: string);
var
  f: TextFile;
  renglones: TStringList;
  flgLeyendoEncabezado: boolean;
  flgFin: boolean;
  r: string;
  kPaso: integer;
  aVal: NReal;
  jCol, kPaso_: integer;

begin
  self.id:= id;
  self.archi:= archi;
  filemode:= 0;
  assignfile( f, self.archi );
  reset( f );
  encabezado:= TStringList.Create;
  renglones:= TStringList.Create;
  cols:= TStringList.Create;

  flgLeyendoEncabezado:= true;
  flgFin:= false;
  while (not Eof( f ) ) and ( not flgFin ) do
  begin
    readln( f, r );
    if r = '' then
    begin
      flgFin:= true;
      continue;
    end;

    if flgLeyendoEncabezado then
    begin
      encabezado.Add( r );
      if pos( 'paso', r ) = 1 then
      begin
        flgLeyendoEncabezado:= false;
        parseCols( r );
      end
    end
    else
      renglones.add( r );
  end;
  closefile( f );

  inherited Create_Init( renglones.count, cols.Count );
  fechas:= TVectR.Create_init( nf );
  for kPaso:= 1 to nf do
  begin
    r:= renglones[kPaso - 1 ];
    kPaso_:= NextInt( r, #9 );
    if kPaso <> kPaso_ then raise Exception.Create( 'Se esperaba paso: '+IntToStr( kPaso ) );
    aval:= NextFloat( r, #9 );
    fechas.pon_e( kPaso_, aval );
    for jCol:= 1 to nc do
    begin
      aval:= NextFloat( r, #9 );
      pon_e( kPaso, jCol, aVal );
    end;
  end;

  renglones.Free;
end;

destructor TArchivoXLT.destroy;
begin
  cols.Free;
  encabezado.Free;
  fechas.Free;
  inherited destroy;
end;

procedure TArchivoXLT.ParseCols(r: string);
var
  pal: string;
begin
  pal:= getNextPalSep( r, #9 );
  while r <> '' do
  begin
     cols.Add( pal );
     pal:= getNextPalSep( r, #9 );
  end;
end;
{ TProblema_Cerebro }

function TProblema_Cerebro.Monitor(const X, Xs: TVectR; f, fs: NReal;
  paso_ok: boolean): boolean;
var
  kPaso, kRec, kParam, nPasos, kPR, kPP: Integer;
  aRec: TRecXCF;
  CF_real, CFAprox, error2: NReal;
  CFX_Entrenador_f: TCF_fCerebros;
  HistoCF_aprox: TPrintCronVar_histograma;

  CronVarParam: TCronVar;

begin
 // Result:=inherited Monitor(X, Xs, f, fs, paso_ok);



  if (flg_Monitor = false) or (abs(X.normEuclid - Xs.normEuclid) < 1E-1) then
  begin
     Result := False;
     Exit;
  end;

 ////////////////////////////////terminar ////////

  CronVarParam:= TCronVar.Create('Parametros');
  CronVarParam.inicializar(Form1.nPP, Form1.nPR, 0, 1);

  nPasos:= Form1.CF.nPuntosT;


  kParam:= Form1.nPR * nPasos;

  for kPR:=1 to Form1.nPR do
    for kPP:=1 to Form1.nPP do
    begin
      kParam:= kParam + Form1.nPR*(kPP - 1) + 1;
      CronVarParam.Enter(kPR-1);
      CronVarParam.valores[kPP]:= Xs.e(kParam);
    end;

  ///////////////////////////////////////////

  CFX_Entrenador_f:= TCF_fCerebros.Create(Form1.aCerebros, Form1.XCF_);

  CFX_Entrenador_f.SetParametrosCerebros(Xs);

  error2:=0;

  for kPaso:=1 to High(Form1.aCerebros) do
  begin
    Form1.CronVarCF_aprox.Enter(kPaso - 1);
    for kRec := 0 to high(Form1.XCF_[kPaso - 1]) do
    begin
      aRec := Form1.XCF_[kPaso - 1][kRec];
      CF_real := aRec.CF;

      Form1.aCerebros[kPaso].SetEntradas(aRec.X);

      Form1.aCerebros[kPaso].evaluar;
      CFAprox := Form1.aCerebros[kPaso].Salida_CapaN.Neuronas[0].salida;
      Form1.CronVarCF_aprox.valores[kRec]:= CFAprox;

      if abs(CFAprox) < 1e10 then
        error2 := error2 + sqr(CFAprox - CF_real);
    end;

    error2 := sqrt(error2 / high(Form1.XCF_[kPaso - 1]));


    if Form1.PaintBox then
      Form1.PaintBox2.Canvas.LineTo(
              trunc((kpaso - 1) / length(Form1.XCF_) * Form1.PaintBOx2.Width),
              trunc(Form1.PaintBox2.Height * (1 - (error2/ Form1.maxCF))));

  end;


  if Form1.ConExcel then
  begin
    HistoCF_aprox := TPrintCronVar_histograma.Create(Form1.CronVarCF_aprox, 'CF_aprox'+ IntToStr(Form1.kIter_archi),
      'CF_aprox'+IntToStr(Form1.kIter_archi), 'MUSD', 4, 2, True, True, False, True, Form1.probabilidadAisladas, True,
      False, True, -Form1.maxCF, Form1.maxCF);
   // xlt := TExcelFile.Create('Histo', 'CF');

    HistoCF_aprox.imprimirse(Form1.xlt);
    Inc(Form1.kIter_archi);
   end;

 // CFX_Entrenador_f.SetParametrosCerebros(X);

 {for kPaso:=1 to high(Form1.Cerebros) do
    aCerebros[kPaso].Free;    }

    CronVarParam.Free;

  Result := False;
end;


procedure TForm1.btBellmanParaOpergenClick(Sender: TObject);
var
  archi: string;
  fCosto: TMatOfNReal;
  nPasos, nEstrellas: integer;
  kPasoT: integer;
  anio, semana, H, Stock: integer;
  dCFdX_Inc, dCFdX_Dec: NReal;
  fecha: TFecha;
  semana_: integer;
  fsal_bellman: textfile;
  error_str: string;
  CF1, CF2: NReal;

begin

  if OpenDialog1.Execute then
  begin
    if CF <> nil then
      CF.Free;
    archi := OpenDialog1.FileName;
    CF := TAdminEstados.CreateReadFromArchi(archi);

    // antes de seguir chequeamos que se trate de una CF
    // con solo dos variables de estado y que sean Bonete y H en ese orden.
    error_str := '';
    if CF.nVarsContinuas <> 2 then
      error_str := error_str + '; CF.nVarsContinuas <> 2';
    if CF.nVarsDiscretas <> 0 then
      error_str := error_str + '; CF.nVarsDiscretas <> 2';
    if CF.xr_def[0].NPuntos <= 1 then
      error_str := error_str + '; CF.xr_def[0].NPuntos <= 1';
    if CF.xr_def[0].nombre <> 'Bonete_Vol' then
      error_str := error_str + '; CF.xr_def[0].nombre <> ''Bonete_Vol''';
    if CF.xr_def[1].nombre <> 'Estado_H' then
      error_str := error_str + '; CF.xr_def[1].nombre <> ''Estado_H''';
    if error_str <> '' then
    begin
      CF.Free;
      CF := nil;
      raise Exception.Create('El archivo CF.bin no tiene las definiciones esperadas.' +
        error_str);
    end;

    fecha := TFecha.Create_Clone(CF.fechaIni);
    //    fCosto := CF.constelacion.fCosto;
    nPasos := CF.nPuntosT;
    nEstrellas := CF.nEstrellasPorPuntoT;


    assignfile(fsal_bellman, 'bellman_paraOperGen.txt');
    rewrite(fsal_bellman);

    semana_ := 0;
    for kPasoT := 1 to nPasos - 1 do
    begin
      anio := fecha.anio;
      semana := fecha.semana52;
      if semana_ <> semana then
      begin
        semana_ := semana;
        for H := 1 to CF.xr_def[1].NPuntos do
          for Stock := 0 to CF.xr_def[0].NPuntos - 1 do
          begin
(*
            // Posicionamos el estado Borde inferior del stock
            CF.xr[0] := CF.xr_def[0].x[stock - 1];
            CF.xr[1] := CF.xr_def[1].x[H - 1];
            // Guardamos el valor de Bellman en el extremo inferior
            CF1      := CF.costoContinuo(kPasoT);
*)
            // Posicionamos el estado Borde superior del stock
            CF.xr[0] := CF.xr_def[0].x[stock];
            CF.xr[1] := CF.xr_def[1].x[H - 1];
            // Guardamos el valor de Bellman en el extremo inferior
            CF2 := CF.costoContinuo(kPasoT);


          (*  imprimimos según formato enviado por Milton
          AÑO      NUMBER(4)
          SEMANA   NUMBER(2)
          CLASE    NUMBER(2)
          PASO     NUMBER(2)
          BELLMAN  NUMBER(15,3)
           *)
           (*
            writeln(fsal_bellman, anio: 4, ' ', semana: 2, ' ', H: 2, ' ',
              Stock: 2, (CF1 + CF2) / 2.0: 15: 3);
*)
            writeln(fsal_bellman, anio: 4, ' ', semana: 2, ' ', H: 2, ' ',
              Stock: 2, CF2: 15: 3);

          end;
      end;
      fecha.dt := fecha.dt + CF.horasDelPaso / 24.0;
    end;
    closefile(fsal_bellman);
  end;
end;

procedure TForm1.bt_DumpToXltClick(Sender: TObject);
var
  archi: string;
  fCosto: TMatOfNReal;
  nPasos, nEstrellas: integer;
  k, j: integer;
begin
  if OpenDialog1.Execute then
  begin
    if CF <> nil then
      CF.Free;
    archi := OpenDialog1.FileName;
    CF := TAdminEstados.CreateReadFromArchi(archi);
    CF.WriteToArchi(ChangeFileExt(archi, '.xlt'));
    CF.Free;
    CF := nil;
  end;
end;

procedure TForm1.btCalcAproLinClick(Sender: TObject);
var
  archi: string;
  kPasoT: integer;

  XXt: TMatR;
  XYt: TMatR;
  N: integer;
  x: TVectR;
  y: NReal;
  jj, j: integer;

  res: boolean;
  exp10: integer;

  vectores_A: TDAofVectR;
  k: integer;
  aProm: TVectR;
  avr: TVectR;

  fsal: textfile;

  minCF, maxCF: NREal;
  dCF: NReal;

begin
  if OpenDialog1.Execute then
  begin
    if CF <> nil then
      CF.Free;
    archi := OpenDialog1.FileName;
    CF := TAdminEstados.CreateReadFromArchi(archi);

    N := CF.nVarsContinuas + CF.nVarsDiscretas + 1;
    XXt := TMatR.Create_Init(N, N);
    XYt := TMatR.Create_Init(N, 1);
    x := TVectR.Create_Init(N);


    minCF := 1e200;
    maxCF := -1e200;

    setlength(vectores_A, CF.nPuntosT - 1);
    for kPasoT := 1 to CF.nPuntosT - 1 do
    begin
      XXt.Ceros;
      XYt.Ceros;
      CF.setEstrellaCERO;
      repeat
        CF.SetEstadoToEstrella;
        y := CF.costoEstrella(kPasoT) / 1e6;

        if y < minCF then
          minCF := y;
        if y > maxCF then
          maxCF := y;

        x.pon_e(1, 1);
        jj := 2;

        for j := 0 to CF.nVarsContinuas - 1 do
        begin
          x.pon_e(jj, (CF.xr[j] - CF.xr_def[j].minval) / CF.xr_def[j].deltaval);
          Inc(jj);
        end;

        for j := 0 to CF.nVarsDiscretas - 1 do
        begin
          x.pon_e(jj, (CF.xd[j] - CF.xr_def[j].minval) / CF.xd_def[j].deltaval);
          Inc(jj);
        end;

        for k := 1 to N do
        begin
          for j := 1 to N do
            XXt.acum_e(k, j, x.e(k) * x.e(j));
          XYt.acum_e(k, 1, x.e(k) * y);
        end;

      until not CF.IncEstrella;

      XXt.Escaler(XYt, res, exp10);
      if not res then
        raise Exception.Create('No se puede resolver por mínimos cuadrados!!!');

      vectores_A[kPasoT - 1] := TVectR.Create_Init(N);
      XYt.CopyColVect(vectores_A[kPasoT - 1], 1);

    end; // Recorrido de los pasos T.

    assignfile(fsal, 'aproplin_CF.xlt');
    rewrite(fsal);

    aProm := TVectR.Create_Init(N);
    aProm.Ceros;

    Write(fsal, 'vmin');
    for j := 1 to N do
    begin
      if j = 1 then
        Write(fsal, #9, minCF)
      else if (j - 2) <= high(CF.xr_def) then
        Write(fsal, #9, CF.xr_def[j - 2].minval)
      else
        Write(fsal, #9, CF.xd_def[j - 2 - length(CF.xr_def)].minval);
    end;
    writeln(fsal);

    Write(fsal, 'Rango');
    for j := 1 to N do
    begin
      if j = 1 then
        Write(fsal, #9, maxCF - minCF)
      else if (j - 2) <= high(CF.xr_def) then
        Write(fsal, #9, CF.xr_def[j - 2].deltaval)
      else
        Write(fsal, #9, CF.xd_def[j - 2 - length(CF.xr_def)].deltaval);
    end;
    writeln(fsal);


    Write(fsal, 'Fecha');
    for j := 1 to N do
    begin
      if j = 1 then
        Write(fsal, #9, 'a0')
      else if (j - 2) <= high(CF.xr_def) then
        Write(fsal, #9, CF.xr_def[j - 2].nombre)
      else
        Write(fsal, #9, CF.xd_def[j - 2 - length(CF.xr_def)].nombre);

    end;
    writeln(fsal);

    for k := 0 to high(vectores_A) do
    begin
      Write(fsal, DateTimeToIsoStr(CF.fechaIni.dt + CF.horasDelPaso * k / 24.0));
      avr := vectores_A[k];
      for j := 1 to N do
      begin
        Write(fsal, #9, avr.e(j));
        aProm.acum_e(j, avr.e(j));
      end;
      writeln(fsal);
    end;

    writeln(fsal, '---------------- PROMEDIO ----------------');

    for j := 1 to N do
      Write(fsal, #9, aProm.e(j) / length(vectores_A));

    writeln(fsal);
    closefile(fsal);
  end;
end;

// Calcula la salida del conjunto de neuronas
function Calc_CFAprox(const alfa: TDAOfVectR; const x0, c_min, dc: TDAOfNReal;
  const X: TVectR; Nivel: integer // 1..NNeuronas nivel a considerar
  ): NReal;
var
  kNeurona: integer;
  res: NReal;
  SalidaAnterior, z, Salida: NReal;
begin
  Salida := 0;
  for kNeurona := Nivel - 1 downto 0 do
  begin
    SalidaAnterior := Salida;
    z := alfa[kNeurona].PEV(X) - x0[kNeurona] + SalidaAnterior;
    Salida := c_min[kNeurona] + sigmoide(z) * dc[kNeurona];
  end;
  Result := Salida;
end;

procedure TForm1.btAproxNeuron01Click(Sender: TObject);
var
  XCF: TDAOfRecXCF;
  aRec: TRecXCF;
  dimX: integer;
  k, j: integer;
  alfa: TDAOfVectR;

  x0, c_min, dc: NReal;

  sal: TextFile;
  nivel: integer;
  CFAprox: NReal;

  arrNeuronasPorCapa: TDAOfNInt;
  kRec, jEntrada, kNeurona: integer;

  NIters: integer;
  kIter: integer;
  paso, normGrad: NREal;
  abs_eprom, eprom: NReal;
  cnt_ok: integer;
  ADN: TDAOfNReal;

  CFX_Entrenador: TCF_fEntrenador;

  f0, fs: NReal;
  resErr: NReal;
  resNIters: integer;
  resValCosto, resValLagrangiana, resdFrontera2: NReal;
  resConvergio: boolean;
  cnt_Exitos: integer;

  kCapa, kNeuron: integer;
  //  aNeurona: TNeuronaConEntradas;
  min_resValCosto: NReal;

  grad: TVectR;
  momento: NReal;
  semilla: integer;
  v_ymin, v_ymax, CFAprox_arr: TVectR;
  ymin, dy, a: NReal;

begin

  setSeparadoresGlobales;

  if Cerebro_ = nil then
    raise Exception.Create('Debe primero crear el cerebro.');

  momento := StrToFloat(eMomento.Text);
  Paso := StrToFloat(ePaso.Text);

  kPasoT := 1;
  setlength(XCF, CF.nEstrellasPorPuntoT);
  dimX := CF.nVarsContinuas + CF.nVarsDiscretas;
  CF.setEstrellaCERO;
  repeat
    CF.SetEstadoToEstrella;
    aRec := TRecXCF.Create(dimX, 1);
    for k := 0 to CF.nVarsContinuas - 1 do
      aRec.X.pon_e(k + 1, CF.xr[k]);
    for k := 0 to CF.nVarsDiscretas - 1 do
      aRec.X.pon_e(k + CF.nVarsContinuas, CF.xd[k]);
    aRec.CF := CF.costoEstrella(kPasoT) / 1.0E6;
    a := aRec.CF;
    XCF[CF.ordinalEstrellaActual] := aRec;
  until not CF.IncEstrella;

  if cbOrdenarPorCF.Checked then
    SortDAOfRecXCFbyY(XCF, 1, True);

  // Normalizar_conjuntoXCF(c_min, dc, XCF, 0.7);

  CalcMinMax_Salidas_conjuntoXCF(v_ymin, v_ymax, XCF);
  ymin := v_ymin.e(1);
  dy := (v_ymax.e(1) - ymin);
  if dy < 1e-10 then
    dy := 1;

  v_ymin.Free;
  v_ymax.Free;

  if not flgEscalado then
  begin
    flgEscalado := True;
    RandSeed := 31;
    Cerebro_.RandomInit(0.00100);
    Cerebro_.EscalarEntradas(XCF);
    Cerebro_.EscalarCapaSalida(XCF);
  end;

  PaintBOx2.Canvas.Brush.Color := clBlack;
  PaintBOx2.Canvas.FillRect(0, 0, PaintBox2.Width, PaintBox2.Height);

  PaintBox2.Canvas.Pen.color := ClRed;
  PaintBox2.Canvas.MoveTo(0, PaintBox2.Height - 1);

  for kRec := 0 to high(XCF) do
  begin
    aRec := XCF[kRec];
    PaintBox2.Canvas.LineTo(trunc(kRec / length(XCF) * PaintBOx2.Width),
      trunc(PaintBox2.Height * (1 - (aRec.CF - ymin) / dy)));
  end;

  application.ProcessMessages;

  //  Cerebro.Iniciar_OptUltimaNeurona(XCF);

  grad := TVectR.Create_Init(Cerebro_.DimParametros);

  PaintBox2.Canvas.Pen.color := ClGreen;
  PaintBox2.Canvas.MoveTo(0, PaintBox2.Height - 1);
  for kRec := 0 to high(XCF) do
  begin
    aRec := XCF[kRec];
    Cerebro_.SetEntradas(aRec.X);
    Cerebro_.evaluar;

    CFAprox := Cerebro_.Salida_CapaN.Neuronas[0].salida;

    if abs(CFAprox) < 1e10 then
      PaintBox2.Canvas.LineTo(
        trunc(kRec / length(XCF) * PaintBOx2.Width),
        trunc(PaintBox2.Height * (1 - (CFAprox - ymin) / dy))
        );

  end;


  writeln('Inicio Opt por Problema ... ');
  PaintBox2.Canvas.Pen.color := ClYellow;
  PaintBox2.Canvas.Pen.Width := 4;
  aRec := XCF[0];
  PaintBox2.Canvas.MoveTo(0, trunc(PaintBox2.Height * (1 - (aRec.CF - ymin) / dy)));
  for kRec := 1 to high(XCF) do
  begin
    aRec := XCF[kRec];
    PaintBox2.Canvas.LineTo(trunc(kRec / length(XCF) * PaintBOx2.Width),
      trunc(PaintBox2.Height * (1 - (aRec.CF - ymin) / dy)));
  end;

  kCapa := 0;
  kNeurona := 0;

  CFAprox_arr := TVectR.Create_Init(length(XCF));

  for kIter := 1 to 10000 do
  begin
    (*
    if kiter < 10 then
     resValCosto := EntrenarCerebro( Cerebro, XCF, 10000, resConvergio, resNIters, -1, -1)
    else
    if random < 0.5 then
    *)
    resValCosto := EntrenarCerebro_EBP(Cerebro_, // Cerebro
      XCF,  // Datos de entrenamiento
      paso, momento);
     (*
    else
    begin
     semilla:= random( 10000 );
     resValCosto := EntrenarCerebro_EBP_minibatch(
       grad,
       Cerebro, // Cerebro
       XCF,  // Datos de entrenamiento
       paso, momento, 200, semilla );
    end;
    *)
(*

 resValCosto :=EntrenarCerebro_rnd( Cerebro, // Cerebro
  XCF,  // Datos de entrenamiento
  12, // Número máximo de iteracciones
  paso,  cnt_Exitos );
  *)


    if kIter = 1 then
      min_resValCosto := resValCosto;

    if resValCosto < min_resValCosto then
    begin

      if cbClearCanvas.Checked then
      begin
        PaintBOx2.Canvas.Brush.Color := clBlack;
        PaintBOx2.Canvas.FillRect(0, 0, PaintBox2.Width, PaintBox2.Height);
      end;

      min_resValCosto := resValcosto;
      paso := paso * 1.005;
      eValCosto.Text := FloatToStr(resValCosto);

      PaintBox2.Canvas.Pen.color := ClYellow;
      PaintBox2.Canvas.Pen.Width := 4;
      aRec := XCF[0];
      PaintBox2.Canvas.MoveTo(0, trunc(PaintBox2.Height * (1 - (aRec.CF - ymin) / dy)));
      for kRec := 1 to high(XCF) do
      begin
        aRec := XCF[kRec];
        PaintBox2.Canvas.LineTo(trunc(kRec / length(XCF) * PaintBOx2.Width),
          trunc(PaintBox2.Height * (1 - (aRec.CF - ymin) / dy)));
      end;

      if (kIter mod 2) = 1 then
        PaintBox2.Canvas.Pen.color := ClGreen
      else
        PaintBox2.Canvas.Pen.color := clFuchsia;

      PaintBox2.Canvas.Pen.Width := 4;
      PaintBox2.Canvas.MoveTo(0, PaintBox2.Height - 1);
      for kRec := 0 to high(XCF) do
      begin
        aRec := XCF[kRec];
        for jEntrada := 0 to dimX - 1 do
          Cerebro_.SetEntrada(jEntrada, aRec.X.e(jEntrada + 1));

        Cerebro_.evaluar;
        CFAprox := Cerebro_.Salida_CapaN.Neuronas[0].salida;

        CFAprox_arr.pon_e(kRec + 1, CFAprox);

        if abs(CFAprox) < 1e10 then
          PaintBox2.Canvas.LineTo(
            trunc(kRec / length(XCF) * PaintBOx2.Width),
            trunc(PaintBox2.Height * (1 - (CFAprox - ymin) / dy)));
      end;
    end
    else
      Paso := 0.9997 * paso;
    (*
    aNeurona := Cerebro.ProximaNeuronaConEntradas(kCapa, kNeurona);
    if aNeurona = nil then
      aNeurona := Cerebro.PrimerNeuronaConEntradas(kCapa, kNeurona);
      *)
    application.ProcessMessages;
  end;

  Cerebro_.WriteToArchi('cerebro_mp.xlt');
  CFAprox_arr.WriteXLTSimple_archi('CF_Aprox.xls');
end;

procedure TForm1.btAddNeuronaClick(Sender: TObject);
begin
  Cerebro_.capas[0].AgregarNeuronaNeutra(Cerebro_.capas[1]);
end;

procedure TForm1.btCFSelectClick(Sender: TObject);
var
  i: integer;
  dummy: NReal;
  s: string;
  k: integer;

begin
  uauxiliares.setSeparadoresGlobales;

  if OpenDialog1.Execute then
  begin
    if CF <> nil then
      CF.Free;
    if evaluador <> nil then
    begin
      evaluador.Free;
      evaluador := nil;
    end;

    if vx <> nil then
    begin
      vx.Free;
      vy.Free;
      mcf.Free;
    end;

    vx := TVectR.Create_INit(PaintBox1.Width);
    vy := TVectR.Create_init(PaintBox1.Height);
    mcf := TMatR.Create_Init(PaintBox1.Width, PaintBox1.Height);


    CF := TAdminEstados.CreateReadFromArchi(OpenDialog1.FileName);
    eFechaIni.Text := CF.fechaIni.AsStr;
    eFechaFin.Text := CF.fechaFin.AsStr;
    eNPasosT.Text := IntToStr(CF.nPuntosT);
    kPasoT := 0;
    ekPasoT.Text := IntToStr(0);
    eFechaDelPasoT.Text := DateTimeToStr((CF.fechaFin.dt - CF.fechaIni.dt) /
      (CF.nPuntosT - 1));



    Dim_EspacioX := CF.nVarsContinuas + CF.nVarsDiscretas;

    sbkPaso.Min := 1;
    sbkPaso.Max := CF.nPuntosT;

    evaluador := TEvaluadorExpresionesSimples.Create;

    for k := 0 to CF.VariablesDeEstado_lst.Count - 1 do
      memo1.Append(PurificarAlfaNum(CF.VariablesDeEstado_lst[k]));


    //inicializamos variables "X" en entorno de cálculo
    for i := 0 to CF.nVarsContinuas - 1 do
    begin
      evaluador.Ejecutar(dummy, '$X_' + PurificarAlfaNum(
        CF.xr_Def[i].nombre) + ':= 0.0;');

      if CF.xr_Def[i].traduccion <> nil then
        evaluador.Ejecutar(dummy, '$T_' + PurificarAlfaNum(
          CF.xr_Def[i].Traduccion.nombre) + ':= 0.0;');

      s := '$X_' + PurificarAlfaNum(CF.xr_Def[i].nombre) + ':= ' +
        FloatToStr(CF.xr_Def[i].minval) + ' + ' +
        FloatToStr(CF.xr_Def[i].deltaval) + ' * x + 1.0 * y;';
      writeln(s);
      mseval.Lines.add(s);

    end;

    for i := 0 to CF.nVarsDiscretas - 1 do
    begin
      evaluador.Ejecutar(dummy, '$X_' + PurificarAlfaNum(
        CF.xd_Def[i].nombre) + ':= 0;');
      if CF.xd_Def[i].traduccion <> nil then
        evaluador.Ejecutar(dummy, '$T_' + PurificarAlfaNum(
          CF.xd_Def[i].nombre) + ':= 0;');
      mseval.Lines.add('$X_' + PurificarAlfaNum(CF.xr_Def[i].nombre) +
        ':= 0.0 + 1.0 * x + 1.0 * y;');
    end;

    // Inicializamos variables
    evaluador.Ejecutar(dummy, 'x := 0.0');
    evaluador.Ejecutar(dummy, 'y := 0.0');

  end;
  uauxiliares.setSeparadoresLocales;
end;

procedure TForm1.btCompress16Click(Sender: TObject);
var
  camino: string;
  nombre: string;
  archi, archi_dest: string;
begin
  if OpenDialog1.Execute then
  begin
    if CF <> nil then
      CF.Free;
    archi := OpenDialog1.FileName;
    CF := TAdminEstados.CreateReadFromArchi(archi);
    camino := ExtractFileDir(archi);
    nombre := ExtractFileName(archi);
    archi_dest := Camino + DirectorySeparator + 'z16_' + nombre;
    CF.WriteToArchi(archi_dest);
    CF.Free;
    CF := nil;
  end;
end;

procedure TForm1.btConvertir178Change(Sender: TObject);
var
  archi: string;
  fCosto: TMatOfNReal;
  nPasos, nEstrellas: integer;
  k, j: integer;
begin
  if OpenDialog1.Execute then
  begin
    if CF <> nil then
      CF.Free;
    archi := OpenDialog1.FileName;
    CF := TAdminEstados.CreateReadFromArchi(archi);
    archi := ChangeFileExt(archi, '') + '_178_.bin';
    CF.StoreInArchi_178_(archi);
  end;
end;

procedure TForm1.btCrearCerebroClick(Sender: TObject);
var
  nCapas: integer;

  pal: string;
  kCapa: integer;
  s: string;
  nNeuronas, kPaso: integer;

begin
  nCapas := 100;
  if Cerebro_ <> nil then
    Cerebro_.Free;
  setlength(arrCntNeuronasPOrCapa, nCapas);
  s := eNeuronasPorCapa.Text;
  pal := nextpal(s);

  kCapa := 0;
  while pal <> '' do
  begin
    if pal = 'N' then
      nNeuronas := Dim_EspacioX
    else
      nNeuronas := StrToInt(pal);
    arrCntNeuronasPOrCapa[kCapa] := nNeuronas;
    Inc(kCapa);
    pal := nextpal(s);
  end;
  setlength(arrCntNeuronasPOrCapa, kCapa);

  Cerebro_ := TCerebro.Create(Dim_EspacioX, arrCntNeuronasPOrCapa,
    TTipoSaturacion(cbTipoSaturacion.ItemIndex), CTS_Lineal,
    TTipoSaturacion(cbTipoSaturacionInternas.ItemIndex));



  randomize;
  Cerebro_.RandomInit(1.0);

  flgEscalado := False;
end;

procedure TForm1.btDibujarNeuronasClick(Sender: TObject);
var
  c: TCanvas;
  w, h: integer;
  nFils, nCols: integer;
  cnt, kCapa, kNeurona: integer;
  aCapa: TCapaNeuronasBase;
  aNeurona: TNeurona;
  aNeuronaConEntradas: TNeuronaConEntradas;
  xCentro, yCentro, radio: integer;

begin
  if Cerebro_ <> nil then
  begin
    w := PaintBox2.Width;
    h := PaintBox2.Height;
    c := PaintBox2.Canvas;

    c.Brush.Color := clWhite;
    c.Rectangle(0, 0, w - 1, h - 1);

    // una columna a la izquierda, capaEntrada, las capas y una a la derecha
    nCols := 1 + 1 + length(Cerebro_.capas) + 1;
    nFils := Cerebro_.CapaEntrada.NNeuronas;
    for kCapa := 0 to high(Cerebro_.Capas) do
    begin
      cnt := Cerebro_.Capas[kCapa].NNeuronas;
      if cnt > nFils then
        nFils := cnt;
    end;

    radio := trunc(min(w / nCols, h / nFils) / 8);

    // Dibujamos la capa de entrada
    c.Pen.Color := clBlack;
    c.Brush.Color := clGray;
    c.Pen.Width := 1;
    aCapa := Cerebro_.CapaEntrada;
    for kNeurona := 0 to aCapa.NNeuronas - 1 do
    begin
      kCapa := -1;
      xCentro := trunc((kCapa + 0.5 + 2) / nCols * w);
      yCentro := trunc((1 - (kNeurona + 0.5) / aCapa.NNeuronas) * h);

      c.Ellipse(xCentro - radio, yCentro - radio, xCentro + radio, yCentro + Radio);
    end;

    // Dibujamos las capas con entrada
    c.Pen.Color := clBlack;
    c.Brush.Color := clGreen;
    c.Pen.Width := 1;
    for kCapa := 0 to high(Cerebro_.capas) do
    begin
      aCapa := Cerebro_.capas[kCapa];
      for kNeurona := 0 to aCapa.NNeuronas - 1 do
      begin
        xCentro := trunc((kCapa + 0.5 + 2) / nCols * w);
        yCentro := trunc((1 - (kNeurona + 0.5) / aCapa.NNeuronas) * h);
        c.Ellipse(xCentro - radio, yCentro - radio, xCentro + radio, yCentro + Radio);
      end;
    end;

  end;
end;


procedure TForm1.PlotIsoCurvas(M: TMatR; vx, vy: TVectR; M2: TMatR;
  vx2, vy2: TVectR; niveles: array of NReal; etiquetas: array of string);

var
  IsoScanner: TIsoScannerMatricial;
  px, py: NReal;
  pol: TPoligonalXY;
  res: boolean;
  ramaDirecta: boolean;
  plabel_x, plabel_y: NReal;
  lblxy: TLabelXY;
  color: TColor;
  trx: TfrmDllForm;
  sal: textfile;
  archi: string;

  procedure PlotCurvas(m: TMatR; vx, vy: TVectR);
  var
    knivel: integer;
    idPol: integer;
  begin

    for knivel := 0 to high(niveles) do
    begin
      archi := 'isocurva_n' + IntToStr(kNivel) + '_cm' + IntToStr(
        round(niveles[kNivel] * 100)) + '.scr';
      assignfile(sal, archi);
      rewrite(sal);

      IsoScanner := TIsoScannerMatricial.Create(m, vx, vy, niveles[knivel]);
      color := escalaColor.Color(niveles[knivel]);
      pol := TPoligonalxy.Create(trx.tr1, 'p', False, color);
      idPol := 1;

      ramaDirecta := True;
      plabel_y := 100000;

      repeat
        res := IsoScanner.GetPunto(px, py);  {pedimos un punto a iso90}
        if IsoScanner.Estado = Reversa then
          ramaDirecta := not ramaDirecta;

        if res then   {Si el punto es valido lo dibuja}
        begin
          if py < plabel_y then   {elige el punto más bajo}
          begin
            plabel_x := px;
            plabel_y := py;          {para poner la etiqueta}
          end;
          if ramaDirecta then
            pol.nuevoPunto(px, py)
          else
            pol.nuevoPuntoAlInicio(px, py);
        end;

        if IsoScanner.Estado = Semiactivo then   {termino con una curva}
        begin
          pol.AppendToAutocadSCR(sal);
          if aDoc_KML <> nil then
            pol.AppendToKMLDocumento(aDoc_KML, archi + '_' + IntToStr(idPol));

          pol := TPoligonalxy.Create(trx.tr1, 'p', False, color);
          Inc(idPol);
          ramaDirecta := True;
          lblxy := TLabelXY.Create(trx.tr1, 'l', plabel_x, plabel_y,
            etiquetas[knivel], color, 10);
          plabel_y := 10000;
        end;
      until IsoScanner.Estado = fin;       {hasta terminar}
      IsoScanner.Free;
      pol.AppendToAutocadSCR(sal);
      closefile(sal);
    end;
  end;

begin
  trx := TfrmDllForm.Create(form1);

  trx.CrearDiagramaXY(
    'Costo Futuro', // Nombres
    512, // MaxNPuntos
    True, // ciruclar
    'x', // nombre_sx
    '', // nombre_sy1: pchar;
    clRed, //  color_sy1: TColor;
    vx.e(1), vx.e(vx.n), //  x1, x2,
    vy.e(1), vy.e(vy.n), //y1, y2
    10, 10    // NDivX, NDivY
    );

  trx.Show;
  trx.dbj_gridx;
  trx.dbj_gridy;
  trx.dbj_borde;
  trx.titulo('Costo Futuro');
  trx.etiquetas_x(vx.e(1), vx.e(vx.n));
  trx.etiquetas_y(vy.e(1), vy.e(vy.n));
  trx.xlabel('x');
  trx.ylabel('y');


  PlotCurvas(m, vx, vy);
  if m2 <> nil then
    PlotCurvas(m2, vx2, vy2);

  trx.tr1.RePlot;
end;

function TForm1.cargar(archi_nombre: string): TArchivoXLT;
var
   archi: string;
   res: TArchivoXLT;
begin
  archi:= archi_nombre;
  res:= TArchivoXLT.CreateFromXLT(archi_nombre,  archi );
  result:= res;

end;


procedure TForm1.btIsoCurvasClick(Sender: TObject);
begin
  PlotIsoCurvas(mcf, vx, vy, nil, nil, nil, niveles, etiquetas);
end;

procedure TForm1.btScanAltitudesClick(Sender: TObject);
var
  k, j: integer;
  lats, lons: TVectR;
  z: TMatR;
  nLats, nLons: integer;
  xE, yN: TVectR;
  x0, x, dx: NReal;

  min_z, max_z: NReal;
  nNiveles: integer;
  UTME, UTMN: NReal;
  UTMZona: char;
  UTMHuso: integer;
  delta_z: NReal;

begin

  aDoc_KML := TKML_Document.CreateNew('Lupi');
  aDoc_KML.AddMarcador('p1', StrToFloat(lat1.Text), StrToFloat(lon1.Text), 1);
  aDoc_KML.AddMarcador('p2', StrToFloat(lat2.Text), StrToFloat(lon2.Text), 1);

  nLats := StrToInt(nPuntosLat.Text);
  nLons := StrToInt(nPuntosLon.Text);
  lats := TVectR.Create_Init(nLats);
  lons := TVectR.Create_Init(nLons);

  x0 := StrToFloat(Lat1.Text);
  dx := (StrToFloat(lat2.Text) - x0) / (nLats - 1);
  for k := 1 to nLats do
    lats.pon_e(k, x0 + (k - 1) * dx);

  x0 := StrToFloat(lon1.Text);
  dx := (StrToFloat(lon2.Text) - x0) / (nLons - 1);
  for k := 1 to nLons do
    lons.pon_e(k, x0 + (k - 1) * dx);

  z := TMatR.CreateFromArchiXLT('altitudes_.xlt');
  //  z:= Elevation_scanMat( lats, lons );

  if z <> nil then
  begin
    lats.WriteXLTSimple_archi('latitudes.xlt');
    lons.WriteXLTSimple_archi('longitudes.xlt');

    // supongo que es un rectángulo chico y paso a metros
    j := round((lons.n - 1) / 2 + 1);
    yN := TVectR.Create_Init(lats.n);
    for k := 1 to lats.n do
    begin
      LatLonToUTM(UTME, UTMN, UTMZona, UTMHuso, C_Ellipsoid_URUGUAY,
        Lats.e(k), lons.e(j));
      yN.pon_e(k, UTMN);
    end;

    k := round((lats.n - 1) / 2 + 1);
    xE := TVectR.Create_Init(lons.n);
    for j := 1 to lons.n do
    begin
      LatLonToUTM(UTME, UTMN, UTMZona, UTMHuso, C_Ellipsoid_URUGUAY,
        Lats.e(k), lons.e(j));
      xE.pon_e(j, UTME);
    end;
    xE.WriteXLTSimple_archi('coordenadas_xE.xlt');
    yN.WriteXLTSimple_archi('coordenadas_yN.xlt');

    z.WriteArchiXLT('altitudes_.xlt');
    z.MinMax(min_z, max_z);

    EscalaColor := TEscalaColor.Create(min_z, max_z);

    // ahora buscamos la aproximación a 0.5m
    min_z := ceil(min_z * 2) / 2;
    max_z := floor(max_z * 2) / 2;
    nNiveles := round((max_z - min_z) * 2 + 1);
    if nNiveles > 1 then
    begin
      delta_z := (max_z - min_z) / (nNiveles - 1);
      setlength(niveles, nNiveles);
      setlength(etiquetas, nNiveles);
      for k := 0 to high(niveles) do
      begin
        niveles[k] := min_z + k * delta_z;
        etiquetas[k] := FloatToStrF(niveles[k], ffFixed, 12, 1);
      end;
      // transpongo porque espera que las filas sena el x y las columnas los y
      z.Transponer;
      //    self.PlotIsoCurvas( z, lons, lats, nil, nil, nil, niveles, etiquetas );
      self.PlotIsoCurvas(z, xE, yN, nil, nil, nil, niveles, etiquetas);
    end;
  end;

  aDoc_KML.WriteArchi_kml('puntos_lu.kml');
  aDoc_KML.Free;
  aDoc_KML := nil;

end;

procedure TForm1.btTest01Click(Sender: TObject);
var
  XCF: TDAOfRecXCF;
  aRec: TRecXCF;
  dimX: integer;
  arrNeuronasPorCapa: TDAofNInt;
  nParametros: integer;
  flog: textfile;
  c_min, dc: NReal;
  cerebro: TCerebro;
  X, Xs: TVectR;
  kRec: integer;
  CFAprox: NReal;
  derr: TDAOfNReal;
begin
  dimX := 1;
  XCF := Crear_XCF_Test01(dimX, 2, 31);

  Normalizar_conjuntoXCF(c_min, dc, XCF, 0.7);

  setlength(arrNeuronasPorCapa, 2);
  arrNeuronasPorCapa[0] := dimX;
  arrNeuronasPorCapa[1] := 1;
  cerebro := TCerebro.Create(dimX, // Cantidad de entradas
    arrNeuronasPorCapa, // Cantidad de capas (sin contar la entrada)
    True); // Indica si saturar la salida de la última capa.

  nparametros := cerebro.DimParametros;
  X := TVectR.Create_init(nparametros);
  Xs := TVectR.Create_init(nparametros);
  randSeed := 131;
  X.random;
  Cerebro.SetParametros(X);
  setlength(derr, 1);

  assignfile(flog, 'cerebro_db.xlt');
  rewrite(flog);
  for kRec := 0 to high(XCF) do
  begin
    Cerebro.BackPropagation_init;
    aRec := XCF[kRec];
    Cerebro.SetEntradas(aRec.X);
    Cerebro.evaluar;
    CFAprox := Cerebro.Salida_CapaN.Neuronas[0].salida;
    derr[0] := (CFAprox - aRec.CF);
    Cerebro.BackPropagation_ClearErr;
    Cerebro.BackPropagation_addMuestra(derr);
    writeln(flog, '***************');
    writeln(flog, 'Muestra:', kRec, #9, CFAprox, #9, aRec.CF);
    Cerebro.print_debug(flog);
  end;
  closefile(flog);

end;




procedure TForm1.btVerClick(Sender: TObject);
var
  k, j, i: integer;
  x, y: NReal;
  ss: TStringList;
  s: string;
  xVar, yVar: TVar;
  vxVar: array of TVar;
  vcf_min, vcf_max, vcf: NReal;
  color: TCOlor;
  klin, iPosBarraBarra: integer;
  ts: string;
  aScript: TExprLst;

  dCdx_Inc, dCDx_Dec: NReal;
  resCod: integer;
  xrpos: NReal;

begin

  kPasoT := StrToInt(ekPaso.Text);
  s := mseval.Text;

  xVar := evaluador.FindVar('x');
  yVar := evaluador.FindVar('y');

  setlength(vxVar, CF.nVarsContinuas + CF.nVarsDiscretas);

  for i := 0 to CF.nVarsContinuas - 1 do
    vxVar[i] := evaluador.FindVar('$X_' + PurificarAlfaNum(CF.xr_Def[i].nombre));
  for i := 0 to CF.nVarsDiscretas - 1 do
    vxVar[CF.nVarsContinuas + i] :=
      evaluador.FindVar('$X_' + PurificarAlfaNum(CF.xd_def[i].nombre));

  ss := TStringList.Create;
  ss.AddStrings(mseval.Lines);

  for klin := 0 to ss.Count - 1 do
  begin
    ts := trim(ss[klin]);
    iPosBarraBarra := pos('//', ts);
    if iPosBarraBarra > 0 then
      ts := copy(ts, 1, iPosBarraBarra - 1);
    ss[klin] := trim(ts);
  end;
  ss.LineBreak := ' ';
  s := ss.Text;
  ss.Free;

  aScript := evaluador.GetExprLst(s);
  for k := 0 to PaintBox1.Width - 1 do
    for j := 0 to PaintBox1.Height - 1 do
    begin
      x := k / (PaintBox1.Width - 1);
      y := (PaintBox1.Height - j - 1) / (PaintBox1.Height - 1);

      vx.pon_e(k + 1, x);
      vy.pon_e(PaintBox1.Height - j, y);

      xVar.val.val_F := x;
      yVar.val.val_F := y;


      aScript.Evaluar;
      // evaluador.Ejecutar(s);

      for i := 0 to CF.nVarsContinuas - 1 do
        CF.xr[i] := vxVar[i].ValAsFloat;
      for i := 0 to CF.nVarsDiscretas - 1 do
        CF.xd[i] := vxVar[CF.nVarsContinuas + i].ValAsInt;
        (*  a medio hacer
      CF.devxr_continuo( 1, kPasoT, dCdx_Inc, dCDx_Dec, resCod, xrpos );
      case resCod of
        -1: vcf:= dCdx_Inc;
        0: vcf:= ( dCdx_Dec + dCdx_Inc ) / 2 ;
        1: vcf:= dCdx_Dec;
      end;

      hBon:= CF.xr_def[1].traduccion.x;
      *)
      vcf := CF.costoContinuo(kPasoT);

      mcf.pon_e(k + 1, PaintBox1.Height - j, vcf);
    end;

  mcf.MinMax(vcf_min, vcf_max);
  EscalaColor := TEscalaColor.Create(vcf_min, vcf_max);

  setlength(niveles, 50);
  setlength(etiquetas, length(niveles));
  for k := 0 to high(niveles) do
  begin
    niveles[k] := vcf_min + (vcf_max - vcf_min) / length(niveles) * (k + 0.5);
    etiquetas[k] := FloatToStr(round(niveles[k] / 1e6 * 10) / 10);
  end;

  for k := 0 to PaintBox1.Width - 1 do
    for j := 0 to PaintBox1.Height - 1 do
    begin
      vcf := mcf.e(k + 1, PaintBox1.Height - j);
      color := escalaColor.Color(vcf);
      PaintBox1.Canvas.Pixels[k, j] := color;
    end;

end;



function nextpal(var s: string): string;
var
  i: integer;
  res: string;
begin
  i := pos(#9, s);
  if i > 0 then
  begin
    res := copy(s, 1, i - 1);
    Delete(s, 1, i);
  end
  else
  begin
    res := s;
    s := '';
  end;
  Result := s;
end;

procedure TForm1.btCopiarYTranspornerUltima7FilasClick(Sender: TObject);
var
  archi: string;
  buff: array[1..10] of TDAOfNReal;
  //array [1..10*5*5*5] of NReal;
  ent, sal: textfile;
  i: integer;
  r: string;
  pal: string;
  N: integer;
  paux: TDAOfNreal;
begin
  N := 10 * 5 * 5 * 5;

  if OpenDialog1.Execute then
  begin
    archi := OpenDialog1.FileName;
    assignfile(ent, archi);
    reset(ent);

    for i := 1 to 10 do
      setlength(buff[i], N);

    while not EOF(ent) do
    begin
      readln(ent, r);

      paux := buff[1];
      for i := 1 to 9 do
        buff[i] := buff[i + 1];
      buff[10] := paux;

      for i := 0 to N - 1 do
      begin
        pal := nextpal(r);
        paux[i] := StrToFloat(pal);
      end;

    end;
    closefile(ent);

  end;
end;




procedure TForm1.bTest02Click(Sender: TObject);
var
  cerebro: TCerebro;
  XCF: TDAOfRecXCF;
  arrNeuronasPorCapa: TDAOfNInt;

  resConvergio: boolean;
  resNIters: integer;
  x, y, e: TVectR;
  e2: NReal;
  sal: textfile;
  iter: integer;

begin

  XCF := Crear_XCF_Test02_(1000, 31);

  setlength(arrNeuronasPorCapa, 1);
  arrNeuronasPorCapa[0] := 1;

  cerebro := TCerebro.Create(1, // Cantidad de entradas
    arrNeuronasPorCapa, // Cantidad de capas (sin contar la entrada)
    True); // Indica si saturar la salida de la última capa.

  x := TVectR.Create_Init(1);
  y := TVectR.Create_Init(1);
  e := TVectR.Create_Init(1);
  randomize;
  cerebro.RandomInit(1);

  assignfile(sal, 'test02.txt');
  rewrite(sal);
  x.pon_e(1, 0.6);
  for iter := 1 to 1000000 do
  begin
    x.pon_e(1, 100 * (random - 0.5));
    if x.e(1) < 0.5 then
      y.pon_e(1, 1)
    else
      y.pon_e(1, 0); // x < 0.5

    cerebro.SetEntradas(x);
    cerebro.BackPropagation_init;
    cerebro.evaluar;

    e2 := cerebro.calc_err2(e, y);

    cerebro.BackPropagation_addMuestra(e);
    //    cerebro.print_debug( sal );
    cerebro.BackPropagation_DarPaso(100, 0.7, 0.3);

    writeln(sal, 'iter: ', iter, #9, 'e2: ', e2);
  end;
  closefile(sal);
  Cerebro.WriteToArchi('cerebro_ebp.xlt');

  EntrenarCerebro(cerebro, XCF, 1000, resConvergio, resNIters, -1, -1);

  Cerebro.WriteToArchi('cerebro_mp.xlt');
  Cerebro.Free;
  free_Data_xcf(XCF);
end;

procedure TForm1.btLoadCFClick(Sender: TObject);
var
  a: NReal;
begin
  if OpenDialog1.Execute then
  begin
    if CF <> nil then
      CF.Free;
    CF := TAdminEstados.CreateReadFromArchi(OpenDialog1.FileName);
    Dim_EspacioX := CF.nVarsContinuas + CF.nVarsDiscretas;
    eDimensionEspacioX.Text := IntToStr(Dim_EspacioX);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //  googlemaps_open( StrToFloat( lat1.text ), StrToFloat( lon1.text ) );
  aDoc_KML := TKML_Document.CreateNew('Lupi');
  aDoc_KML.AddMarcador('p1', StrToFloat(lat1.Text), StrToFloat(lon1.Text), 1);
  aDoc_KML.AddMarcador('p2', StrToFloat(lat2.Text), StrToFloat(lon2.Text), 1);
  aDoc_KML.WriteArchi_kml('puntos_lu.kml');
  aDoc_KML.Free;
  aDoc_KML := nil;
end;

procedure TForm1.AproxN01ConParsClick(Sender: TObject);
var
  aRec: TRecXCF;
  dimX: integer;
  k, j: integer;

  CFAprox: NReal;

  arrNeuronasPorCapa: TDAOfNInt;
  kRec, jEntrada, kNeurona: integer;

  kIter, kPaso: integer;
  resValCosto, CF_real: NReal;
  resConvergio, BP: boolean;
  resNIters, nparametrosX: integer;

  kCapa, kNeuron, nIter, nparametros, nHasta: integer;
  //  aNeurona: TNeuronaConEntradas;
  min_resValCosto, paso_ini: NReal;

  error2: ValReal;



  HistoCF, HistoCF_aprox, HistoError: TPrintCronVar_histograma;
  CronVarCF, CronVarError: TCronVar;
  //xlt: TExcelFile;
  aCerebro0, aCerebro: TCerebro;
  aNeurona0, aNeurona: TNeuronaEntrada;
  problema_opt: TProblema_Cerebro;


begin

  setSeparadoresGlobales;

  momento := StrToFloat(eMomento.Text);
  Paso := StrToFloat(ePaso.Text); /// 52;

  CronVarCF := TCronVar.Create('CF');
  CronVarCF_aprox := TCronVar.Create('CF_aprox');
  CronVarError := TCronVar.Create('errorCF');

  CronVarCF.inicializar(CF.nEstrellasPorPuntoT,
    CF.nPuntosT - 1, CF.fechaIni.dt, CF.horasDelPaso);
  CronVarCF_aprox.inicializar(CF.nEstrellasPorPuntoT,
    CF.nPuntosT - 1, CF.fechaIni.dt, CF.horasDelPaso);
  CronVarError.inicializar(CF.nEstrellasPorPuntoT,
    CF.nPuntosT - 1, CF.fechaIni.dt, CF.horasDelPaso);

  SetLength(probabilidadAisladas, 4);
  probabilidadAisladas[0] := 0.2;
  probabilidadAisladas[1] := 0.4;
  probabilidadAisladas[2] := 0.6;
  probabilidadAisladas[3] := 0.8;


  if Cerebro_ = nil then
    raise Exception.Create('Debe primero crear el cerebro.');

  if Cerebros = nil then
  begin

    setlength(Cerebros, CF.nPuntosT); // va de 1 a N y la pos 0 no se usa
    setlength(aCerebros, CF.nPuntosT); //Copia de cerebros para ir mostrando resultados
    for kPaso := 1 to high(Cerebros) do
    begin
      Cerebros[kPaso] := TCerebro.Create(Dim_EspacioX, arrCntNeuronasPOrCapa,
        TTipoSaturacion(cbTipoSaturacion.ItemIndex), CTS_Lineal,
        TTipoSaturacion(cbTipoSaturacionInternas.ItemIndex));

     { aCerebros[kPaso] := TCerebro.Create(Dim_EspacioX, arrCntNeuronasPOrCapa,
        TTipoSaturacion(cbTipoSaturacion.ItemIndex), CTS_Lineal,
        TTipoSaturacion(cbTipoSaturacionInternas.ItemIndex));   }

      aCerebros[kPaso]:= Cerebros[kPaso].Clonar;
    end;


    maxCF := -1e50;

    {$IFNDEF BP}
    parsimonia := TParsimonia.Create(7.0, 365.2425, 1, 0, cerebros[1].DimParametros);
    {$ENDIF}

    nPR:= cerebros[1].DimParametros;
    nPP:= parsimonia.nParametrosPorPaso;

    SetLength(XCF_, CF.nPuntosT - 1);

    for kPaso := 1 to high(Cerebros) do
    begin
      kPasoT := kPaso - 1;
      CronVarCF.Enter(kPaso - 1);
      setlength(XCF_[kPaso - 1], CF.nEstrellasPorPuntoT);
      dimX := CF.nVarsContinuas + CF.nVarsDiscretas;
      CF.setEstrellaCERO;
      repeat
        CF.SetEstadoToEstrella;
        XCF_[kPaso - 1][CF.ordinalEstrellaActual] := TRecXCF.Create(dimX, 1);

        for k := 0 to CF.nVarsContinuas - 1 do
          XCF_[kPaso - 1][CF.ordinalEstrellaActual].X.pon_e(k + 1, CF.xr[k]);
        for k := 0 to CF.nVarsDiscretas - 1 do
          XCF_[kPaso - 1][CF.ordinalEstrellaActual].X.pon_e(k + CF.nVarsContinuas, CF.xd[k]);

        XCF_[kPaso - 1][CF.ordinalEstrellaActual].CF := CF.costoEstrella(kPaso) / 1.0E6;

        CronVarCF.valores[CF.ordinalEstrellaActual] :=
          XCF_[kPaso - 1][CF.ordinalEstrellaActual].CF;

        if XCF_[kPaso - 1][CF.ordinalEstrellaActual].CF > maxCF then
          maxCF := XCF_[kPaso - 1][CF.ordinalEstrellaActual].CF;

        //XCF_[kPaso][CF.ordinalEstrellaActual] := aRec;
      until not CF.IncEstrella;

      if cbOrdenarPorCF.Checked then
        SortDAOfRecXCFbyY(XCF_[kPaso - 1], 1, True);

      // Normalizar_conjuntoXCF(c_min, dc, XCF_[kPaso], 0.7);


      if not flgEscalado then
      begin
        RandSeed:=31;
        Cerebros[kPaso].RandomInit(0.00100);
        Cerebros[kPaso].EscalarEntradas(XCF_[kPaso - 1]);
        Cerebros[kPaso].EscalarCapaSalida(XCF_[kPaso - 1]);
      end;
    end;



    if not flgEscalado then
    begin
      aCerebro0:= Cerebros[1];
      aCerebro:= aCerebro0;
      for kPaso:=2 to high( Cerebros ) do
      begin
         aCerebro:= Cerebros[kPaso];
         for kNeurona:= 0 to aCerebro.NEntradas-1 do
         begin
           aNeurona0:= aCerebro0.CapaEntrada.Neuronas[ kNeurona ] as TNeuronaEntrada;
           aNeurona:= aCerebro.CapaEntrada.Neuronas[ kNeurona ] as TNeuronaEntrada;
           aNeurona0.bias:= aNeurona0.bias + aNeurona.bias;
           aNeurona0.ro:= aNeurona0.ro + aNeurona.ro;
         end;
      end;

      for kNeurona:= 0 to aCerebro.NEntradas-1 do
      begin
        aNeurona0:= aCerebro0.CapaEntrada.Neuronas[ kNeurona ] as TNeuronaEntrada;
        aNeurona0.bias:= aNeurona0.bias / ( length( Cerebros ) - 1);
        aNeurona0.ro:= aNeurona0.ro / ( length( Cerebros ) - 1 );
      end;

      for kPaso:=2 to high( Cerebros ) do
      begin
         aCerebro:= Cerebros[kPaso];
         for kNeurona:= 0 to aCerebro.NEntradas-1 do
         begin
           aNeurona0:= aCerebro0.CapaEntrada.Neuronas[ kNeurona ] as TNeuronaEntrada;
           aNeurona:= aCerebro.CapaEntrada.Neuronas[ kNeurona ] as TNeuronaEntrada;
           aNeurona.bias:= aNeurona0.bias;
           aNeurona.ro:= aNeurona0.ro;
         end;
      end;
    end;


    flgEscalado := True;

    {$IFNDEF BP}
    nparametros:= parsimonia.dimParsimonia * Cerebros[1].DimParametros;

    grad_ant := TVectR.Create_Init(nparametros);
    grad_ant.Ceros;

    X := TVectR.Create_init(nparametros);
    X.random();
    X.MasReal(0.001);

    CFX_fEntrenador := TCF_fCerebrosConParsimonia.Create(Cerebros, XCF_, parsimonia);

    {$ENDIF}

   { CFX_fEntrenador.f(X);
    CFX_fEntrenador.acum_g(grad_ant,X);

    X.SumRPV(-paso, grad_ant);

    CFX_fEntrenador.SetParametrosCerebros(X); }

  end;


 { application.ProcessMessages;


  PaintBox2.Canvas.Pen.color := ClGreen;
  PaintBox2.Canvas.MoveTo(0, PaintBox2.Height - 1);

  for kPaso := 1 to high(Cerebros) do
    for kRec := 0 to high(XCF_[kpaso - 1]) do
    begin
      aRec := XCF_[kpaso - 1][kRec];
      CF_real := aRec.CF;
      Cerebros[kpaso].SetEntradas(aRec.X);
      Cerebros[kpaso].evaluar;

      CFAprox := Cerebros[kpaso].Salida_CapaN.Neuronas[0].salida;

      if abs(CFAprox) < 1e10 then
        PaintBox2.Canvas.LineTo(
          trunc((kpaso - 1) / length(XCF_) * PaintBOx2.Width),
          trunc(PaintBox2.Height * (1 - (CFAprox - CF_real)))
          );

    end;
         }

  writeln('Inicio Opt por Problema ... ');


  for kPaso:=1 to high( Cerebros)  do
    for kRec := 0 to high(XCF_[kPaso-1]) do
    begin
      aRec := XCF_[kPaso-1][kRec];
      Cerebro_.SetEntradas(aRec.X);
      Cerebro_.evaluar;

      CFAprox := Cerebro_.Salida_CapaN.Neuronas[0].salida;
    end;


  kCapa := 0;
  kNeurona := 0;
  resConvergio := False;
  kIter := 0;
  min_resValCosto := 1E6;
  nIter := 100000;

  {$IFNDEF BP}
  if (cbParsimonia.Checked) or (cbMaxInBox.Checked) then
    nIter := 1;
  {$ENDIF}

  BP:=false;

  paso_ini:=paso;

  {$IFDEF BP}
  for kPaso:=1 to high( Cerebros)  do
  begin
  paso:=paso_ini;
  {$ENDIF}
  for kIter := 1 to nIter do
  begin


  {$IFDEF BP}
      resValCosto := EntrenarCerebro_EBP(Cerebros[kPaso], // Cerebro
         XCF_[kPaso-1],  // Datos de entrenamiento
         paso, momento);
         BP:=true;
         if kIter = 1 then
           min_resValCosto := resValCosto;
   {$ENDIF}

    if not BP then
      if cbParsimonia.Checked then
        resValCosto := EntrenarCerebrosConParsimonia_aData( Cerebros, // Cerebro
          XCF_,  // Datos de entrenamiento
          parsimonia,
          10000, resConvergio, resNIters, -1, -1)
      else
        if cbBPconParsimonia.Checked then
        begin
          resValCosto := EntrenarCerebro_EBP_ConParsimonia(Cerebros, // Cerebro
            XCF_,  // Datos de entrenamiento
            parsimonia, paso, momento, grad_ant, X, CFX_fEntrenador);
            if kIter = 1 then
               min_resValCosto := resValCosto;
        end
        else
          if cbMaxInBox.Checked then
          begin
            kIter_archi:=1;
            ConExcel:=true;
            PaintBox:=false;
            xlt := TExcelFile.Create('Histo', 'CF');
            nparametrosX := Cerebros[1].DimParametros * ( high(Cerebros) + parsimonia.dimParsimonia );
            //Creo problema con nCerebros  restricciones (la parsimonia) y
            //la funcion objetivo es el e2 de los cerebros sin parsimonia
             problema_opt := TProblema_Cerebro.Create_init(high(Cerebros) + 1,
                      nparametrosX + 1, 0, nil, nil,false);

             //Resolvedor
             resValCosto := EntrenarCerebrosConParsimonia_aData_MaxInBox( Cerebros, // Cerebro
              XCF_,  // Datos de entrenamiento
              parsimonia,
              100000, resConvergio, resNIters, -1, -1,  problema_opt)
          end
          else
            raise Exception.Create('Debe seleccionar un tipo de entrenador.');


   writeln( paso, '  ', resValCosto );

   if resValCosto > 1E30 then
    Break;


    if (resValCosto < min_resValCosto)  then
    begin
      if cbClearCanvas.Checked then
      begin
        PaintBOx2.Canvas.Brush.Color := clBlack;
        PaintBOx2.Canvas.FillRect(0, 0, PaintBox2.Width, PaintBox2.Height);
      end;

      if  (min_resValCosto-resValCosto) < 1E-3 then
         paso := paso * 1.1
      else
         paso := paso * 1.005;

      min_resValCosto := resValcosto;
      eValCosto.Text := FloatToStr(resValCosto);

      ePaso.Text:=FloatToStr(paso);


      application.ProcessMessages;

      if (kIter mod 2) = 1 then
        PaintBox2.Canvas.Pen.color := ClGreen
      else
        PaintBox2.Canvas.Pen.color := clFuchsia;

      PaintBox2.Canvas.Pen.Width := 4;
      PaintBox2.Canvas.MoveTo(0, PaintBox2.Height - 1);


      error2 := 0;

      {$IFNDEF BP}
      for kPaso:=1 to high(Cerebros) do
      {$ENDIF}
      begin
        CronVarCF_aprox.Enter(kPaso - 1);
        CronVarError.Enter(kPaso - 1);
        for kRec := 0 to high(XCF_[kPaso - 1]) do
        begin
          aRec := XCF_[kPaso - 1][kRec];
          CF_real := aRec.CF;

          Cerebros[kPaso].SetEntradas(aRec.X);

         {for jEntrada := 0 to dimX - 1 do
              Cerebros[kPaso].SetEntrada(jEntrada, aRec.X.e(jEntrada + 1)); }

          Cerebros[kPaso].evaluar;
          CFAprox := Cerebros[kPaso].Salida_CapaN.Neuronas[0].salida;

          CronVarCF_aprox.valores[kRec] := CFAprox;
          CronVarError.valores[kRec] := (CFAprox - CF_real){/maxCF};

          if abs(CFAprox) < 1e10 then
            error2 := error2 + sqr(CFAprox - CF_real);
        end;

        error2 := sqrt(error2 / high(XCF_[kPaso - 1]));


        //Cerebro.WriteToArchi('cerebro_mp'+IntToStr(kPaso)+'.xlt');

        PaintBox2.Canvas.LineTo(
          trunc((kpaso - 1) / length(XCF_) * PaintBOx2.Width),
          trunc(PaintBox2.Height * (1 - (error2 / maxCF))));

      end;
    end
    else
    if  (min_resValCosto-resValCosto) < 1E-3 then
         paso := paso * 1
      else
         paso := paso * 0.9997;

    //paso := paso* 0.9997;

    application.ProcessMessages;
  end;

  {$IFDEF BP}
  end;
  {$ENDIF}

  setSeparadoresGlobales;

  HistoCF := TPrintCronVar_histograma.Create(CronVarCF, 'CF',
    'CF', 'MUSD', 4, 2, True, True, False, True, probabilidadAisladas, True,
    False, True, -maxCF, maxCF);
  HistoCF_aprox := TPrintCronVar_histograma.Create(CronVarCF_aprox, 'CF_aprox',
    'CF_aprox', 'MUSD', 4, 2, True, True, False, True, probabilidadAisladas, True,
    False, True, -maxCF, maxCF);
  HistoError := TPrintCronVar_histograma.Create(CronVarError, 'Error CF-CF_aprox',
    'Error CF-CF_aprox', 'p.u', 4, 2, True, True, False, True,
    probabilidadAisladas, True, False, True, -maxCF, maxCF);


  HistoCF.imprimirse(xlt);
  HistoCF_aprox.imprimirse(xlt);
  HistoError.imprimirse(xlt);
  xlt.Guardar('CF_aproximacion_Neurona_.xls');
  xlt.Cerrar;

  //X.Free;
 // grad_ant.Free;

end;

procedure TForm1.Button2Click(Sender: TObject);
var
  nombre, carpeta, archi,ext,s: String;
  cant_Try, CFAprox,error2,CF_real: NReal;
  data: TMatR;
  kPaso, kTry, kIter, dimX, k, cantCF: Integer;

begin

  setSeparadoresGlobales;

  if XCF_=nil then
  begin
    SetLength(XCF_, CF.nPuntosT - 1);

    for kPaso := 1 to Length(XCF_) do
    begin
      setlength(XCF_[kPaso - 1], CF.nEstrellasPorPuntoT);
      dimX := CF.nVarsContinuas + CF.nVarsDiscretas;
      CF.setEstrellaCERO;
      repeat
        CF.SetEstadoToEstrella;
        XCF_[kPaso - 1][CF.ordinalEstrellaActual] := TRecXCF.Create(dimX, 1);

        for k := 0 to CF.nVarsContinuas - 1 do
          XCF_[kPaso - 1][CF.ordinalEstrellaActual].X.pon_e(k + 1, CF.xr[k]);
        for k := 0 to CF.nVarsDiscretas - 1 do
          XCF_[kPaso - 1][CF.ordinalEstrellaActual].X.pon_e(k + CF.nVarsContinuas, CF.xd[k]);

        XCF_[kPaso - 1][CF.ordinalEstrellaActual].CF := CF.costoEstrella(kPaso) / 1.0E6;


        if XCF_[kPaso - 1][CF.ordinalEstrellaActual].CF > maxCF then
          maxCF := XCF_[kPaso - 1][CF.ordinalEstrellaActual].CF;

        //XCF_[kPaso][CF.ordinalEstrellaActual] := aRec;
      until not CF.IncEstrella;

    end;
  end;




  nombre:='CF_aproximacion_Neurona_.xls';
  ext:= ExtractFileExt( nombre );
  carpeta:= copy( nombre,1, length( nombre ) - length( ext ) );

  carpeta:= carpeta + '_resultados_';

  if not DirectoryExists( carpeta ) then
     raise Exception.Create('No existe el directorio de resultados.');

  kIter:=1;

  archi:=carpeta + DirectorySeparator + 'hoja_CF_aprox' +IntToStr(kIter) + '.xlt' ;

  //Cuento la cantidad de archivos
  while FileExists(archi) do
  begin
    inc(kIter);
    archi:=carpeta + DirectorySeparator + 'hoja_CF_aprox' + IntToStr(kIter) + '.xlt' ;
  end;

  cantCF:=kIter;

  kIter:=1;

  archi:=carpeta + DirectorySeparator + 'hoja_CF_aprox' +IntToStr(kIter) + '.xlt' ;

  //grafico el arror de los CF con respecto al posta
  while FileExists(archi) do
  begin

    data:= cargar(archi);

    for kPaso:=1 to Length(XCF_) do
    begin
      error2:=0;
      for kTry:=1 to Length(XCF_[kPaso-1]) do
      begin
        CFAprox:= data.e(kPaso,kTry);
        CF_real:= XCF_[kPaso-1][kTry-1].CF;

        if abs(CFAprox) < 1e10 then
              error2 := error2 + sqr(CFAprox - CF_real);
      end;

      error2 := sqrt(error2 / high(XCF_[kPaso - 1]));

      PaintBox2.Canvas.LineTo(
        trunc((kpaso - 1) / length(XCF_) * PaintBOx2.Width),
        trunc(PaintBox2.Height * (1 - (error2 / maxCF))));


    end;

    PaintBox2.Canvas.Pen.color :=ColorGradienteAzulRojo(kIter/cantCF) ;

    inc(kIter);
    archi:=carpeta + DirectorySeparator + 'hoja_CF_aprox' + IntToStr(kIter) + '.xlt' ;

  end;





end;


procedure TForm1.cbAutoChange(Sender: TObject);
begin
  while (sbKPaso.Position < sbKPaso.Max) and cbAuto.Checked do
  begin
    application.ProcessMessages;
    sbkpaso.Position := sbkpaso.Position + 12;
    application.ProcessMessages;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  uInicioYFinal.AlFInal;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  aDoc_KML := nil;
  uInicioYFinal.AlInicio;
  setSeparadoresGlobales;
  eMomento.Text := FloatToStr(0.999);
  ePaso.Text := FloatToStr(0.001);
  setSeparadoresLocales;
  {$IFDEF BP}
  cbParsimonia.Enabled:=false;
  cbBPconParsimonia.Enabled:=false;
  cbMaxInBox.Enabled:=false;
  {$ENDIF}

end;



procedure TForm1.sbKPasoChange(Sender: TObject);
begin
  if evaluador <> nil then
  begin
    ekPaso.Text := IntToStr(sbKPaso.Position);
    btVerClick(Sender);
  end;
end;

end.
