1531 lines
118 KiB
MQL5
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
|
|
//+------------------------------------------------------------------+
|