2025-09-09 14:15:32 -05:00
|
|
|
#pragma OPENCL EXTENSION cl_khr_fp64 : enable //Tiene que soportar double
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef cl_khr_int64
|
|
|
|
#define entero_signed long
|
|
|
|
#define entero_unsigned ulong
|
|
|
|
#pragma OPENCL EXTENSION cl_khr_int64 : enable
|
|
|
|
#else
|
|
|
|
#define entero_signed int
|
|
|
|
#define entero_unsigned uint
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define min_value 1e-9
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//| |
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void fit_standard_scaler_init(
|
|
|
|
__global double* mean, // Output: [cols]
|
|
|
|
__global double* std, // Output: [cols]
|
|
|
|
__global const double* matrix, // Input: [rows * cols]
|
|
|
|
const entero_unsigned cols,
|
|
|
|
const entero_unsigned rows
|
|
|
|
)
|
|
|
|
{
|
|
|
|
uint col = get_global_id(0); // Solo una dimensión
|
|
|
|
|
|
|
|
if(col >= cols)
|
|
|
|
return;
|
|
|
|
|
|
|
|
//--- media
|
|
|
|
double total_sum = 0.0;
|
|
|
|
for(entero_unsigned row = 0; row < rows; row++)
|
|
|
|
{
|
|
|
|
entero_unsigned idx = row * cols + col;
|
|
|
|
total_sum += matrix[idx];
|
|
|
|
}
|
|
|
|
|
|
|
|
double mean_col = total_sum / rows; //media
|
|
|
|
mean[col] = mean_col;
|
|
|
|
|
|
|
|
double variance_sum = 0.0; //valor inicial
|
|
|
|
|
|
|
|
for(entero_unsigned row = 0; row < rows; row++)
|
|
|
|
{
|
|
|
|
entero_unsigned idx = row * cols + col;
|
|
|
|
double diff = matrix[idx] - mean_col;
|
|
|
|
variance_sum += diff * diff; //obtenemos la variacion Suma
|
|
|
|
}
|
|
|
|
|
|
|
|
double variance = variance_sum / (rows); // ddof=0
|
|
|
|
double std_val = sqrt(variance); //valor del std
|
|
|
|
|
|
|
|
// Evitar división por cero
|
|
|
|
std[col] = (std_val < min_value) ? 1.0 : std_val;
|
|
|
|
}
|
|
|
|
|
2025-09-18 16:08:06 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void standar_scaler_fit_transform_vector(
|
|
|
|
const double mean,
|
|
|
|
const double std,
|
|
|
|
__global double* X_to_scale
|
|
|
|
)
|
|
|
|
{
|
|
|
|
uint idx = get_global_id(0);
|
|
|
|
X_to_scale[idx] = (X_to_scale[idx] - mean) / std;
|
|
|
|
}
|
|
|
|
|
2025-09-09 14:15:32 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void standard_scaler_tranform_matrix(
|
|
|
|
__global const double* mean,
|
|
|
|
__global const double* std,
|
|
|
|
__global double* matrix,
|
|
|
|
const entero_unsigned cols
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//2 dimensiones
|
2025-09-18 16:08:06 -05:00
|
|
|
const uint row = get_global_id(0);
|
|
|
|
const uint col = get_global_id(1);
|
2025-09-09 14:15:32 -05:00
|
|
|
|
|
|
|
entero_unsigned idx = row * cols + col;
|
2025-09-18 16:08:06 -05:00
|
|
|
|
|
|
|
// La compprobacion ya se hace en init
|
|
|
|
matrix[idx] = (matrix[idx] - mean[col]) / std[col];
|
2025-09-09 14:15:32 -05:00
|
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void standard_scaler_tranform_vector(
|
|
|
|
__global const double* mean,
|
|
|
|
__global const double* std,
|
|
|
|
__global double* vector
|
|
|
|
)
|
|
|
|
{
|
2025-09-18 16:08:06 -05:00
|
|
|
const uint idx = get_global_id(0);
|
|
|
|
// esta funcion ya esta cargada por lo que std ya esta corregido (si es que era muy pequeño)
|
|
|
|
vector[idx] = (vector[idx] - mean[idx]) / std[idx];
|
2025-09-09 14:15:32 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-09-18 16:08:06 -05:00
|
|
|
|
2025-09-09 14:15:32 -05:00
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void standard_scaler_inverse_tranform_matrix(
|
|
|
|
__global const double* mean,
|
|
|
|
__global const double* std,
|
|
|
|
__global double* matrix,
|
|
|
|
const entero_unsigned cols
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//2 dimensiones
|
|
|
|
uint row = get_global_id(0);
|
|
|
|
uint col = get_global_id(1);
|
|
|
|
|
|
|
|
entero_unsigned idx = row * cols + col;
|
|
|
|
matrix[idx] = matrix[idx] * std[col] + mean[col];
|
|
|
|
} //X_unscaled[row][col] = X_to_unscale[row][col] * this.std[col] + this.mean[col];
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void standard_scaler_inverse_tranform_vector(
|
|
|
|
__global const double* mean,
|
|
|
|
__global const double* std,
|
|
|
|
__global double* vector
|
|
|
|
)
|
|
|
|
{
|
|
|
|
uint idx = get_global_id(0);
|
|
|
|
vector[idx] = vector[idx] * std[idx] + mean[idx] ;
|
|
|
|
} //X_unscaled[i] = X_to_unscale[i] * this.std[i] + this.mean[i];
|
|
|
|
|
2025-09-18 16:08:06 -05:00
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//| |
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void fit_scaler_max_min_init(
|
|
|
|
__global double* min_values, // Output: [cols]
|
|
|
|
__global double* max_values, // Output: [cols]
|
|
|
|
__global const double* matrix, // Input: [rows * cols]
|
|
|
|
const entero_unsigned cols,
|
|
|
|
const entero_unsigned rows
|
|
|
|
)
|
|
|
|
{
|
|
|
|
const uint col = get_global_id(0); // Solo una dimensión
|
|
|
|
|
|
|
|
// variables inicales
|
|
|
|
double max_col = DBL_MIN;
|
|
|
|
double min_col = DBL_MAX;
|
|
|
|
|
|
|
|
// Macro incial
|
|
|
|
#define value(prow , pcol) matrix[prow * cols + pcol]
|
|
|
|
|
|
|
|
|
|
|
|
// Encontramos el miaxmo y minimo
|
|
|
|
for(int i = 0; i < rows; i++)
|
|
|
|
{
|
|
|
|
const double val = value(i, col);
|
|
|
|
if(val > max_col)
|
|
|
|
max_col = val;
|
|
|
|
|
|
|
|
if(val < min_col)
|
|
|
|
min_col = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Correcion de valores pequeños
|
|
|
|
if(max_col - min_col < min_value)
|
|
|
|
max_col = min_col + 1.0;
|
|
|
|
|
|
|
|
// Escritura
|
|
|
|
max_values[col] = max_col;
|
|
|
|
min_values[col] = min_col;
|
|
|
|
#undef value
|
|
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void max_min_scaler_fit_transform_vector(
|
|
|
|
const double min_data,
|
|
|
|
const double max_data,
|
|
|
|
__global double* vector
|
|
|
|
)
|
|
|
|
{
|
|
|
|
const uint idx = get_global_id(0); // Indice en la primera dimension
|
|
|
|
vector[idx] = (vector[idx] - min_data) / (max_data - min_data); // la comprobacion de division se hace en mql
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void max_min_scaler_tranform_matrix(
|
|
|
|
__global const double* min_values, //vector
|
|
|
|
__global const double* max_values, // vector
|
|
|
|
__global double* matrix, // matriz
|
|
|
|
const entero_unsigned cols
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//2 dimensiones
|
|
|
|
const uint row = get_global_id(0);
|
|
|
|
const uint col = get_global_id(1);
|
|
|
|
|
|
|
|
entero_unsigned idx = row * cols + col;
|
|
|
|
// la comprobacion de rango se ha hecho en init (los valores ya estan corregidos)
|
|
|
|
matrix[idx] = (matrix[idx] - min_values[col]) / (max_values[col] - min_values[col]);
|
|
|
|
}
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void max_min_scaler_tranform_vector(
|
|
|
|
__global const double* min_values,
|
|
|
|
__global const double* max_values,
|
|
|
|
__global double* vector
|
|
|
|
)
|
|
|
|
{
|
|
|
|
const uint idx = get_global_id(0);
|
|
|
|
// esta funcion ya esta cargada por lo que range ya esta corregido (si es que era muy pequeño)
|
|
|
|
vector[idx] = (vector[idx] - min_values[idx]) / (max_values[idx] - min_values[idx]);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void min_max_inverse_tranform_matrix(
|
|
|
|
__global const double* min_values,
|
|
|
|
__global const double* max_values,
|
|
|
|
__global double* matrix,
|
|
|
|
const entero_unsigned cols
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//2 dimensiones
|
|
|
|
const uint row = get_global_id(0);
|
|
|
|
const uint col = get_global_id(1);
|
|
|
|
|
|
|
|
entero_unsigned idx = row * cols + col;
|
|
|
|
matrix[idx] = matrix[idx] * (max_values[col] - min_values[col]) + min_values[col];
|
|
|
|
}
|
|
|
|
// X_unscaled[row][col] = X_to_unscale[row][col] * (this.max_vals[col] - this.min_vals[col]) + this.min_vals[col];
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void max_min_scaler_inverse_tranform_vector(
|
|
|
|
__global const double* min_values,
|
|
|
|
__global const double* max_values,
|
|
|
|
__global double* vector
|
|
|
|
)
|
|
|
|
{
|
|
|
|
const uint idx = get_global_id(0);
|
|
|
|
vector[idx] = vector[idx] * (max_values[idx] - min_values[idx]) + min_values[idx];
|
|
|
|
} // X_unscaled[i] = X_to_unscale[i] * (this.max_vals[i] - this.min_vals[i]) + this.min_vals[i];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-09 14:15:32 -05:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//| |
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void ExtractMatrixToScaler(
|
|
|
|
__global const double* data, //solo lectura
|
|
|
|
__global double* result, //Escritura y lectura
|
|
|
|
const entero_unsigned rows_data,
|
|
|
|
const entero_unsigned cols_data,
|
|
|
|
const entero_unsigned rows_res,
|
|
|
|
const entero_unsigned cols_res,
|
|
|
|
const entero_unsigned cols_to_escale, //numero de columnas a extraer desde el inicio
|
|
|
|
const entero_unsigned start_col
|
|
|
|
)
|
|
|
|
{
|
|
|
|
uint row = get_global_id(0);
|
|
|
|
uint col = get_global_id(1);
|
|
|
|
|
|
|
|
entero_unsigned idx_data = row * cols_data + (col + start_col);
|
|
|
|
entero_unsigned idx_res = row * cols_res + col; // Asumiendo mismas dimensiones
|
|
|
|
result[idx_res] = data[idx_data];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
matrix ScalerBase::ExtractMatrixToScale(const matrix &X) const
|
|
|
|
{
|
|
|
|
matrix result;
|
|
|
|
|
|
|
|
if(use_custom)
|
|
|
|
{
|
|
|
|
result.Init(X.Rows(), count_cols);
|
|
|
|
|
|
|
|
for(entero_unsigned row = 0; row < X.Rows(); row++)
|
|
|
|
for(entero_unsigned col = 0; col < count_cols; col++)
|
|
|
|
result[row][col] = X[row][start_col + col];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
entero_unsigned cols_to_scale = X.Cols() - excluyed_cols;
|
|
|
|
result.Init(X.Rows(), cols_to_scale);
|
|
|
|
|
|
|
|
for(entero_unsigned row = 0; row < X.Rows(); row++)
|
|
|
|
for(entero_unsigned col = 0; col < cols_to_scale; col++)
|
|
|
|
result[row][col] = X[row][col];
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//| |
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void ExtractVectorToScale(
|
|
|
|
__global const double* data,
|
|
|
|
__global double* result,
|
|
|
|
const entero_unsigned start_col,
|
|
|
|
const entero_unsigned count_cols
|
|
|
|
)
|
|
|
|
{
|
|
|
|
uint idx = get_global_id(0);
|
|
|
|
result[idx] = data[start_col + idx];
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
vector ScalerBaseCL::ExtractVectorToScale(const vector &X) const
|
|
|
|
{
|
|
|
|
vector result;
|
|
|
|
|
|
|
|
if(use_custom)
|
|
|
|
{
|
|
|
|
// Extraer rango específico
|
|
|
|
result.Resize(count_cols);
|
|
|
|
for(entero_unsigned i = 0; i < count_cols; i++)
|
|
|
|
result[i] = X[start_col + i];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Extraer todas excepto las últimas N
|
|
|
|
entero_unsigned size_to_scale = X.Size() - excluyed_cols;
|
|
|
|
result.Resize(size_to_scale);
|
|
|
|
for(entero_unsigned i = 0; i < size_to_scale; i++)
|
|
|
|
result[i] = X[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//| |
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void ReconstructVector(
|
|
|
|
__global const double* data, //data
|
|
|
|
__global double* result, //resultado
|
|
|
|
const entero_unsigned start_col,
|
|
|
|
const entero_unsigned count_cols
|
|
|
|
)
|
|
|
|
{
|
|
|
|
uint idx = get_global_id(0);
|
|
|
|
result[idx + start_col] = data[idx]; //No es necesario comprobar ya se da eltamaño
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
vector ScalerBaseCL::ReconstructVector(const vector &X_original, const vector &X_scaled) const
|
|
|
|
{
|
|
|
|
vector result = X_original;
|
|
|
|
|
|
|
|
if(use_custom)
|
|
|
|
{
|
|
|
|
// Reemplazar rango específico
|
|
|
|
for(entero_unsigned i = 0; i < count_cols; i++)
|
|
|
|
result[start_col + i] = X_scaled[i];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Reemplazar todas excepto las últimas N
|
|
|
|
for(entero_unsigned i = 0; i < X_scaled.Size(); i++)
|
|
|
|
result[i] = X_scaled[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
//| |
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
__kernel void ReconstructMatrix(
|
|
|
|
__global const double* scaled_data, // X_scaled
|
|
|
|
__global double* original_result, // X_original
|
|
|
|
const entero_unsigned rows_data,
|
|
|
|
const entero_unsigned cols_data,
|
|
|
|
const entero_unsigned rows_res,
|
|
|
|
const entero_unsigned cols_res,
|
|
|
|
const entero_unsigned cols_to_insert, // Columnas a insertar
|
|
|
|
const entero_unsigned start_col // Posición donde insertar
|
|
|
|
)
|
|
|
|
{
|
|
|
|
uint row = get_global_id(0);
|
|
|
|
uint col = get_global_id(1);
|
|
|
|
|
|
|
|
// Leer desde X_scaled
|
|
|
|
entero_unsigned idx_scaled = row * cols_to_insert + col;
|
|
|
|
|
|
|
|
// Escribir en X_original en posición específica
|
|
|
|
entero_unsigned target_col = start_col + col;
|
|
|
|
|
|
|
|
|
|
|
|
entero_unsigned idx_result = row * cols_res + target_col;
|
|
|
|
|
|
|
|
original_result[idx_result] = scaled_data[idx_scaled];
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
matrix ScalerBaseCL::ReconstructMatrix(const matrix &X_original, const matrix &X_scaled) const
|
|
|
|
{
|
|
|
|
matrix result = X_original; // Copia completa
|
|
|
|
|
|
|
|
if(use_custom)
|
|
|
|
{
|
|
|
|
for(entero_unsigned row = 0; row < X_original.Rows(); row++)
|
|
|
|
for(entero_unsigned col = 0; col < count_cols; col++)
|
|
|
|
result[row][start_col + col] = X_scaled[row][col];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for(entero_unsigned row = 0; row < X_original.Rows(); row++)
|
|
|
|
for(entero_unsigned col = 0; col < X_scaled.Cols(); col++)
|
|
|
|
result[row][col] = X_scaled[row][col];
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
//+------------------------------------------------------------------+
|