2041 lines
140 KiB
MQL5
2041 lines
140 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| ScalerBaseCL.mqh |
|
|
//| Copyright 2025, Leo. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2025, Leo."
|
|
#property link "https://www.mql5.com"
|
|
#property strict
|
|
|
|
#ifndef SCALERBYLEO_SCALER_BASE_CL_MQH
|
|
#define SCALERBYLEO_SCALER_BASE_CL_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Include |
|
|
//+------------------------------------------------------------------+
|
|
#ifdef SCALER_BASE_CL_DEBUG
|
|
#include "..\\..\\CLByLeo\\CL.mqh"
|
|
#else
|
|
#include "..\\..\\CLByLeo\\CLFast.mqh"
|
|
#endif
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Defines |
|
|
//+------------------------------------------------------------------+
|
|
#resource "Kernels\\ScalerUint.cl" as const string cl_scaler_program_uint
|
|
#resource "Kernels\\ScalerUlong.cl" as const string cl_scaler_program_ulong
|
|
|
|
|
|
//--- Generales
|
|
#define SCALER_BASE_CL_MIN_VAL 1e-9
|
|
|
|
//--- Principal - Global
|
|
#define cl_scaler_kernels_total 16
|
|
#define cl_scaler_buffers_total 8
|
|
|
|
//--- Kernels globales (compartidos)
|
|
#define kernel_matrix_extraer 0
|
|
#define kernel_matrix_reconstruir 1
|
|
#define kernel_vector_extraer 2
|
|
#define kernel_vector_reconstruir 3
|
|
|
|
//--- Argumentos recons/extraer matrix
|
|
#define kernel_matrix_extraer_recons_arg_buff_data 0
|
|
#define kernel_matrix_extraer_recons_arg_buff_res 1
|
|
#define kernel_matrix_extraer_recons_arg_rows_data 2
|
|
#define kernel_matrix_extraer_recons_arg_cols_data 3
|
|
#define kernel_matrix_extraer_recons_arg_rows_res 4
|
|
#define kernel_matrix_extraer_recons_arg_cols_res 5
|
|
#define kernel_matrix_extraer_recons_arg_extraer_cols 6
|
|
#define kernel_matrix_extraer_recons_arg_start_col 7
|
|
|
|
//--- Kernel global [2] - Kernel[3] Vectores argumentos
|
|
#define kernel_vector_extraer_recons_arg_buff_data 0
|
|
#define kernel_vector_extraer_recons_arg_buff_res 1
|
|
#define kernel_vector_extraer_recons_arg_start_col 2
|
|
#define kernel_vector_extraer_recons_arg_count_col 3
|
|
|
|
//--- Buffers globales
|
|
// argumentos/buffer - no solo de esta funcion GLOBALES
|
|
#define global_buffer_data_1 0 //mean/min/iqrs - buffer
|
|
#define global_buffer_data_2 1 // std/max/medians - buffer
|
|
#define global_matrix_to_escale 2 //Matriz a escalar (transform, fit_tranform, inverse_tranform) - buffer
|
|
#define global_vector_to_escale 3 //Vector a escalar (fit_tranform, inverse_tranform) - buffer
|
|
|
|
// Para extracion de matrizes si es necesario
|
|
#define global_extraer_recos_mtx_matrix_data 4
|
|
#define global_extraer_recos_mtx_matrix_res 5
|
|
|
|
// Para extracion de vecores si es necesario
|
|
#define global_extraer_recos_vec_vector_data 6
|
|
#define global_extraer_recos_vec_vector_res 7
|
|
|
|
|
|
//--- Indice general para el vector data
|
|
// Indice general del vector /TRANSFORM - FITTRANSFORM
|
|
#define kernel_arg_index_all_vector_to_escale 2 //En caso que se escale un vector - indice de argunmento
|
|
|
|
|
|
//--- Kernels StandardizationScaler (4-9)
|
|
#define kernel_standardization_fit_init 4
|
|
#define kernel_standardization_transform_matrix 5
|
|
#define kernel_standardization_transform_vector 6
|
|
#define kernel_standardization_inverse_matrix 7
|
|
#define kernel_standardization_inverse_vector 8
|
|
#define kernel_standardization_fit_transform_vector 9
|
|
|
|
//--- Argumentos StandardizationScaler
|
|
#define kernel_standardization_arg_cols 3
|
|
#define kernel_standardization_arg_rows 4
|
|
|
|
//--- Kernels MaxMinScaler (10-15)
|
|
#define kernel_maxmin_fit_init 10
|
|
#define kernel_maxmin_transform_matrix 11
|
|
#define kernel_maxmin_transform_vector 12
|
|
#define kernel_maxmin_inverse_matrix 13
|
|
#define kernel_maxmin_inverse_vector 14
|
|
#define kernel_maxmin_fit_transform_vector 15
|
|
|
|
//--- Argumentos MaxMinScaler
|
|
#define kernel_maxmin_arg_cols 3
|
|
#define kernel_maxmin_arg_rows 4
|
|
|
|
//--- Argumentos fit_transform_vector (ambos scalers)
|
|
#define kernel_fit_transform_vector_arg_data1 0
|
|
#define kernel_fit_transform_vector_arg_data2 1
|
|
|
|
//---
|
|
#define SCALER_BASE_CL_FINAL_LINE -1
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T> //T es uint o ulong
|
|
class ScalerBaseCL : public CLoggerBase
|
|
{
|
|
private:
|
|
//---
|
|
static void CleanBufferVector();
|
|
static void CleanBufferMatrix();
|
|
|
|
protected:
|
|
static COpenCL cl;
|
|
static uint8_t type_suported;
|
|
static bool open_cl_is_create;
|
|
static bool kernels_base_created;
|
|
|
|
string file_name_out;
|
|
string prefix_file;
|
|
bool loaded_scaler;
|
|
|
|
bool use_custom; //Bandera para saber si se usa custom (true) o excluyed (false)
|
|
T start_col;
|
|
T count_cols;
|
|
T excluyed_cols;
|
|
|
|
virtual bool Save() = 0;
|
|
virtual bool Load(string prefix_name) = 0;
|
|
|
|
//--- Chekear el tamaño
|
|
bool CheckSizeCustom(const matrix &mtx) const;
|
|
bool CheckSizeExcluded(const matrix &mtx) const;
|
|
bool CheckSizeCustom(const vector &v) const;
|
|
bool CheckSizeExcluded(const vector &v) const;
|
|
//---
|
|
void CleanBuffersOnlyData();
|
|
void CleanExtraData();
|
|
|
|
public:
|
|
ScalerBaseCL();
|
|
static inline COpenCL* GetCLPointer() { return GetPointer(cl); }
|
|
|
|
//--- Seteo de rangos
|
|
void SetRangeEscaler(T start_col_, T count_col_); //Custom
|
|
void SetRangeEscaler(T excluyed_cols_ = 1); //Mas simple, el usuario decide cuantas columnas empezando por atras se excluyen
|
|
|
|
//--- Metodos para guardar o cargar
|
|
inline bool save(string prefix_name);
|
|
inline bool load(string prefix_name);
|
|
|
|
//--- Tranformar \ Inverse Transform \ Fit Transform
|
|
//- Fit
|
|
// Transorfmra un archivo
|
|
bool fit_transform_file(const string &file_name, ushort sep, int extra_file_flags, bool save_data, uint file_code_page = CP_ACP, int start_line = 1);
|
|
|
|
// Transforma un archivo y devuelve la matriz
|
|
matrix fit_transform_by_file(const string& file_name, ushort sep, int file_flags, bool save_data, uint file_code_page = CP_ACP,
|
|
int start_line = 1, int end_line = SCALER_BASE_CL_FINAL_LINE);
|
|
|
|
// Transforma un string
|
|
matrix fit_transform_by_src(const string& src, ushort sep, bool save_data, int str_start_line = 1, int str_end_line = SCALER_BASE_CL_FINAL_LINE); // Transforma string
|
|
|
|
// Matrix real
|
|
virtual matrix fit_transform(matrix &X, bool save_data) = 0;
|
|
|
|
// Vector
|
|
virtual vector fit_transform(vector &X) = 0; //Para vectores no se guarda data
|
|
|
|
//- Normal
|
|
virtual matrix transform(matrix &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) = 0;
|
|
virtual vector transform(vector &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) = 0;
|
|
virtual matrix inverse_transform(matrix &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) = 0;
|
|
virtual vector inverse_transform(vector &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) = 0;
|
|
|
|
//--- Extracion
|
|
matrix ExtractMatrixToScale(matrix &X) const;
|
|
vector ExtractVectorToScale(vector &X) const;
|
|
|
|
//--- Reconstruccion
|
|
matrix ReconstructMatrix(matrix &X_original, matrix &X_scaled) const;
|
|
vector ReconstructVector(vector &X_original, vector &X_scaled) const;
|
|
|
|
|
|
//--- Archivos
|
|
virtual inline string GetOutputFile() const final { return this.file_name_out; }
|
|
};
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
static COpenCL ScalerBaseCL::cl;
|
|
template <typename T>
|
|
static bool ScalerBaseCL::open_cl_is_create = false;
|
|
template <typename T>
|
|
static bool ScalerBaseCL::kernels_base_created = false;
|
|
|
|
template <typename t>
|
|
static uint8_t ScalerBaseCL::type_suported = 0;
|
|
|
|
#define SCALER_BASE_CL_FLAG_UINT 1
|
|
#define SCALER_BASE_CL_FLAG_ULONG 2
|
|
|
|
//+------------------------------------------------------------------+
|
|
string ScalerBaseCL_FlagToStr(uint8_t f)
|
|
{
|
|
//---
|
|
if(f == 0)
|
|
{
|
|
return "Indefinido";
|
|
}
|
|
|
|
//---
|
|
string str = "";
|
|
|
|
//---
|
|
if((f & SCALER_BASE_CL_FLAG_UINT) != 0)
|
|
str = "(uint";
|
|
|
|
//---
|
|
if((f & SCALER_BASE_CL_FLAG_ULONG) != 0)
|
|
str += (str == "") ? "(ulong)" : (" Y ulong)");
|
|
else
|
|
str += ")";
|
|
|
|
//---
|
|
return str;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
uint8_t ScalerBaseCL_StrToFlag(const string& in)
|
|
{
|
|
//---
|
|
uint8_t f = 0;
|
|
|
|
//---
|
|
if(in == "uint")
|
|
f |= SCALER_BASE_CL_FLAG_UINT;
|
|
|
|
//---
|
|
if(in == "ulong")
|
|
f |= SCALER_BASE_CL_FLAG_ULONG;
|
|
|
|
//---
|
|
return f;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T> ScalerBaseCL::ScalerBaseCL()
|
|
: start_col(0), count_cols(0), use_custom(false), excluyed_cols(1), file_name_out(NULL), loaded_scaler(false)
|
|
{
|
|
//---
|
|
const string curr_type_s = typename(T);
|
|
uint8_t curr_type = ScalerBaseCL_StrToFlag(curr_type_s);
|
|
|
|
//---
|
|
if(!open_cl_is_create)
|
|
{
|
|
//--- Creamos el contexto
|
|
const int divice = CL_USE_ANY;
|
|
cl.ContextCreate(divice);
|
|
type_suported = cl.SupportInt64() ? (3) : (1); // Si soporta INT64 soporta tambien int32 | solo soporta int32
|
|
|
|
//--- Verificamos que la clase se haya instanciado con el tipo soportado
|
|
if((type_suported & curr_type) == 0)
|
|
{
|
|
LogError(StringFormat("El device solo soporta %s, clase creada con %s", ScalerBaseCL_FlagToStr(type_suported), curr_type_s), FUNCION_ACTUAL);
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
cl.ProgramCreate((curr_type == 3 ? cl_scaler_program_ulong : cl_scaler_program_uint));
|
|
|
|
//---
|
|
if(!cl.SupportDouble())
|
|
{
|
|
LogFatalError("Es necesario que el divice soporte double para calculos precisos", FUNCION_ACTUAL);
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
cl.SetKernelsCount(cl_scaler_kernels_total);
|
|
cl.SetBuffersCount(cl_scaler_buffers_total);
|
|
|
|
//--- Creamos los kerneles base (solo una vez)
|
|
if(!kernels_base_created)
|
|
{
|
|
if(!cl.KernelCreate(kernel_matrix_extraer, "ExtractMatrixToScaler"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
if(!cl.KernelCreate(kernel_vector_extraer, "ExtractVectorToScale"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
if(!cl.KernelCreate(kernel_vector_reconstruir, "ReconstructVector"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
if(!cl.KernelCreate(kernel_matrix_reconstruir, "ReconstructMatrix"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
kernels_base_created = true;
|
|
}
|
|
|
|
//---
|
|
open_cl_is_create = true;
|
|
}
|
|
else
|
|
{
|
|
// Unicamente verirficamos si el tipo con el que se creo la clase es valido
|
|
if((type_suported & curr_type) == 0)
|
|
{
|
|
LogError(StringFormat("El device solo soporta %s, clase creada con %s", ScalerBaseCL_FlagToStr(type_suported), curr_type_s), FUNCION_ACTUAL);
|
|
Remover();
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
bool ScalerBaseCL::CheckSizeCustom(const matrix &mtx) const
|
|
{
|
|
if(start_col >= mtx.Cols())
|
|
{
|
|
LogError(StringFormat("Columna de inicio %I64u >= total columnas %I64u", start_col, mtx.Cols()), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
if(start_col + count_cols > mtx.Cols())
|
|
{
|
|
LogError(StringFormat("Rango [%I64u:%I64u] excede columnas disponibles %I64u", start_col, start_col + count_cols - 1, mtx.Cols()), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
bool ScalerBaseCL::CheckSizeExcluded(const matrix &mtx) const
|
|
{
|
|
if(mtx.Cols() < excluyed_cols)
|
|
{
|
|
LogError(StringFormat("Columnas a excluir %I64u >= total columnas %I64u", excluyed_cols, mtx.Cols()), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
bool ScalerBaseCL::CheckSizeCustom(const vector &v) const
|
|
{
|
|
if(start_col >= v.Size())
|
|
{
|
|
LogError(StringFormat("Columna de inicio %I64u >= tamaño total del vector%I64u", start_col, v.Size()), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
if(start_col + count_cols > v.Size())
|
|
{
|
|
LogError(StringFormat("Rango [%I64u:%I64u] excede el tamaño del vector %I64u", start_col, start_col + count_cols - 1, v.Size()), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
bool ScalerBaseCL::CheckSizeExcluded(const vector &v) const
|
|
{
|
|
if(v.Size() < excluyed_cols)
|
|
{
|
|
LogError(StringFormat("Columnas a excluir %I64u >= tamaño del vector: %I64u", excluyed_cols, v.Size()), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
void ScalerBaseCL::CleanBufferMatrix(void)
|
|
{
|
|
cl.BufferFree(global_extraer_recos_mtx_matrix_data);
|
|
cl.BufferFree(global_extraer_recos_mtx_matrix_res);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
void ScalerBaseCL::CleanBufferVector(void)
|
|
{
|
|
cl.BufferFree(global_extraer_recos_vec_vector_data);
|
|
cl.BufferFree(global_extraer_recos_vec_vector_res);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
void ScalerBaseCL::SetRangeEscaler(T start_col_, T count_col_)
|
|
{
|
|
this.use_custom = true;
|
|
this.count_cols = count_col_;
|
|
this.start_col = start_col_;
|
|
LogInfo(StringFormat("Configurado escalado CUSTOM: columnas %I64u a %I64u (%I64u columnas)", start_col_, start_col_ + count_col_ - 1, count_col_), FUNCION_ACTUAL);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
void ScalerBaseCL::SetRangeEscaler(T excluyed_cols_ = 1)
|
|
{
|
|
this.excluyed_cols = excluyed_cols_;
|
|
this.use_custom = false;
|
|
LogInfo(StringFormat("Configurado escalado EXCLUDED: excluir últimas %I64u columnas", excluyed_cols_), FUNCION_ACTUAL);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
matrix ScalerBaseCL::ExtractMatrixToScale(matrix &X) const
|
|
{
|
|
/*
|
|
Recordemos que previamenet se compmprueba el tamaño asi que no hace falta hacerlo
|
|
*/
|
|
if(use_custom)
|
|
{
|
|
if(X.Cols() == count_cols) //Se extrae todo, asi que no hacemo snada
|
|
return X;
|
|
|
|
matrix result(X.Rows(), count_cols);
|
|
|
|
cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_data, X, CL_MEM_READ_ONLY); //no lo modifica solo lectura
|
|
cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_res, result, CL_MEM_WRITE_ONLY);
|
|
|
|
cl.SetArgumentBuffer(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_buff_data, global_extraer_recos_mtx_matrix_data);
|
|
cl.SetArgumentBuffer(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_buff_res, global_extraer_recos_mtx_matrix_res);
|
|
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_rows_data, (T)X.Rows()); //cast a t dado que cl es stricto
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_cols_data, (T)X.Cols());
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_rows_res, (T)result.Rows());
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_cols_res, (T)result.Cols());
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_extraer_cols, count_cols);
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_start_col, start_col);
|
|
|
|
uint work_off[2] = {0, 0};
|
|
uint work_size[2] = {(uint)result.Rows(), (uint)result.Cols()};
|
|
|
|
cl.Execute(kernel_matrix_extraer, 2, work_off, work_size);
|
|
/* CPU
|
|
for(ulong row = 0; row < X.Rows(); row++)
|
|
for(ulong col = 0; col < count_cols; col++)
|
|
result[row][col] = X[row][start_col + col];
|
|
*/
|
|
|
|
cl.BufferToMatrix(global_extraer_recos_mtx_matrix_res, result, result.Rows(), result.Cols());
|
|
|
|
//---
|
|
CleanBufferMatrix();
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
if(excluyed_cols == 0) //No hay columnas a exlcuir escalar todo
|
|
return X;
|
|
|
|
T cols_to_scale = T(X.Cols() - excluyed_cols);
|
|
matrix result(X.Rows(), cols_to_scale); //Tinee que tener el mismo tamaño
|
|
|
|
cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_data, X, CL_MEM_READ_ONLY);
|
|
cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_res, result, CL_MEM_WRITE_ONLY);
|
|
|
|
cl.SetArgumentBuffer(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_buff_data, global_extraer_recos_mtx_matrix_data);
|
|
cl.SetArgumentBuffer(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_buff_res, global_extraer_recos_mtx_matrix_res);
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_rows_data, (T)X.Rows());
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_cols_data, (T)X.Cols());
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_rows_res, (T)result.Rows());
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_cols_res, (T)result.Cols());
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_extraer_cols, cols_to_scale);
|
|
cl.SetArgument(kernel_matrix_extraer, kernel_matrix_extraer_recons_arg_start_col, (T)0);
|
|
|
|
uint work_off[2] = {0, 0};
|
|
uint work_size[2] = {(uint)result.Rows(), (uint)result.Cols()};
|
|
|
|
cl.Execute(kernel_matrix_extraer, 2, work_off, work_size);
|
|
/*
|
|
for(ulong row = 0; row < X.Rows(); row++)
|
|
for(ulong col = 0; col < cols_to_scale; col++)
|
|
result[row][col] = X[row][col];
|
|
*/
|
|
|
|
|
|
cl.BufferToMatrix(global_extraer_recos_mtx_matrix_res, result, result.Rows(), result.Cols()); //queremos modfiicar result
|
|
|
|
//---
|
|
CleanBufferMatrix();
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
matrix ScalerBaseCL::ReconstructMatrix(matrix &X_original, matrix &X_scaled) const //X_Scaled solo lectura..
|
|
{
|
|
if(X_original.Rows() == X_scaled.Rows() && X_original.Cols() == X_scaled.Cols())
|
|
return X_scaled;
|
|
|
|
matrix result = X_original; // Copia completa
|
|
|
|
if(use_custom)
|
|
{
|
|
cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_data, X_scaled, CL_MEM_READ_ONLY);
|
|
cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_res, result, CL_MEM_READ_WRITE);
|
|
|
|
cl.SetArgumentBuffer(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_buff_data, global_extraer_recos_mtx_matrix_data);
|
|
cl.SetArgumentBuffer(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_buff_res, global_extraer_recos_mtx_matrix_res);
|
|
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_rows_data, (T)X_scaled.Rows());
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_cols_data, (T)X_scaled.Cols());
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_rows_res, (T)result.Rows());
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_cols_res, (T)result.Cols());
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_extraer_cols, count_cols);
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_start_col, start_col);
|
|
|
|
|
|
uint work_off[2] = {0, 0};
|
|
uint work_size[2] = {(uint)X_scaled.Rows(), (uint)X_scaled.Cols()};
|
|
|
|
cl.Execute(kernel_matrix_reconstruir, 2, work_off, work_size);
|
|
|
|
cl.BufferToMatrix(global_extraer_recos_mtx_matrix_res, result, result.Rows(), result.Cols());
|
|
/*
|
|
|
|
for(ulong row = 0; row < X_original.Rows(); row++)
|
|
for(ulong col = 0; col < count_cols; col++)
|
|
result[row][start_col + col] = X_scaled[row][col];*/
|
|
|
|
//---
|
|
CleanBufferMatrix();
|
|
}
|
|
else
|
|
{
|
|
cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_data, X_scaled, CL_MEM_READ_ONLY);
|
|
cl.BufferFromMatrix(global_extraer_recos_mtx_matrix_res, result, CL_MEM_READ_WRITE);
|
|
|
|
cl.SetArgumentBuffer(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_buff_data, global_extraer_recos_mtx_matrix_data);
|
|
cl.SetArgumentBuffer(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_buff_res, global_extraer_recos_mtx_matrix_res);
|
|
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_rows_data, (T)X_scaled.Rows());
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_cols_data, (T)X_scaled.Cols());
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_rows_res, (T)result.Rows());
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_cols_res, (T)result.Cols());
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_extraer_cols, (T)X_scaled.Cols()); //aqui del original...
|
|
cl.SetArgument(kernel_matrix_reconstruir, kernel_matrix_extraer_recons_arg_start_col, (T)0);
|
|
|
|
|
|
uint work_off[2] = {0, 0};
|
|
uint work_size[2] = {(uint)X_scaled.Rows(), (uint)X_scaled.Cols()};
|
|
|
|
cl.Execute(kernel_matrix_reconstruir, 2, work_off, work_size);
|
|
|
|
cl.BufferToMatrix(global_extraer_recos_mtx_matrix_res, result, result.Rows(), result.Cols());
|
|
/* for(ulong row = 0; row < X_original.Rows(); row++)
|
|
for(ulong col = 0; col < X_scaled.Cols(); col++)
|
|
result[row][col] = X_scaled[row][col];*/
|
|
|
|
//---
|
|
CleanBufferMatrix();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
vector ScalerBaseCL::ExtractVectorToScale(vector &X) const
|
|
{
|
|
if(use_custom)
|
|
{
|
|
if(X.Size() == count_cols)
|
|
return X;
|
|
|
|
vector result(count_cols);
|
|
cl.BufferFromVector(global_extraer_recos_vec_vector_data, X, CL_MEM_READ_ONLY); //No se modifica X solo lectura
|
|
cl.BufferFromVector(global_extraer_recos_vec_vector_res, result, CL_MEM_WRITE_ONLY);
|
|
|
|
cl.SetArgumentBuffer(kernel_vector_extraer, kernel_vector_extraer_recons_arg_buff_data, global_extraer_recos_vec_vector_data);
|
|
cl.SetArgumentBuffer(kernel_vector_extraer, kernel_vector_extraer_recons_arg_buff_res, global_extraer_recos_vec_vector_res);
|
|
cl.SetArgument(kernel_vector_extraer, kernel_vector_extraer_recons_arg_start_col, start_col);
|
|
cl.SetArgument(kernel_vector_extraer, kernel_vector_extraer_recons_arg_count_col, count_cols);
|
|
|
|
|
|
// Extraer rango específico
|
|
/*
|
|
result.Resize(count_cols);
|
|
for(ulong i = 0; i < count_cols; i++)
|
|
result[i] = X[start_col + i];*/
|
|
|
|
uint work_off[1] = {0};
|
|
uint work_size[1] = {(uint)result.Size()};
|
|
cl.Execute(kernel_vector_extraer, 1, work_off, work_size);
|
|
cl.BufferToVector(global_extraer_recos_vec_vector_res, result, result.Size());
|
|
|
|
//---
|
|
CleanBufferVector();
|
|
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
if(excluyed_cols == 0)
|
|
return X;
|
|
|
|
T size_to_scale = T(X.Size() - excluyed_cols);
|
|
vector result(size_to_scale);
|
|
|
|
cl.BufferFromVector(global_extraer_recos_vec_vector_data, X, CL_MEM_READ_ONLY); //No se modifica X solo lectura
|
|
cl.BufferFromVector(global_extraer_recos_vec_vector_res, result, CL_MEM_WRITE_ONLY);
|
|
|
|
cl.SetArgumentBuffer(kernel_vector_extraer, kernel_vector_extraer_recons_arg_buff_data, global_extraer_recos_vec_vector_data);
|
|
cl.SetArgumentBuffer(kernel_vector_extraer, kernel_vector_extraer_recons_arg_buff_res, global_extraer_recos_vec_vector_res);
|
|
cl.SetArgument(kernel_vector_extraer, kernel_vector_extraer_recons_arg_start_col, (T)0);
|
|
cl.SetArgument(kernel_vector_extraer, kernel_vector_extraer_recons_arg_count_col, (T)size_to_scale);
|
|
|
|
// Extraer todas excepto las últimas N
|
|
uint work_off[1] = {0};
|
|
uint work_size[1] = {(uint)result.Size()};
|
|
cl.Execute(kernel_vector_extraer, 1, work_off, work_size);
|
|
cl.BufferToVector(global_extraer_recos_vec_vector_res, result, result.Size());
|
|
|
|
//---
|
|
CleanBufferVector();
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
vector ScalerBaseCL::ReconstructVector(vector &X_original, vector &X_scaled) const
|
|
{
|
|
if(X_original.Size() == X_scaled.Size())
|
|
return X_scaled;
|
|
|
|
vector result = X_original;
|
|
|
|
if(use_custom)
|
|
{
|
|
// Reemplazar rango específico
|
|
cl.BufferFromVector(global_extraer_recos_vec_vector_data, X_scaled, CL_MEM_READ_ONLY);
|
|
cl.BufferFromVector(global_extraer_recos_vec_vector_res, result, CL_MEM_READ_WRITE);
|
|
|
|
cl.SetArgumentBuffer(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_buff_data, global_extraer_recos_vec_vector_data);
|
|
cl.SetArgumentBuffer(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_buff_res, global_extraer_recos_vec_vector_res);
|
|
cl.SetArgument(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_start_col, start_col);
|
|
cl.SetArgument(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_count_col, count_cols);
|
|
|
|
uint work_off[1] = {0};
|
|
uint work_size[1] = {(uint) X_scaled.Size()};
|
|
cl.Execute(kernel_vector_reconstruir, 1, work_off, work_size);
|
|
cl.BufferToVector(global_extraer_recos_vec_vector_res, result, result.Size()); //escribimos en el result vector final
|
|
|
|
/*
|
|
for(ulong i = 0; i < count_cols; i++)
|
|
result[start_col + i] = X_scaled[i];
|
|
*/
|
|
|
|
//---
|
|
CleanBufferVector();
|
|
}
|
|
else
|
|
{
|
|
// Reemplazar todas excepto las últimas N
|
|
cl.BufferFromVector(global_extraer_recos_vec_vector_data, X_scaled, CL_MEM_READ_ONLY);
|
|
cl.BufferFromVector(global_extraer_recos_vec_vector_res, result, CL_MEM_READ_WRITE);
|
|
|
|
cl.SetArgumentBuffer(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_buff_data, global_extraer_recos_vec_vector_data);
|
|
cl.SetArgumentBuffer(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_buff_res, global_extraer_recos_vec_vector_res);
|
|
cl.SetArgument(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_start_col, (T)0);
|
|
cl.SetArgument(kernel_vector_reconstruir, kernel_vector_extraer_recons_arg_count_col, (T)X_scaled.Size()); //aqui del original... no del "no_const"
|
|
|
|
uint work_off[1] = {0};
|
|
uint work_size[1] = {(uint) X_scaled.Size()};
|
|
cl.Execute(kernel_vector_reconstruir, 1, work_off, work_size);
|
|
cl.BufferToVector(global_extraer_recos_vec_vector_res, result, result.Size()); //escribimos en el result vector final
|
|
/*
|
|
for(ulong i = 0; i < X_scaled.Size(); i++)
|
|
result[i] = X_scaled[i];*/
|
|
|
|
//---
|
|
CleanBufferVector();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
inline bool ScalerBaseCL::load(string prefix_name)
|
|
{
|
|
loaded_scaler = true;
|
|
return this.Load(prefix_name);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
inline bool ScalerBaseCL::save(string prefix_name)
|
|
{
|
|
this.file_name_out = prefix_name + this.prefix_file;
|
|
return this.Save();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
void ScalerBaseCL::CleanBuffersOnlyData(void)
|
|
{
|
|
cl.BufferFree(global_matrix_to_escale);
|
|
cl.BufferFree(global_vector_to_escale);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
void ScalerBaseCL::CleanExtraData(void)
|
|
{
|
|
cl.BufferFree(global_buffer_data_1);
|
|
cl.BufferFree(global_buffer_data_2);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
/*
|
|
Notas:
|
|
- file_flags: puede tener los valores de FILE_ANSI, FILE_COMON, etc.. las banderas (FILE_READ) ya bienen por derfecto
|
|
*/
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
matrix ScalerBaseCL::fit_transform_by_file(const string& file_name, ushort sep, int file_flags, bool save_data, uint file_code_page = CP_ACP,
|
|
int start_line = 1, int end_line = SCALER_BASE_CL_FINAL_LINE)
|
|
{
|
|
//---
|
|
ResetLastError();
|
|
|
|
//---
|
|
matrix m = {};
|
|
const int file_handle = FileOpen(file_name, (file_flags | FILE_READ | FILE_TXT), '\n', file_code_page);
|
|
if(file_handle == INVALID_HANDLE)
|
|
{
|
|
LogCriticalError(StringFormat("Error al abrir el archivo = %s, ultimo erorr = %d", file_name, GetLastError()), FUNCION_ACTUAL);
|
|
return m;
|
|
}
|
|
|
|
//---
|
|
int curr_line = 0;
|
|
string arr[];
|
|
int dt = 0;
|
|
int curr_row = 0;
|
|
string line = "";
|
|
|
|
//--- Se lee hasta el final
|
|
if(end_line == SCALER_BASE_CL_FINAL_LINE)
|
|
{
|
|
//---
|
|
while(!FileIsEnding(file_handle))
|
|
{
|
|
//---
|
|
line = FileReadString(file_handle);
|
|
|
|
//---
|
|
if(curr_line >= start_line)
|
|
{
|
|
//---
|
|
if((dt = StringSplit(line, sep, arr)) < 1)
|
|
{
|
|
LogError(StringFormat("Linea mal formada = %d:\n%s", curr_line, line), FUNCION_ACTUAL);
|
|
FileClose(file_handle);
|
|
return m;
|
|
}
|
|
|
|
//---
|
|
m.Resize(curr_row + 1, dt);
|
|
for(int i = 0; i < dt; i++)
|
|
{
|
|
m[curr_row][i] = double(arr[i]);
|
|
}
|
|
|
|
//---
|
|
curr_row++;
|
|
}
|
|
|
|
//---
|
|
curr_line++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//---
|
|
while(!FileIsEnding(file_handle))
|
|
{
|
|
//---
|
|
line = FileReadString(file_handle);
|
|
|
|
//---
|
|
if(curr_line >= start_line)
|
|
{
|
|
//---
|
|
if((dt = StringSplit(line, sep, arr)) < 1)
|
|
{
|
|
LogError(StringFormat("Linea mal formada = %d:\n%s", curr_line, line), FUNCION_ACTUAL);
|
|
FileClose(file_handle);
|
|
return m;
|
|
}
|
|
|
|
//---
|
|
m.Resize(curr_row + 1, dt);
|
|
for(int i = 0; i < dt; i++)
|
|
{
|
|
m[curr_row][i] = double(arr[i]);
|
|
}
|
|
|
|
//---
|
|
curr_row++;
|
|
}
|
|
|
|
//---
|
|
curr_line++;
|
|
if(curr_line > end_line)
|
|
break;
|
|
}
|
|
}
|
|
|
|
//---
|
|
FileClose(file_handle);
|
|
|
|
//---
|
|
return fit_transform(m, save_data);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
bool ScalerBaseCL::fit_transform_file(const string &file_name, ushort sep, int extra_file_flags, bool save_data, uint file_code_page = CP_ACP, int start_line = 1)
|
|
{
|
|
//---
|
|
ResetLastError();
|
|
|
|
//---
|
|
matrix m = {};
|
|
int file_handle = FileOpen(file_name, (extra_file_flags | FILE_TXT | FILE_READ), '\n', file_code_page);
|
|
if(file_handle == INVALID_HANDLE)
|
|
{
|
|
LogCriticalError(StringFormat("Error al abrir el archivo = %s, ultimo erorr = %d", file_name, GetLastError()), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
int curr_line = 0;
|
|
string arr[];
|
|
int dt = 0;
|
|
int curr_row = 0;
|
|
string line = "";
|
|
string extra[];
|
|
ArrayResize(extra, 0);
|
|
|
|
|
|
//--- Se lee hasta el final
|
|
while(!FileIsEnding(file_handle))
|
|
{
|
|
//---
|
|
line = FileReadString(file_handle);
|
|
//PrintFormat("'%s'", line);
|
|
|
|
//---
|
|
if(curr_line >= start_line)
|
|
{
|
|
//---
|
|
if((dt = StringSplit(line, sep, arr)) < 1)
|
|
{
|
|
LogError(StringFormat("Linea mal formada = %d:\n%s", curr_line, line), FUNCION_ACTUAL);
|
|
FileClose(file_handle);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
m.Resize(curr_row + 1, dt);
|
|
for(int i = 0; i < dt; i++)
|
|
{
|
|
m[curr_row][i] = double(arr[i]);
|
|
}
|
|
|
|
//---
|
|
curr_row++;
|
|
}
|
|
else
|
|
{
|
|
extra[ArrayResize(extra, ArraySize(extra) + 1) - 1] = line;
|
|
}
|
|
|
|
//---
|
|
curr_line++;
|
|
}
|
|
|
|
|
|
//--- Transformamos y cerramos
|
|
m = fit_transform(m, save_data);
|
|
FileClose(file_handle);
|
|
|
|
//--- Reescribir
|
|
// Abrimos pero en escritura
|
|
file_handle = FileOpen(file_name, (extra_file_flags | FILE_TXT | FILE_WRITE), 0, file_code_page);
|
|
if(file_handle == INVALID_HANDLE)
|
|
{
|
|
LogCriticalError(StringFormat("Error al abrir el archivo = %s, ultimo erorr = %d", file_name, GetLastError()), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
// Init line
|
|
for(int i = 0; i < ArraySize(extra); i++)
|
|
FileWrite(file_handle, extra[i]);
|
|
|
|
// Matrix
|
|
const ulong rows = m.Rows();
|
|
const ulong cols = m.Cols();
|
|
for(ulong row = 0; row < rows; row++)
|
|
{
|
|
//---
|
|
line = "";
|
|
for(ulong col = 0; col < cols; col++)
|
|
{
|
|
line += string(m[row][col]) + ", ";
|
|
}
|
|
StringSetLength(line, StringLen(line) - 2);
|
|
|
|
//---
|
|
FileWrite(file_handle, line);
|
|
}
|
|
|
|
//--- Ceramos el archivo
|
|
FileClose(file_handle);
|
|
|
|
//---
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
matrix ScalerBaseCL::fit_transform_by_src(const string& src, ushort sep, bool save_data, int str_start_line = 1, int str_end_line = SCALER_BASE_CL_FINAL_LINE)
|
|
{
|
|
//---
|
|
matrix m = {};
|
|
|
|
//---
|
|
int curr_line = 0;
|
|
string arr[];
|
|
int dt = 0;
|
|
int curr_row = 0;
|
|
string general_arr[];
|
|
string line = "";
|
|
|
|
//---
|
|
const int total_row = StringSplit(src, '\n', general_arr);
|
|
if(total_row <= str_start_line)
|
|
{
|
|
LogError(StringFormat("Numero de filas del string %d es invalida", total_row), FUNCION_ACTUAL);
|
|
return m;
|
|
}
|
|
|
|
//--- Se lee hasta el final
|
|
if(str_end_line == SCALER_BASE_CL_FINAL_LINE)
|
|
{
|
|
//---
|
|
for(int r = 0; r < total_row; r++)
|
|
{
|
|
//---
|
|
line = general_arr[r];
|
|
|
|
//---
|
|
if(curr_line >= str_start_line)
|
|
{
|
|
//---
|
|
if((dt = StringSplit(line, sep, arr)) < 1)
|
|
{
|
|
LogError(StringFormat("Linea mal formada = %d:\n%s", curr_line, line), FUNCION_ACTUAL);
|
|
return m;
|
|
}
|
|
|
|
//---
|
|
m.Resize(curr_row + 1, dt);
|
|
for(int i = 0; i < dt; i++)
|
|
{
|
|
m[curr_row][i] = double(arr[i]);
|
|
}
|
|
|
|
//---
|
|
curr_row++;
|
|
}
|
|
|
|
//---
|
|
curr_line++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//---
|
|
for(int r = 0; r < total_row; r++)
|
|
{
|
|
//---
|
|
line = general_arr[r];
|
|
|
|
//---
|
|
if(curr_line >= str_start_line)
|
|
{
|
|
//---
|
|
if((dt = StringSplit(line, sep, arr)) < 1)
|
|
{
|
|
LogError(StringFormat("Linea mal formada = %d:\n%s", curr_line, line), FUNCION_ACTUAL);
|
|
return m;
|
|
}
|
|
|
|
//---
|
|
m.Resize(curr_row + 1, dt);
|
|
for(int i = 0; i < dt; i++)
|
|
{
|
|
m[curr_row][i] = double(arr[i]);
|
|
}
|
|
|
|
//---
|
|
curr_row++;
|
|
}
|
|
|
|
//---
|
|
curr_line++;
|
|
if(curr_line > str_end_line)
|
|
break;
|
|
}
|
|
}
|
|
|
|
//---
|
|
return fit_transform(m, save_data);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Standardization Scaler |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
class StandardizationScalerCL : public ScalerBaseCL<T>
|
|
{
|
|
private:
|
|
static bool kernels_created;
|
|
|
|
protected:
|
|
vector mean, std;
|
|
|
|
bool Save() override;
|
|
bool Load(string prefix_name) override;
|
|
|
|
public:
|
|
StandardizationScalerCL();
|
|
vector fit_transform(vector &X) override;
|
|
matrix fit_transform(matrix &X, bool save_data) override;
|
|
matrix transform(matrix &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override;
|
|
vector transform(vector &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override;
|
|
matrix inverse_transform(matrix &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override;
|
|
vector inverse_transform(vector &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override;
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
static bool StandardizationScalerCL::kernels_created = false;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T> StandardizationScalerCL::StandardizationScalerCL()
|
|
{
|
|
this.prefix_file = "_mean_std.csv";
|
|
|
|
//--- Seteamos los kernels (solo una vez)
|
|
if(!kernels_created)
|
|
{
|
|
if(!cl.KernelCreate(kernel_standardization_fit_init, "fit_standard_scaler_init"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
if(!cl.KernelCreate(kernel_standardization_transform_matrix, "standard_scaler_tranform_matrix"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
if(!cl.KernelCreate(kernel_standardization_transform_vector, "standard_scaler_tranform_vector"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
if(!cl.KernelCreate(kernel_standardization_inverse_matrix, "standard_scaler_inverse_tranform_matrix"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
if(!cl.KernelCreate(kernel_standardization_inverse_vector, "standard_scaler_inverse_tranform_vector"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
if(!cl.KernelCreate(kernel_standardization_fit_transform_vector, "standar_scaler_fit_transform_vector"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
kernels_created = true;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
bool StandardizationScalerCL::Save()
|
|
{
|
|
FileDelete(this.file_name_out);
|
|
ResetLastError();
|
|
|
|
//---
|
|
int handle = FileOpen(this.file_name_out, FILE_WRITE | FILE_CSV | FILE_COMMON);
|
|
if(handle == INVALID_HANDLE)
|
|
{
|
|
LogFatalError(StringFormat("Invalid handle Err= %d >> Filename= %s", GetLastError(), this.file_name_out), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
FileWrite(handle, vector_to_string(this.mean));
|
|
FileWrite(handle, vector_to_string(this.std));
|
|
FileWrite(handle, count_cols);
|
|
FileWrite(handle, start_col);
|
|
FileWrite(handle, excluyed_cols);
|
|
FileWrite(handle, (int)use_custom);
|
|
|
|
//---
|
|
FileClose(handle);
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
bool StandardizationScalerCL::Load(string prefix_name)
|
|
{
|
|
this.file_name_out = prefix_name + this.prefix_file;
|
|
|
|
//---
|
|
ResetLastError();
|
|
int handle = FileOpen(file_name_out, FILE_READ | FILE_CSV | FILE_COMMON, "\n");
|
|
if(handle == INVALID_HANDLE)
|
|
{
|
|
LogFatalError(StringFormat("Invalid handle Err= %d >> Filename= %s", GetLastError(), this.file_name_out), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
this.mean = string_to_vector(FileReadString(handle));
|
|
this.std = string_to_vector(FileReadString(handle));
|
|
this.count_cols = (T)StringToInteger(FileReadString(handle));
|
|
this.start_col = (T)StringToInteger(FileReadString(handle));
|
|
this.excluyed_cols = (T)StringToInteger(FileReadString(handle));
|
|
this.use_custom = (bool)StringToInteger(FileReadString(handle));
|
|
|
|
//---
|
|
FileClose(handle);
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
vector StandardizationScalerCL::fit_transform(vector &X)
|
|
{
|
|
if(loaded_scaler)
|
|
{
|
|
LogWarning("Este es un escalador cargado >> no es necesario ajustarlo a los nuevos datos, llame a otra instancia de una clase", FUNCION_ACTUAL);
|
|
return transform(X);
|
|
}
|
|
|
|
//---
|
|
if(use_custom)
|
|
{
|
|
if(!CheckSizeCustom(X))
|
|
return X;
|
|
}
|
|
else
|
|
{
|
|
if(!CheckSizeExcluded(X))
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
vector X_to_scaled = ExtractVectorToScale(X);
|
|
const ulong X_to_scaled_size = X_to_scaled.Size();
|
|
|
|
//---
|
|
double mean_val = X_to_scaled.Mean();
|
|
double std_val = X_to_scaled.Std();
|
|
|
|
if(std_val < SCALER_BASE_CL_MIN_VAL)
|
|
std_val = 1.0;
|
|
|
|
//---
|
|
cl.BufferFromVector(global_vector_to_escale, X_to_scaled, CL_MEM_READ_WRITE);
|
|
cl.SetArgument(kernel_standardization_fit_transform_vector, kernel_fit_transform_vector_arg_data1, mean_val);
|
|
cl.SetArgument(kernel_standardization_fit_transform_vector, kernel_fit_transform_vector_arg_data2, std_val);
|
|
cl.SetArgumentBuffer(kernel_standardization_fit_transform_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale);
|
|
|
|
//---
|
|
uint work_size[1] = { (uint)X_to_scaled_size };
|
|
uint offset[1] = {0};
|
|
|
|
if(!cl.Execute(kernel_standardization_fit_transform_vector, 1, offset, work_size))
|
|
return X;
|
|
|
|
//---
|
|
cl.BufferToVector(global_vector_to_escale, X_to_scaled, X_to_scaled_size);
|
|
return ReconstructVector(X, X_to_scaled);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
matrix StandardizationScalerCL::fit_transform(matrix &X, bool save_data)
|
|
{
|
|
if(loaded_scaler)
|
|
{
|
|
LogWarning("Este es un escalador cargado >> no es necesario ajustarlo a los nuevos datos, llame a otra instancia de una clase", FUNCION_ACTUAL);
|
|
return transform(X);
|
|
}
|
|
|
|
LogInfo(StringFormat("Numero de columnas de entrada: %I64u", X.Cols()), FUNCION_ACTUAL);
|
|
|
|
//---
|
|
if(use_custom)
|
|
{
|
|
if(!CheckSizeCustom(X))
|
|
return X;
|
|
}
|
|
else
|
|
{
|
|
if(!CheckSizeExcluded(X))
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
matrix X_to_scale = ExtractMatrixToScale(X);
|
|
const ulong X_to_scale_cols = X_to_scale.Cols();
|
|
const ulong X_to_scale_rows = X_to_scale.Rows();
|
|
|
|
LogInfo(StringFormat("Columnas a escalar: %I64u", X_to_scale_cols), FUNCION_ACTUAL);
|
|
|
|
//---
|
|
vector mean_cts(X_to_scale_cols);
|
|
vector std_cts(X_to_scale_cols);
|
|
|
|
//---
|
|
cl.BufferFromVector(global_buffer_data_1, mean_cts, CL_MEM_READ_WRITE);
|
|
cl.BufferFromVector(global_buffer_data_2, std_cts, CL_MEM_READ_WRITE);
|
|
cl.BufferFromMatrix(global_matrix_to_escale, X_to_scale, CL_MEM_READ_WRITE);
|
|
|
|
//--- Argumentos 1
|
|
cl.SetArgumentBuffer(kernel_standardization_fit_init, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_standardization_fit_init, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_standardization_fit_init, global_matrix_to_escale, global_matrix_to_escale);
|
|
cl.SetArgument(kernel_standardization_fit_init, kernel_standardization_arg_cols, (T)X_to_scale_cols);
|
|
cl.SetArgument(kernel_standardization_fit_init, kernel_standardization_arg_rows, (T)X_to_scale_rows);
|
|
|
|
// Read
|
|
cl.BufferToVector(global_buffer_data_1, mean_cts, X_to_scale_cols);
|
|
cl.BufferToVector(global_buffer_data_2, std_cts, X_to_scale_cols);
|
|
|
|
//---
|
|
const static uint work_off_set[1] = {0};
|
|
uint work_size[1] = { (uint)X_to_scale_cols };
|
|
|
|
cl.Execute(kernel_standardization_fit_init, 1, work_off_set, work_size);
|
|
|
|
//--- Argumentos 2
|
|
cl.SetArgumentBuffer(kernel_standardization_transform_matrix, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_standardization_transform_matrix, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_standardization_transform_matrix, global_matrix_to_escale, global_matrix_to_escale);
|
|
cl.SetArgument(kernel_standardization_transform_matrix, kernel_standardization_arg_cols, (T)X_to_scale_cols);
|
|
|
|
// Read
|
|
const static uint work_off_tranforst[2] = {0, 0};
|
|
uint work_size_tranfors[2] = { (uint)X_to_scale_rows, (uint)X_to_scale_cols };
|
|
cl.Execute(kernel_standardization_transform_matrix, 2, work_off_tranforst, work_size_tranfors);
|
|
|
|
//---
|
|
cl.BufferToMatrix(global_matrix_to_escale, X_to_scale, X_to_scale_rows, X_to_scale_cols);
|
|
|
|
//---
|
|
if(save_data)
|
|
{
|
|
this.mean = mean_cts;
|
|
this.std = std_cts;
|
|
}
|
|
|
|
//--- Limpiar los buffers
|
|
CleanBuffersOnlyData();
|
|
CleanExtraData();
|
|
|
|
//--- Aqui siempre se reconstruye
|
|
return ReconstructMatrix(X, X_to_scale);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
matrix StandardizationScalerCL::transform(matrix &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false)
|
|
{
|
|
if(!loaded_scaler)
|
|
{
|
|
LogError("Primero llame a fit_transform o load() antes de transform", FUNCION_ACTUAL);
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
if(use_custom)
|
|
{
|
|
if(!CheckSizeCustom(X))
|
|
return X;
|
|
}
|
|
else
|
|
{
|
|
if(!CheckSizeExcluded(X))
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
matrix X_to_scale = solo_escalar_lo_previsto ? ExtractMatrixToScale(X) : X;
|
|
const ulong X_to_scale_cols = X_to_scale.Cols();
|
|
const ulong X_to_scale_rows = X_to_scale.Rows();
|
|
|
|
//---
|
|
if(X_to_scale_cols != this.mean.Size())
|
|
{
|
|
LogError(StringFormat("Columnas a escalar %I64u != columnas entrenadas %u", X_to_scale_cols, this.mean.Size()), FUNCION_ACTUAL);
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
cl.BufferFromMatrix(global_matrix_to_escale, X_to_scale, CL_MEM_READ_WRITE);
|
|
cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY);
|
|
cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY);
|
|
|
|
//--- Argumentos
|
|
cl.SetArgumentBuffer(kernel_standardization_transform_matrix, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_standardization_transform_matrix, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_standardization_transform_matrix, global_matrix_to_escale, global_matrix_to_escale);
|
|
cl.SetArgument(kernel_standardization_transform_matrix, kernel_standardization_arg_cols, (T)X_to_scale_cols);
|
|
|
|
//---
|
|
const static uint work_off_set[2] = {0, 0};
|
|
uint work_size_tranfors[2] = { (uint)X_to_scale_rows, (uint)X_to_scale_cols };
|
|
cl.Execute(kernel_standardization_transform_matrix, 2, work_off_set, work_size_tranfors);
|
|
|
|
//---
|
|
cl.BufferToMatrix(global_matrix_to_escale, X_to_scale, X_to_scale_rows, X_to_scale_cols);
|
|
|
|
//--- Limpiar los buffers
|
|
CleanBuffersOnlyData();
|
|
|
|
//---
|
|
return (reconstruir) ? ReconstructMatrix(X, X_to_scale) : X_to_scale;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
vector StandardizationScalerCL::transform(vector &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false)
|
|
{
|
|
if(!loaded_scaler)
|
|
{
|
|
LogError("Primero llame a fit_transform o load() antes de transform", FUNCION_ACTUAL);
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
vector X_to_scale = solo_escalar_lo_previsto ? ExtractVectorToScale(X) : X;
|
|
const ulong X_to_scale_size = X_to_scale.Size();
|
|
|
|
if(X_to_scale_size != this.mean.Size())
|
|
{
|
|
LogError(StringFormat("Elementos a escalar %I64u != elementos entrenados %u", X_to_scale_size, this.mean.Size()), FUNCION_ACTUAL);
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
cl.BufferFromVector(global_vector_to_escale, X_to_scale, CL_MEM_READ_WRITE);
|
|
cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY);
|
|
cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY);
|
|
|
|
//--- Argumentos
|
|
cl.SetArgumentBuffer(kernel_standardization_transform_vector, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_standardization_transform_vector, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_standardization_transform_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale);
|
|
|
|
//---
|
|
const static uint work_off_set[1] = {0};
|
|
uint work_size_tranfors[1] = { (uint)X_to_scale_size};
|
|
cl.Execute(kernel_standardization_transform_vector, 1, work_off_set, work_size_tranfors);
|
|
|
|
//---
|
|
cl.BufferToVector(global_vector_to_escale, X_to_scale, X_to_scale_size);
|
|
|
|
//--- Limpiar los buffers
|
|
CleanBuffersOnlyData();
|
|
|
|
//---
|
|
return (reconstruir) ? ReconstructVector(X, X_to_scale) : X_to_scale;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
matrix StandardizationScalerCL::inverse_transform(matrix &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false)
|
|
{
|
|
if(!loaded_scaler)
|
|
{
|
|
LogError("Escalador no entrenado. Llame primero a fit_transform", FUNCION_ACTUAL);
|
|
return X_scaled;
|
|
}
|
|
|
|
//---
|
|
matrix X_to_unscale = (solo_escalar_lo_previsto) ? ExtractMatrixToScale(X_scaled) : X_scaled;
|
|
const ulong X_to_unscale_cols = X_to_unscale.Cols();
|
|
const ulong X_to_unscale_rows = X_to_unscale.Rows();
|
|
|
|
//---
|
|
if(X_to_unscale_cols != this.mean.Size())
|
|
{
|
|
LogError(StringFormat("Columnas escaladas %I64u != columnas entrenadas %u", X_to_unscale_cols, this.mean.Size()), FUNCION_ACTUAL);
|
|
return X_scaled;
|
|
}
|
|
|
|
//---
|
|
cl.BufferFromMatrix(global_matrix_to_escale, X_to_unscale, CL_MEM_READ_WRITE);
|
|
cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY);
|
|
cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY);
|
|
|
|
//--- Argumentos
|
|
cl.SetArgumentBuffer(kernel_standardization_inverse_matrix, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_standardization_inverse_matrix, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_standardization_inverse_matrix, global_matrix_to_escale, global_matrix_to_escale);
|
|
cl.SetArgument(kernel_standardization_inverse_matrix, kernel_standardization_arg_cols, (T)X_to_unscale_cols);
|
|
|
|
//---
|
|
const static uint work_off_set[2] = {0, 0};
|
|
uint work_size_tranfors[2] = { (uint)X_to_unscale_rows, (uint)X_to_unscale_cols };
|
|
cl.Execute(kernel_standardization_inverse_matrix, 2, work_off_set, work_size_tranfors);
|
|
|
|
//---
|
|
cl.BufferToMatrix(global_matrix_to_escale, X_to_unscale, X_to_unscale_rows, X_to_unscale_cols);
|
|
|
|
//--- Limpiar los buffers
|
|
CleanBuffersOnlyData();
|
|
|
|
//---
|
|
return (reconstruir) ? ReconstructMatrix(X_scaled, X_to_unscale) : X_to_unscale;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
vector StandardizationScalerCL::inverse_transform(vector &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false)
|
|
{
|
|
if(!loaded_scaler)
|
|
{
|
|
LogError("Escalador no entrenado. Llame primero a fit_transform", FUNCION_ACTUAL);
|
|
return X_scaled;
|
|
}
|
|
|
|
//---
|
|
vector X_to_unscale = (solo_escalar_lo_previsto) ? ExtractVectorToScale(X_scaled) : X_scaled;
|
|
const ulong X_to_unscale_size = X_to_unscale.Size();
|
|
|
|
//---
|
|
if(X_to_unscale_size != this.mean.Size())
|
|
{
|
|
LogError(StringFormat("Elementos escalados %I64u != elementos entrenados %u", X_to_unscale_size, this.mean.Size()), FUNCION_ACTUAL);
|
|
return X_scaled;
|
|
}
|
|
|
|
//---
|
|
cl.BufferFromVector(global_vector_to_escale, X_to_unscale, CL_MEM_READ_WRITE);
|
|
cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY);
|
|
cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY);
|
|
|
|
//--- Argumentos
|
|
cl.SetArgumentBuffer(kernel_standardization_inverse_vector, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_standardization_inverse_vector, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_standardization_inverse_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale);
|
|
|
|
//---
|
|
const static uint work_off_set[1] = {0};
|
|
uint work_size_tranfors[1] = { (uint)X_to_unscale_size};
|
|
cl.Execute(kernel_standardization_inverse_vector, 1, work_off_set, work_size_tranfors);
|
|
|
|
//---
|
|
cl.BufferToVector(global_vector_to_escale, X_to_unscale, X_to_unscale_size);
|
|
|
|
//--- Limpiar los buffers
|
|
CleanBuffersOnlyData();
|
|
|
|
//---
|
|
return (reconstruir) ? ReconstructVector(X_scaled, X_to_unscale) : X_to_unscale;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| MaxMin Scaler |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
class MaxMinScalerCL : public ScalerBaseCL<T>
|
|
{
|
|
private:
|
|
static bool kernels_created;
|
|
|
|
protected:
|
|
vector min_vals, max_vals;
|
|
|
|
bool Save() override;
|
|
bool Load(string prefix_name) override;
|
|
|
|
public:
|
|
MaxMinScalerCL();
|
|
|
|
vector fit_transform(vector &X) override;
|
|
matrix fit_transform(matrix &X, bool save_data) override;
|
|
matrix transform(matrix &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override;
|
|
vector transform(vector &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override;
|
|
matrix inverse_transform(matrix &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override;
|
|
vector inverse_transform(vector &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false) override;
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
static bool MaxMinScalerCL::kernels_created = false;
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T> MaxMinScalerCL::MaxMinScalerCL(void)
|
|
{
|
|
this.prefix_file = "_min_max.csv";
|
|
|
|
//--- Seteamos los kernels (solo una vez)
|
|
if(!kernels_created)
|
|
{
|
|
if(!cl.KernelCreate(kernel_maxmin_fit_init, "fit_scaler_max_min_init"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
if(!cl.KernelCreate(kernel_maxmin_transform_matrix, "max_min_scaler_tranform_matrix"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
if(!cl.KernelCreate(kernel_maxmin_transform_vector, "max_min_scaler_tranform_vector"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
if(!cl.KernelCreate(kernel_maxmin_inverse_matrix, "min_max_inverse_tranform_matrix"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
if(!cl.KernelCreate(kernel_maxmin_inverse_vector, "max_min_scaler_inverse_tranform_vector"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
//---
|
|
if(!cl.KernelCreate(kernel_maxmin_fit_transform_vector, "max_min_scaler_fit_transform_vector"))
|
|
{
|
|
Remover();
|
|
return;
|
|
}
|
|
|
|
kernels_created = true;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
bool MaxMinScalerCL::Save()
|
|
{
|
|
FileDelete(this.file_name_out);
|
|
ResetLastError();
|
|
|
|
//---
|
|
int handle = FileOpen(this.file_name_out, FILE_WRITE | FILE_CSV | FILE_COMMON);
|
|
if(handle == INVALID_HANDLE)
|
|
{
|
|
LogFatalError(StringFormat("Invalid handle Err= %d >> Filename= %s", GetLastError(), this.file_name_out), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
FileWrite(handle, vector_to_string(this.min_vals));
|
|
FileWrite(handle, vector_to_string(this.max_vals));
|
|
FileWrite(handle, count_cols);
|
|
FileWrite(handle, start_col);
|
|
FileWrite(handle, excluyed_cols);
|
|
FileWrite(handle, (int)use_custom);
|
|
|
|
//---
|
|
FileClose(handle);
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
bool MaxMinScalerCL::Load(string prefix_name)
|
|
{
|
|
this.file_name_out = prefix_name + this.prefix_file;
|
|
|
|
//---
|
|
ResetLastError();
|
|
int handle = FileOpen(file_name_out, FILE_READ | FILE_CSV | FILE_COMMON, "\n");
|
|
if(handle == INVALID_HANDLE)
|
|
{
|
|
LogFatalError(StringFormat("Invalid handle Err= %d >> Filename= %s", GetLastError(), this.file_name_out), FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
this.min_vals = string_to_vector(FileReadString(handle));
|
|
this.max_vals = string_to_vector(FileReadString(handle));
|
|
this.count_cols = (T)StringToInteger(FileReadString(handle));
|
|
this.start_col = (T)StringToInteger(FileReadString(handle));
|
|
this.excluyed_cols = (T)StringToInteger(FileReadString(handle));
|
|
this.use_custom = (bool)StringToInteger(FileReadString(handle));
|
|
|
|
//---
|
|
FileClose(handle);
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
vector MaxMinScalerCL::fit_transform(vector &X)
|
|
{
|
|
if(loaded_scaler)
|
|
{
|
|
LogWarning("Este es un escalador cargado >> no es necesario ajustarlo a los nuevos datos, llame a otra instancia de una clase", FUNCION_ACTUAL);
|
|
return transform(X);
|
|
}
|
|
|
|
//---
|
|
if(use_custom)
|
|
{
|
|
if(!CheckSizeCustom(X))
|
|
return X;
|
|
}
|
|
else
|
|
{
|
|
if(!CheckSizeExcluded(X))
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
vector X_to_scaled = ExtractVectorToScale(X);
|
|
const ulong X_to_scaled_size = X_to_scaled.Size();
|
|
|
|
//---
|
|
double min = X_to_scaled.Min();
|
|
double max = X_to_scaled.Max();
|
|
|
|
if((max - min) < SCALER_BASE_CL_MIN_VAL)
|
|
max = min + 1.0;
|
|
|
|
//---
|
|
cl.BufferFromVector(global_vector_to_escale, X_to_scaled, CL_MEM_READ_WRITE);
|
|
cl.SetArgument(kernel_maxmin_fit_transform_vector, kernel_fit_transform_vector_arg_data1, min);
|
|
cl.SetArgument(kernel_maxmin_fit_transform_vector, kernel_fit_transform_vector_arg_data2, max);
|
|
cl.SetArgumentBuffer(kernel_maxmin_fit_transform_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale);
|
|
|
|
//---
|
|
uint work_size[1] = { (uint)X_to_scaled_size };
|
|
uint offset[1] = {0};
|
|
|
|
if(!cl.Execute(kernel_maxmin_fit_transform_vector, 1, offset, work_size))
|
|
return X;
|
|
|
|
//---
|
|
cl.BufferToVector(global_vector_to_escale, X_to_scaled, X_to_scaled_size);
|
|
return ReconstructVector(X, X_to_scaled);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
matrix MaxMinScalerCL::fit_transform(matrix &X, bool save_data)
|
|
{
|
|
if(loaded_scaler)
|
|
{
|
|
LogWarning("Este es un escalador cargado >> no es necesario ajustarlo a los nuevos datos, llame a otra instancia de una clase", FUNCION_ACTUAL);
|
|
return transform(X);
|
|
}
|
|
|
|
LogInfo(StringFormat("Numero de columnas de entrada: %I64u", X.Cols()), FUNCION_ACTUAL);
|
|
|
|
//---
|
|
if(use_custom)
|
|
{
|
|
if(!CheckSizeCustom(X))
|
|
return X;
|
|
}
|
|
else
|
|
{
|
|
if(!CheckSizeExcluded(X))
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
matrix X_to_scale = ExtractMatrixToScale(X);
|
|
const ulong X_to_scale_cols = X_to_scale.Cols();
|
|
const ulong X_to_scale_rows = X_to_scale.Rows();
|
|
|
|
LogInfo(StringFormat("Columnas a escalar: %I64u", X_to_scale_cols), FUNCION_ACTUAL);
|
|
|
|
//---
|
|
vector min_cts(X_to_scale_cols);
|
|
vector max_cts(X_to_scale_cols);
|
|
|
|
//--- Buffers
|
|
cl.BufferFromVector(global_buffer_data_1, min_cts, CL_MEM_READ_WRITE);
|
|
cl.BufferFromVector(global_buffer_data_2, max_cts, CL_MEM_READ_WRITE);
|
|
cl.BufferFromMatrix(global_matrix_to_escale, X_to_scale, CL_MEM_READ_WRITE);
|
|
|
|
//--- Argumentos 1
|
|
cl.SetArgumentBuffer(kernel_maxmin_fit_init, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_maxmin_fit_init, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_maxmin_fit_init, global_matrix_to_escale, global_matrix_to_escale);
|
|
cl.SetArgument(kernel_maxmin_fit_init, kernel_maxmin_arg_cols, (T)X_to_scale_cols);
|
|
cl.SetArgument(kernel_maxmin_fit_init, kernel_maxmin_arg_rows, (T)X_to_scale_rows);
|
|
|
|
|
|
//---
|
|
const static uint work_off_set[1] = {0};
|
|
uint work_size[1] = { (uint)X_to_scale_cols };
|
|
|
|
cl.Execute(kernel_maxmin_fit_init, 1, work_off_set, work_size);
|
|
|
|
|
|
// Read vector
|
|
cl.BufferToVector(global_buffer_data_1, min_cts, X_to_scale_cols);
|
|
cl.BufferToVector(global_buffer_data_2, max_cts, X_to_scale_cols);
|
|
|
|
//--- Argumentos 2
|
|
cl.SetArgumentBuffer(kernel_maxmin_transform_matrix, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_maxmin_transform_matrix, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_maxmin_transform_matrix, global_matrix_to_escale, global_matrix_to_escale);
|
|
cl.SetArgument(kernel_maxmin_transform_matrix, kernel_maxmin_arg_cols, (T)X_to_scale_cols);
|
|
|
|
// Read matrix
|
|
const static uint work_off_tranforst[2] = {0, 0};
|
|
uint work_size_tranfors[2] = { (uint)X_to_scale_rows, (uint)X_to_scale_cols };
|
|
cl.Execute(kernel_maxmin_transform_matrix, 2, work_off_tranforst, work_size_tranfors);
|
|
|
|
//---
|
|
cl.BufferToMatrix(global_matrix_to_escale, X_to_scale, X_to_scale_rows, X_to_scale_cols);
|
|
|
|
//---
|
|
if(save_data)
|
|
{
|
|
this.min_vals = min_cts;
|
|
this.max_vals = max_cts;
|
|
}
|
|
|
|
//--- Limpiar los buffers
|
|
CleanBuffersOnlyData();
|
|
CleanExtraData();
|
|
|
|
//--- Aqui siempre se reconstruye
|
|
return ReconstructMatrix(X, X_to_scale);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
matrix MaxMinScalerCL::transform(matrix &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false)
|
|
{
|
|
if(!loaded_scaler)
|
|
{
|
|
LogError("Primero llame a fit_transform o load() antes de transform", FUNCION_ACTUAL);
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
if(use_custom)
|
|
{
|
|
if(!CheckSizeCustom(X))
|
|
return X;
|
|
}
|
|
else
|
|
{
|
|
if(!CheckSizeExcluded(X))
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
matrix X_to_scale = solo_escalar_lo_previsto ? ExtractMatrixToScale(X) : X;
|
|
const ulong X_to_scale_cols = X_to_scale.Cols();
|
|
const ulong X_to_scale_rows = X_to_scale.Rows();
|
|
|
|
//---
|
|
if(X_to_scale_cols != this.min_vals.Size())
|
|
{
|
|
LogError(StringFormat("Columnas a escalar %I64u != columnas entrenadas %u", X_to_scale_cols, this.min_vals.Size()), FUNCION_ACTUAL);
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
cl.BufferFromMatrix(global_matrix_to_escale, X_to_scale, CL_MEM_READ_WRITE);
|
|
cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY);
|
|
cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY);
|
|
|
|
//--- Argumentos
|
|
cl.SetArgumentBuffer(kernel_maxmin_transform_matrix, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_maxmin_transform_matrix, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_maxmin_transform_matrix, global_matrix_to_escale, global_matrix_to_escale);
|
|
cl.SetArgument(kernel_maxmin_transform_matrix, kernel_maxmin_arg_cols, (T)X_to_scale_cols);
|
|
|
|
//---
|
|
const static uint work_off_set[2] = {0, 0};
|
|
uint work_size_tranfors[2] = { (uint)X_to_scale_rows, (uint)X_to_scale_cols };
|
|
cl.Execute(kernel_maxmin_transform_matrix, 2, work_off_set, work_size_tranfors);
|
|
|
|
//---
|
|
cl.BufferToMatrix(global_matrix_to_escale, X_to_scale, X_to_scale_rows, X_to_scale_cols);
|
|
|
|
//--- Limpiar los buffers
|
|
CleanBuffersOnlyData();
|
|
|
|
//---
|
|
return (reconstruir) ? ReconstructMatrix(X, X_to_scale) : X_to_scale;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
vector MaxMinScalerCL::transform(vector &X, bool solo_escalar_lo_previsto = false, bool reconstruir = false)
|
|
{
|
|
if(!loaded_scaler)
|
|
{
|
|
LogError("Primero llame a fit_transform o load() antes de transform", FUNCION_ACTUAL);
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
vector X_to_scale = solo_escalar_lo_previsto ? ExtractVectorToScale(X) : X;
|
|
const ulong X_to_scale_size = X_to_scale.Size();
|
|
|
|
if(X_to_scale_size != this.min_vals.Size())
|
|
{
|
|
LogError(StringFormat("Elementos a escalar %I64u != elementos entrenados %u", X_to_scale_size, this.min_vals.Size()), FUNCION_ACTUAL);
|
|
return X;
|
|
}
|
|
|
|
//---
|
|
cl.BufferFromVector(global_vector_to_escale, X_to_scale, CL_MEM_READ_WRITE);
|
|
cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY);
|
|
cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY);
|
|
|
|
//--- Argumentos
|
|
cl.SetArgumentBuffer(kernel_maxmin_transform_vector, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_maxmin_transform_vector, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_maxmin_transform_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale);
|
|
|
|
//---
|
|
const static uint work_off_set[1] = {0};
|
|
uint work_size_tranfors[1] = { (uint)X_to_scale_size};
|
|
cl.Execute(kernel_maxmin_transform_vector, 1, work_off_set, work_size_tranfors);
|
|
|
|
//---
|
|
cl.BufferToVector(global_vector_to_escale, X_to_scale, X_to_scale_size);
|
|
|
|
//--- Limpiar los buffers
|
|
CleanBuffersOnlyData();
|
|
|
|
//---
|
|
return (reconstruir) ? ReconstructVector(X, X_to_scale) : X_to_scale;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
matrix MaxMinScalerCL::inverse_transform(matrix &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false)
|
|
{
|
|
if(!loaded_scaler)
|
|
{
|
|
LogError("Escalador no entrenado. Llame primero a fit_transform", FUNCION_ACTUAL);
|
|
return X_scaled;
|
|
}
|
|
|
|
//---
|
|
matrix X_to_unscale = (solo_escalar_lo_previsto) ? ExtractMatrixToScale(X_scaled) : X_scaled;
|
|
const ulong X_to_unscale_cols = X_to_unscale.Cols();
|
|
const ulong X_to_unscale_rows = X_to_unscale.Rows();
|
|
|
|
//---
|
|
if(X_to_unscale_cols != this.min_vals.Size())
|
|
{
|
|
LogError(StringFormat("Columnas escaladas %I64u != columnas entrenadas %u", X_to_unscale_cols, this.min_vals.Size()), FUNCION_ACTUAL);
|
|
return X_scaled;
|
|
}
|
|
|
|
//---
|
|
cl.BufferFromMatrix(global_matrix_to_escale, X_to_unscale, CL_MEM_READ_WRITE);
|
|
cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY);
|
|
cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY);
|
|
|
|
//--- Argumentos
|
|
cl.SetArgumentBuffer(kernel_maxmin_inverse_matrix, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_maxmin_inverse_matrix, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_maxmin_inverse_matrix, global_matrix_to_escale, global_matrix_to_escale);
|
|
cl.SetArgument(kernel_maxmin_inverse_matrix, kernel_maxmin_arg_cols, (T)X_to_unscale_cols);
|
|
|
|
//---
|
|
const static uint work_off_set[2] = {0, 0};
|
|
uint work_size_tranfors[2] = { (uint)X_to_unscale_rows, (uint)X_to_unscale_cols };
|
|
cl.Execute(kernel_maxmin_inverse_matrix, 2, work_off_set, work_size_tranfors);
|
|
|
|
//---
|
|
cl.BufferToMatrix(global_matrix_to_escale, X_to_unscale, X_to_unscale_rows, X_to_unscale_cols);
|
|
|
|
//--- Limpiar los buffers
|
|
CleanBuffersOnlyData();
|
|
|
|
//---
|
|
return (reconstruir) ? ReconstructMatrix(X_scaled, X_to_unscale) : X_to_unscale;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
vector MaxMinScalerCL::inverse_transform(vector &X_scaled, bool solo_escalar_lo_previsto = false, bool reconstruir = false)
|
|
{
|
|
if(!loaded_scaler)
|
|
{
|
|
LogError("Escalador no entrenado. Llame primero a fit_transform", FUNCION_ACTUAL);
|
|
return X_scaled;
|
|
}
|
|
|
|
//---
|
|
vector X_to_unscale = (solo_escalar_lo_previsto) ? ExtractVectorToScale(X_scaled) : X_scaled;
|
|
const ulong X_to_unscale_size = X_to_unscale.Size();
|
|
|
|
//---
|
|
if(X_to_unscale_size != this.min_vals.Size())
|
|
{
|
|
LogError(StringFormat("Elementos escalados %I64u != elementos entrenados %u", X_to_unscale_size, this.min_vals.Size()), FUNCION_ACTUAL);
|
|
return X_scaled;
|
|
}
|
|
|
|
//---
|
|
cl.BufferFromVector(global_vector_to_escale, X_to_unscale, CL_MEM_READ_WRITE);
|
|
cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY);
|
|
cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY);
|
|
|
|
//--- Argumentos
|
|
cl.SetArgumentBuffer(kernel_maxmin_inverse_vector, global_buffer_data_1, global_buffer_data_1);
|
|
cl.SetArgumentBuffer(kernel_maxmin_inverse_vector, global_buffer_data_2, global_buffer_data_2);
|
|
cl.SetArgumentBuffer(kernel_maxmin_inverse_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale);
|
|
|
|
//---
|
|
const static uint work_off_set[1] = {0};
|
|
uint work_size_tranfors[1] = { (uint)X_to_unscale_size};
|
|
cl.Execute(kernel_maxmin_inverse_vector, 1, work_off_set, work_size_tranfors);
|
|
|
|
//---
|
|
cl.BufferToVector(global_vector_to_escale, X_to_unscale, X_to_unscale_size);
|
|
|
|
//--- Limpiar los buffers
|
|
CleanBuffersOnlyData();
|
|
|
|
//---
|
|
return (reconstruir) ? ReconstructVector(X_scaled, X_to_unscale) : X_to_unscale;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
#endif // SCALERBYLEO_SCALER_BASE_CL_MQH
|
|
//+------------------------------------------------------------------+
|