ScalerByLeo/Scaler.cl
Nique_372 b435cdff9d
2025-09-18 16:08:06 -05:00

428 lines
12 KiB
Common Lisp

#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;
}
//+------------------------------------------------------------------+
__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;
}
//+------------------------------------------------------------------+
__kernel void standard_scaler_tranform_matrix(
__global const double* mean,
__global const double* std,
__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;
// La compprobacion ya se hace en init
matrix[idx] = (matrix[idx] - mean[col]) / std[col];
}
//+------------------------------------------------------------------+
__kernel void standard_scaler_tranform_vector(
__global const double* mean,
__global const double* std,
__global double* vector
)
{
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];
}
//+------------------------------------------------------------------+
__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];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
__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];
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
__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;
}
*/
//+------------------------------------------------------------------+