ScalerByLeo/ScalerBaseCL.mqh
Nique_372 2420303dbd
2025-09-22 09:44:56 -05:00

1531 lines
118 KiB
MQL5

//+------------------------------------------------------------------+
//| ScalerBaseCLCL.mqh |
//| Copyright 2025, Leo. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Leo."
#property link "https://www.mql5.com"
#property strict
#ifndef SCALER_CL_BY_LEO_GEN_MQH
#define SCALER_CL_BY_LEO_GEN_MQH
#include "..\\MQLArticles\\Utils\\File.mqh"
#ifdef SCALER_BASE_CL_DEBUG
#include "..\\CLByLeo\\CL.mqh"
#else
#include "..\\CLByLeo\\CLFast.mqh"
#endif
//+------------------------------------------------------------------+
//| Scaler Base |
//+------------------------------------------------------------------+
#resource "Scaler.cl" as const string cl_scaler_program
//--- Generales
#define SCALER_MIN_VAL 1e-9
//--- Principal - Global
#define cl_scaler_kernels_total 10
#define cl_scaler_buffers_total 8
//--- Kernels globales
#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 globales
//--- Kernel[0] para la funcion de inicilizacino fit
#define kernel_fit_transform_init 4
// argumentos
#define kernel_fit_transform_init_arg_cols 3
#define kernel_fit_transform_init_arg_rows 4
//--- Kernel[1] para la transformacion (2) usso, ademas esta funcion recibe los mismo argumento que fit, solo qeu no incluye rows
#define kernel_matrix_transform 5
//--- Kenel[2] para tranforma vector
#define kernel_vector_transform 6 //se usan los mimos argunmenso global_....
//--- kernel[3] para desescalar data matrix, recibe los mismo parametros que el kernel 1
#define kernel_inverse_tranform_matrix 7
//--- kernel[4] para desescalar data vector recibe los mismo parametros que el kernel 2
#define kernel_inverse_transform_vector 8
//--- Kernel para el fit transform de vector
#define kernel_fit_transform_vector 9
#define kernel_fit_transform_vector_arg_data1 0
#define kernel_fit_transform_vector_arg_data2 1
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool ScalerCheckSizeCustomM(const matrix &mtx, ulong start_col, ulong count_cols, ulong excluyed_cols)
{
if(start_col >= mtx.Cols())
{
FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Columna de inicio %I64u >= total columnas %I64u", start_col, mtx.Cols()));
return false;
}
if(start_col + count_cols > mtx.Cols())
{
FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Rango [%I64u:%I64u] excede columnas disponibles %I64u", start_col, start_col + count_cols - 1, mtx.Cols()));
return false;
}
return true;
}
//+------------------------------------------------------------------+
bool ScalerCheckSizeExcludedM(const matrix &mtx, ulong start_col, ulong count_cols, ulong excluyed_cols)
{
if(mtx.Cols() < excluyed_cols)
{
FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Columnas a excluir %I64u >= total columnas %I64u", excluyed_cols, mtx.Cols()));
return false;
}
return true;
}
//+------------------------------------------------------------------+
bool ScalerCheckSizeCustomV(const vector &v, ulong start_col, ulong count_cols, ulong excluyed_cols)
{
if(start_col >= v.Size())
{
FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Columna de inicio %I64u >= tamaño total del vector%I64u", start_col, v.Size()));
return false;
}
if(start_col + count_cols > v.Size())
{
FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Rango [%I64u:%I64u] excede el tamaño del vector %I64u", start_col, start_col + count_cols - 1, v.Size()));
return false;
}
return true;
}
//+------------------------------------------------------------------+
bool ScalerCheckSizeExcludedV(const vector &v, ulong start_col, ulong count_cols, ulong excluyed_cols)
{
if(v.Size() < excluyed_cols)
{
FastLog(FUNCION_ACTUAL, ERROR_TEXT, StringFormat("Columnas a excluir %I64u >= tamaño del vector: %I64u", excluyed_cols, v.Size()));
return false;
}
return true;
}
//+------------------------------------------------------------------+
typedef bool(*ScalerFuncionCheckV)(const vector &v, ulong start_col, ulong count_cols, ulong excluyed_cols);
typedef bool(*ScalerFuncionCheckM)(const matrix &mtx, ulong start_col, ulong count_cols, ulong excluyed_cols);
//---
template <typename T> //T es uint o ulong
class ScalerBaseCL : public CLoggerBase
{
private:
//---
static void CleanBufferVector();
static void CleanBufferMatrix();
protected:
static COpenCL cl;
static string type_suported;
static bool open_cl_is_create;
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
ScalerFuncionCheckM CheckSizeMatrix;
ScalerFuncionCheckV CheckSizeVector;
//---
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
virtual matrix fit_transform(matrix &X, bool save_data) = 0;
virtual vector fit_transform(vector &X) = 0; //Para vectores no se guarda data
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 string ScalerBaseCL::type_suported = "";
//+------------------------------------------------------------------+
template <typename T> ScalerBaseCL::ScalerBaseCL()
: start_col(0), count_cols(0), use_custom(false), excluyed_cols(1), file_name_out(NULL), loaded_scaler(false)
{
CheckSizeMatrix = ScalerCheckSizeExcludedM;
CheckSizeVector = ScalerCheckSizeExcludedV;
if(open_cl_is_create == false)
{
const int divice = CL_USE_ANY;
cl.ContextCreate(divice);
cl.ProgramCreate(cl_scaler_program);
if(cl.SupportDouble() == false)
{
LogFatalError("Es necesario que el divice soporte double para calculos precisos", FUNCION_ACTUAL);
Remover();
return;
}
type_suported = cl.SupportInt64() ? "ulong" : "uint";
cl.SetKernelsCount(cl_scaler_kernels_total);
cl.SetBuffersCount(cl_scaler_buffers_total);
if(cl.KernelCreate(kernel_matrix_extraer, "ExtractMatrixToScaler") == false)
{
Remover();
return;
}
if(cl.KernelCreate(kernel_vector_extraer, "ExtractVectorToScale") == false)
{
Remover();
return;
}
if(cl.KernelCreate(kernel_vector_reconstruir, "ReconstructVector") == false)
{
Remover();
return;
}
if(cl.KernelCreate(kernel_matrix_reconstruir, "ReconstructMatrix") == false)
{
Remover();
return;
}
open_cl_is_create = true;
}
if(typename(T) != type_suported)
{
LogError(StringFormat("El device solo soporta %s, clase creada con %s", type_suported, typename(T)), FUNCION_ACTUAL);
Remover();
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
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);
CheckSizeMatrix = ScalerCheckSizeCustomM;
CheckSizeVector = ScalerCheckSizeCustomV;
}
//+------------------------------------------------------------------+
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);
CheckSizeMatrix = ScalerCheckSizeExcludedM;
CheckSizeVector = ScalerCheckSizeExcludedV;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
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;
ulong cols_to_scale = 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;
ulong size_to_scale = 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);
}
//+------------------------------------------------------------------+
//| Standardization Scaler |
//+------------------------------------------------------------------+
template <typename T> //T = (uint o ulong) S = (float o double)
class StandardizationScalerCL : public ScalerBaseCL<T>
{
protected:
vector mean, std;
bool Save() override;
bool Load(string prefix_name) override;
public:
StandardizationScalerCL();
vector fit_transform(vector &X) override; //Para vectores no se guarda data
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> StandardizationScalerCL::StandardizationScalerCL()
{
this.prefix_file = "_mean_std.csv";
//--- Seteamos los kernels restantes
if(!cl.KernelCreate(kernel_fit_transform_init, "fit_standard_scaler_init"))
{
Remover();
return;
}
if(!cl.KernelCreate(kernel_matrix_transform, "standard_scaler_tranform_matrix"))
{
Remover();
return;
}
if(!cl.KernelCreate(kernel_vector_transform, "standard_scaler_tranform_vector"))
{
Remover();
return;
}
if(!cl.KernelCreate(kernel_inverse_tranform_matrix, "standard_scaler_inverse_tranform_matrix"))
{
Remover();
return;
}
if(!cl.KernelCreate(kernel_inverse_transform_vector, "standard_scaler_inverse_tranform_vector"))
{
Remover();
return;
}
if(!cl.KernelCreate(kernel_fit_transform_vector, "standar_scaler_fit_transform_vector"))
{
Remover();
return;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
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));
//--- Establecemos una unica vez
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(!CheckSizeVector(X, start_col, count_cols, excluyed_cols))
return X;
//---
vector X_to_scaled = ExtractVectorToScale(X);
//---
double mean_val = X_to_scaled.Mean();
double std_val = X_to_scaled.Std();
if(std_val < SCALER_MIN_VAL)
std_val = 1.0;
//---
cl.BufferFromVector(global_vector_to_escale, X_to_scaled, CL_MEM_READ_WRITE);
cl.SetArgument(kernel_fit_transform_vector, kernel_fit_transform_vector_arg_data1, mean_val);
cl.SetArgument(kernel_fit_transform_vector, kernel_fit_transform_vector_arg_data2, std_val);
cl.SetArgumentBuffer(kernel_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_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(!CheckSizeMatrix(X, start_col, count_cols, excluyed_cols))
return X;
//---
matrix X_to_scale = ExtractMatrixToScale(X);
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); //lectura y escritura en los 3 buffers
//--- Argumentos 1
cl.SetArgumentBuffer(kernel_fit_transform_init, global_buffer_data_1, global_buffer_data_1);
cl.SetArgumentBuffer(kernel_fit_transform_init, global_buffer_data_2, global_buffer_data_2);
cl.SetArgumentBuffer(kernel_fit_transform_init, global_matrix_to_escale, global_matrix_to_escale);
cl.SetArgument(kernel_fit_transform_init, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols());
cl.SetArgument(kernel_fit_transform_init, kernel_fit_transform_init_arg_rows, (T)X_to_scale.Rows());
const static uint work_off_set[1] = {0}; //no offset
uint work_size[1] = { (uint)X_to_scale.Cols() };
cl.Execute(kernel_fit_transform_init, 1, work_off_set, work_size);
//--- Argumentos 2
cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_1, global_buffer_data_1);
cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_2, global_buffer_data_2);
cl.SetArgumentBuffer(kernel_matrix_transform, global_matrix_to_escale, global_matrix_to_escale);
cl.SetArgument(kernel_matrix_transform, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols());
const static uint work_off_tranforst[2] = {0, 0}; //no offset
uint work_size_tranfors[2] = { (uint)X_to_scale.Rows(), (uint)X_to_scale.Cols() };
cl.Execute(kernel_matrix_transform, 2, work_off_tranforst, work_size_tranfors);
matrix X_scaled(X_to_scale.Rows(), X_to_scale.Cols());
cl.BufferToMatrix(global_matrix_to_escale, X_scaled, X_scaled.Rows(), X_scaled.Cols());
//---
if(save_data)
{
this.mean = mean_cts;
this.std = std_cts;
}
//--- Limpiar los buffers
CleanBuffersOnlyData(); //Buffers de data
CleanExtraData(); //Data extra, dado que fit transforn se pude usar con difernetes mean/st
//--- Aqui siempre se reconstruye
return ReconstructMatrix(X, X_scaled);
}
//+------------------------------------------------------------------+
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(!CheckSizeMatrix(X, start_col, count_cols, excluyed_cols))
return X;
//---
matrix X_to_scale = solo_escalar_lo_previsto ? ExtractMatrixToScale(X) : X;
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); //lectura y escritura en los 3 buffers
cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY); //mean lecutra
cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY); //std lecutra
//--- Argumentos
cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_1, global_buffer_data_1); // mean
cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_2, global_buffer_data_2); // std
cl.SetArgumentBuffer(kernel_matrix_transform, global_matrix_to_escale, global_matrix_to_escale); // matrix a escalar
cl.SetArgument(kernel_matrix_transform, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols()); //columnas
const static uint work_off_set[2] = {0, 0}; //no offset
uint work_size_tranfors[2] = { (uint)X_to_scale.Rows(), (uint)X_to_scale.Cols() };
cl.Execute(kernel_matrix_transform, 2, work_off_set, work_size_tranfors);
matrix X_scaled(X_to_scale.Rows(), X_to_scale.Cols());
cl.BufferToMatrix(global_matrix_to_escale, X_scaled, X_scaled.Rows(), X_scaled.Cols());
//--- Limpiar los buffers
CleanBuffersOnlyData();
//---
if(reconstruir)
return ReconstructMatrix(X, X_scaled);
else
return X_scaled;
}
//+------------------------------------------------------------------+
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;
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); //lectura y escritura en los 3 buffers
cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY); //mean lecutra
cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY); //std lecutra
//--- Argumentos
cl.SetArgumentBuffer(kernel_vector_transform, global_buffer_data_1, global_buffer_data_1); // mean
cl.SetArgumentBuffer(kernel_vector_transform, global_buffer_data_2, global_buffer_data_2); // std
cl.SetArgumentBuffer(kernel_vector_transform, kernel_arg_index_all_vector_to_escale, global_vector_to_escale); // vector a escalar
//---
const static uint work_off_set[1] = {0}; //no offset
uint work_size_tranfors[1] = { (uint)X_to_scale.Size()}; //solo 1 dimension por lo tanto seran Size trabajadores
cl.Execute(kernel_vector_transform, 1, work_off_set, work_size_tranfors); //Ejeuctamos el kernel
//---
vector X_scaled(X_to_scale.Size());
cl.BufferToVector(global_vector_to_escale, X_scaled, X_scaled.Size());
//--- Limpiar los buffers
CleanBuffersOnlyData();
//---
if(reconstruir)
return ReconstructVector(X, X_scaled);
else
return X_scaled;
}
//+------------------------------------------------------------------+
template <typename T>
//Oye aqyu solo escalar lo provisto se vbuelve solo_desescalar_lo_previsto, no puedo cambiar nombre... pero ya ssabes no te confundas
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;
//---
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;
}
//--- Nuevo buffer
cl.BufferFromMatrix(global_matrix_to_escale, X_to_unscale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers
cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY); //mean lecutra
cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY); //std lecutra
//--- Argumentos
cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_buffer_data_1, global_buffer_data_1); // mean
cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_buffer_data_2, global_buffer_data_2); // std
cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_matrix_to_escale, global_matrix_to_escale); // matrix a escalar
cl.SetArgument(kernel_inverse_tranform_matrix, kernel_fit_transform_init_arg_cols, (T)X_to_unscale.Cols()); //columnas
const static uint work_off_set[2] = {0, 0}; //no offset
uint work_size_tranfors[2] = { (uint)X_to_unscale.Rows(), (uint)X_to_unscale.Cols() }; //2 dimensiones matriz
cl.Execute(kernel_inverse_tranform_matrix, 2, work_off_set, work_size_tranfors);
matrix X_unscaled(X_to_unscale.Rows(), X_to_unscale.Cols());
cl.BufferToMatrix(global_matrix_to_escale, X_unscaled, X_to_unscale.Rows(), X_to_unscale.Cols()); //Leeemos para nueva matriz
//--- Limpiar los buffers
CleanBuffersOnlyData();
//---
if(reconstruir)
return ReconstructMatrix(X_scaled, X_unscaled);
else
return X_unscaled;
}
//+------------------------------------------------------------------+
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;
//---
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); //lectura y escritura en los 3 buffers
cl.BufferFromVector(global_buffer_data_1, mean, CL_MEM_READ_ONLY); //mean lecutra
cl.BufferFromVector(global_buffer_data_2, std, CL_MEM_READ_ONLY); //std lecutra
//--- Argumentos
cl.SetArgumentBuffer(kernel_inverse_transform_vector, global_buffer_data_1, global_buffer_data_1); // mean
cl.SetArgumentBuffer(kernel_inverse_transform_vector, global_buffer_data_2, global_buffer_data_2); // std
cl.SetArgumentBuffer(kernel_inverse_transform_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale); // vector a escalar
//---
const static uint work_off_set[1] = {0}; //no offset
uint work_size_tranfors[1] = { (uint)X_to_unscale.Size()}; //solo 1 dimension por lo tanto seran Size trabajadores
cl.Execute(kernel_inverse_transform_vector, 1, work_off_set, work_size_tranfors); //Ejeuctamos el kernel
vector X_unscaled(X_to_unscale.Size());
cl.BufferToVector(global_vector_to_escale, X_unscaled, X_unscaled.Size());
//--- Limpiar los buffers
CleanBuffersOnlyData();
//---
if(reconstruir)
return ReconstructVector(X_scaled, X_unscaled);
else
return X_unscaled;
}
//+------------------------------------------------------------------+
//| MaxMin Scaler |
//+------------------------------------------------------------------+
//---
template <typename T>
class MaxMinScalerCL : public ScalerBaseCL<T>
{
protected:
vector min_vals, max_vals;
bool Save() override;
bool Load(string prefix_name) override;
public:
MaxMinScalerCL();
//---
vector fit_transform(vector &X) override; //Para vectores no se guarda data
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> MaxMinScalerCL::MaxMinScalerCL(void)
{
this.prefix_file = "_min_max.csv";
//--- Seteamos los kernels restantes
if(!cl.KernelCreate(kernel_fit_transform_init, "fit_scaler_max_min_init"))
{
Remover();
return;
}
if(!cl.KernelCreate(kernel_matrix_transform, "max_min_scaler_tranform_matrix"))
{
Remover();
return;
}
if(!cl.KernelCreate(kernel_vector_transform, "max_min_scaler_tranform_vector"))
{
Remover();
return;
}
if(!cl.KernelCreate(kernel_inverse_tranform_matrix, "min_max_inverse_tranform_matrix"))
{
Remover();
return;
}
if(!cl.KernelCreate(kernel_inverse_transform_vector, "max_min_scaler_inverse_tranform_vector"))
{
Remover();
return;
}
if(!cl.KernelCreate(kernel_fit_transform_vector, "max_min_scaler_fit_transform_vector"))
{
Remover();
return;
}
}
//+------------------------------------------------------------------+
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(!CheckSizeVector(X, start_col, count_cols, excluyed_cols))
return X;
//---
vector X_to_scaled = ExtractVectorToScale(X);
//--- Obtenemos el maximo y miunimo cpu
double min = X_to_scaled.Min();
double max = X_to_scaled.Max();
//--- Modifcamos el max si el valor rango es pequeño
if((max - min) < SCALER_MIN_VAL)
max = min + 1.0;
//--- Establecemos argumentos y creamos y escribimos en el buffer
cl.BufferFromVector(global_vector_to_escale, X_to_scaled, CL_MEM_READ_WRITE); // Bufer vector
cl.SetArgument(kernel_fit_transform_vector, kernel_fit_transform_vector_arg_data1, min);
cl.SetArgument(kernel_fit_transform_vector, kernel_fit_transform_vector_arg_data2, max);
cl.SetArgumentBuffer(kernel_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_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(!CheckSizeMatrix(X, start_col, count_cols, excluyed_cols))
return X;
//---
matrix X_to_scale = ExtractMatrixToScale(X);
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());
//--- Creacion de los 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); //lectura y escritura en los 3 buffers
//--- Argumentos 1
cl.SetArgumentBuffer(kernel_fit_transform_init, global_buffer_data_1, global_buffer_data_1);
cl.SetArgumentBuffer(kernel_fit_transform_init, global_buffer_data_2, global_buffer_data_2);
cl.SetArgumentBuffer(kernel_fit_transform_init, global_matrix_to_escale, global_matrix_to_escale);
cl.SetArgument(kernel_fit_transform_init, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols());
cl.SetArgument(kernel_fit_transform_init, kernel_fit_transform_init_arg_rows, (T)X_to_scale.Rows());
const static uint work_off_set[1] = {0}; //no offset
uint work_size[1] = { (uint)X_to_scale.Cols() };
cl.Execute(kernel_fit_transform_init, 1, work_off_set, work_size);
//--- Argumentos 2
cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_1, global_buffer_data_1);
cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_2, global_buffer_data_2);
cl.SetArgumentBuffer(kernel_matrix_transform, global_matrix_to_escale, global_matrix_to_escale);
cl.SetArgument(kernel_matrix_transform, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols());
const static uint work_off_tranforst[2] = {0, 0}; //no offset
uint work_size_tranfors[2] = { (uint)X_to_scale.Rows(), (uint)X_to_scale.Cols() };
cl.Execute(kernel_matrix_transform, 2, work_off_tranforst, work_size_tranfors);
matrix X_scaled(X_to_scale.Rows(), X_to_scale.Cols());
cl.BufferToMatrix(global_matrix_to_escale, X_scaled, X_scaled.Rows(), X_scaled.Cols());
//---
if(save_data)
{
this.min_vals = min_cts;
this.max_vals = max_cts;
}
//--- Limpiar los buffers
CleanBuffersOnlyData(); //Buffers de data
CleanExtraData(); //Data extra, dado que fit transforn se pude usar con difernetes mean/st
//--- Aqui siempre se reconstruye
return ReconstructMatrix(X, X_scaled);
}
//+------------------------------------------------------------------+
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(!CheckSizeMatrix(X, start_col, count_cols, excluyed_cols))
return X;
//---
matrix X_to_scale = solo_escalar_lo_previsto ? ExtractMatrixToScale(X) : X;
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;
}
//--- Creacion y escribtura de los buffers
cl.BufferFromMatrix(global_matrix_to_escale, X_to_scale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers
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_matrix_transform, global_buffer_data_1, global_buffer_data_1); // min
cl.SetArgumentBuffer(kernel_matrix_transform, global_buffer_data_2, global_buffer_data_2); // max
cl.SetArgumentBuffer(kernel_matrix_transform, global_matrix_to_escale, global_matrix_to_escale); // matrix a escalar
cl.SetArgument(kernel_matrix_transform, kernel_fit_transform_init_arg_cols, (T)X_to_scale.Cols()); //columnas
const static uint work_off_set[2] = {0, 0}; //no offset
uint work_size_tranfors[2] = { (uint)X_to_scale.Rows(), (uint)X_to_scale.Cols() };
cl.Execute(kernel_matrix_transform, 2, work_off_set, work_size_tranfors);
matrix X_scaled(X_to_scale.Rows(), X_to_scale.Cols());
cl.BufferToMatrix(global_matrix_to_escale, X_scaled, X_scaled.Rows(), X_scaled.Cols());
//--- Limpiar los buffers
CleanBuffersOnlyData();
//---
if(reconstruir)
return ReconstructMatrix(X, X_scaled);
else
return X_scaled;
}
//+------------------------------------------------------------------+
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;
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_WRITE_ONLY); //lectura y escritura en los 3 buffers
cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY); //min lecutra
cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY); //max lecutra
//--- Argumentos
cl.SetArgumentBuffer(kernel_vector_transform, global_buffer_data_1, global_buffer_data_1); // min
cl.SetArgumentBuffer(kernel_vector_transform, global_buffer_data_2, global_buffer_data_2); // max
cl.SetArgumentBuffer(kernel_vector_transform, kernel_arg_index_all_vector_to_escale, global_vector_to_escale); // vector a escalar
//---
const static uint work_off_set[1] = {0}; //no offset
uint work_size_tranfors[1] = { (uint)X_to_scale.Size()}; //solo 1 dimension por lo tanto seran Size trabajadores
cl.Execute(kernel_vector_transform, 1, work_off_set, work_size_tranfors); //Ejeuctamos el kernel
//---
vector X_scaled(X_to_scale.Size());
cl.BufferToVector(global_vector_to_escale, X_scaled, X_scaled.Size());
//--- Limpiar los buffers
CleanBuffersOnlyData();
//---
if(reconstruir)
return ReconstructVector(X, X_scaled);
else
return X_scaled;
}
//+------------------------------------------------------------------+
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;
//---
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;
}
//--- Nuevo buffer
cl.BufferFromMatrix(global_matrix_to_escale, X_to_unscale, CL_MEM_READ_WRITE); //lectura y escritura en los 3 buffers
cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY); //min lecutra
cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY); //max lecutra
//--- Argumentos
cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_buffer_data_1, global_buffer_data_1); // min
cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_buffer_data_2, global_buffer_data_2); // max
cl.SetArgumentBuffer(kernel_inverse_tranform_matrix, global_matrix_to_escale, global_matrix_to_escale); // matrix a escalar
cl.SetArgument(kernel_inverse_tranform_matrix, kernel_fit_transform_init_arg_cols, (T)X_to_unscale.Cols()); //columnas
const static uint work_off_set[2] = {0, 0}; //no offset
uint work_size_tranfors[2] = { (uint)X_to_unscale.Rows(), (uint)X_to_unscale.Cols() }; //2 dimensiones matriz
cl.Execute(kernel_inverse_tranform_matrix, 2, work_off_set, work_size_tranfors);
matrix X_unscaled(X_to_unscale.Rows(), X_to_unscale.Cols());
cl.BufferToMatrix(global_matrix_to_escale, X_unscaled, X_to_unscale.Rows(), X_to_unscale.Cols()); //Leeemos para nueva matriz
//--- Limpiar los buffers
CleanBuffersOnlyData();
//---
if(reconstruir)
return ReconstructMatrix(X_scaled, X_unscaled);
else
return X_unscaled;
}
// X_unscaled[row][col] = X_to_unscale[row][col] * (this.max_vals[col] - this.min_vals[col]) + this.min_vals[col];
//+------------------------------------------------------------------+
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;
//---
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); //lectura y escritura en los 3 buffers
cl.BufferFromVector(global_buffer_data_1, min_vals, CL_MEM_READ_ONLY); //min lecutra
cl.BufferFromVector(global_buffer_data_2, max_vals, CL_MEM_READ_ONLY); //max lecutra
//--- Argumentos
cl.SetArgumentBuffer(kernel_inverse_transform_vector, global_buffer_data_1, global_buffer_data_1); // min
cl.SetArgumentBuffer(kernel_inverse_transform_vector, global_buffer_data_2, global_buffer_data_2); // max
cl.SetArgumentBuffer(kernel_inverse_transform_vector, kernel_arg_index_all_vector_to_escale, global_vector_to_escale); // vector a escalar
//---
const static uint work_off_set[1] = {0}; //no offset
uint work_size_tranfors[1] = { (uint)X_to_unscale.Size()}; //solo 1 dimension por lo tanto seran Size trabajadores
cl.Execute(kernel_inverse_transform_vector, 1, work_off_set, work_size_tranfors); //Ejeuctamos el kernel
vector X_unscaled(X_to_unscale.Size());
cl.BufferToVector(global_vector_to_escale, X_unscaled, X_unscaled.Size());
//--- Limpiar los buffers
CleanBuffersOnlyData();
//---
if(reconstruir)
return ReconstructVector(X_scaled, X_unscaled);
else
return X_unscaled;
}
//+------------------------------------------------------------------+
#endif
//+------------------------------------------------------------------+