162 lines
5 KiB
MQL5
162 lines
5 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| RScalar.mqh |
|
|
//| Copyright 2026, Leo. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2026, Leo."
|
|
#property link "https://www.mql5.com/en/users/nique_372"
|
|
#property strict
|
|
|
|
#ifndef SCALERBYLEO_SRC_SCALER_RSCALER_RSCALAR_MQH
|
|
#define SCALERBYLEO_SRC_SCALER_RSCALER_RSCALAR_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
#include "RBase.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
namespace TSN
|
|
{
|
|
//+------------------------------------------------------------------+
|
|
//| Robust Scaler (CPU) |
|
|
//+------------------------------------------------------------------+
|
|
template<typename TFlt>
|
|
class RobustScaler : public RobustScalerBase<TFlt>
|
|
{
|
|
public:
|
|
RobustScaler(void) { m_type = SCALERBYLEO_SCALER_TYPE_ROBUST; }
|
|
~RobustScaler(void) {}
|
|
|
|
//---
|
|
__forceinline bool FitTransform(const matrix<TFlt> &X, matrix<TFlt> &out);
|
|
bool Transform(const matrix<TFlt> &X, matrix<TFlt> &out);
|
|
bool InverseTransform(const matrix<TFlt> &X_scaled, matrix<TFlt> &out);
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
template<typename TFlt>
|
|
__forceinline bool RobustScaler::FitTransform(const matrix<TFlt> &X, matrix<TFlt> &out)
|
|
{
|
|
//---
|
|
if(!Fit(X))
|
|
return false;
|
|
if(!Transform(X, out))
|
|
return false;
|
|
|
|
//---
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Transform |
|
|
//+------------------------------------------------------------------+
|
|
template<typename TFlt>
|
|
bool RobustScaler::Transform(const matrix<TFlt> &X, matrix<TFlt> &out)
|
|
{
|
|
//---
|
|
if(!m_loaded_scaler)
|
|
{
|
|
m_last_err = SCALERBYLEO_ERR_NOT_TRAINED;
|
|
return false;
|
|
}
|
|
|
|
//--- chekeo de rows
|
|
const ulong rows = X.Rows();
|
|
if(rows == 0)
|
|
{
|
|
m_last_err = SCALERBYLEO_ERR_EMPTY_INPUT;
|
|
return false;
|
|
}
|
|
|
|
//--- chekeo de cols
|
|
const ulong total_cols = X.Cols();
|
|
const ulong fs = m_medians.Size();
|
|
if(m_i_start + fs > total_cols)
|
|
{
|
|
m_last_err = SCALERBYLEO_ERR_SIZE_MISMATCH;
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
// En caso nos obligen a reoncutr y no coinciden entonces
|
|
if(m_reconstruir && fs != total_cols)
|
|
{
|
|
out = X; // copia optimizada (ya probado, conpensa el overwrite)
|
|
// modificamos inplace
|
|
for(ulong c = 0; c < fs; c++)
|
|
for(ulong r = 0; r < rows; r++)
|
|
out[r][m_i_start + c] = TFlt((double(X[r][m_i_start + c]) - m_medians[c]) * m_iqrs_inv[c]);
|
|
}
|
|
else
|
|
{
|
|
// De lo contrario exacto asi que inplace
|
|
out.Resize(rows, fs);
|
|
for(ulong c = 0; c < fs; c++)
|
|
for(ulong r = 0; r < rows; r++)
|
|
out[r][c] = TFlt((double(X[r][m_i_start + c]) - m_medians[c]) * m_iqrs_inv[c]);
|
|
}
|
|
|
|
//---
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| InverseTransform |
|
|
//+------------------------------------------------------------------+
|
|
template<typename TFlt>
|
|
bool RobustScaler::InverseTransform(const matrix<TFlt> &X_scaled, matrix<TFlt> &out)
|
|
{
|
|
//---
|
|
if(!m_loaded_scaler)
|
|
{
|
|
m_last_err = SCALERBYLEO_ERR_NOT_TRAINED;
|
|
return false;
|
|
}
|
|
|
|
//--- chekeo de rows
|
|
const ulong rows = X_scaled.Rows();
|
|
if(rows == 0)
|
|
{
|
|
m_last_err = SCALERBYLEO_ERR_EMPTY_INPUT;
|
|
return false;
|
|
}
|
|
|
|
//--- chekeo de cols
|
|
const ulong total_cols = X_scaled.Cols();
|
|
const ulong fs = m_medians.Size();
|
|
if(m_i_start + fs > total_cols)
|
|
{
|
|
m_last_err = SCALERBYLEO_ERR_SIZE_MISMATCH;
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
// En caso nos obligen a reoncutr y no coinciden entonces
|
|
if(m_reconstruir && fs != total_cols)
|
|
{
|
|
out = X_scaled; // copia optimizada (ya probado, conpensa el overwrite)
|
|
// modificamos inplace
|
|
for(ulong c = 0; c < fs; c++)
|
|
for(ulong r = 0; r < rows; r++)
|
|
out[r][m_i_start + c] = TFlt((double(X_scaled[r][m_i_start + c]) * m_iqrs[c]) + m_medians[c]);
|
|
}
|
|
else
|
|
{
|
|
// De lo contrario exacto asi que inplace
|
|
out.Resize(rows, fs);
|
|
for(ulong c = 0; c < fs; c++)
|
|
for(ulong r = 0; r < rows; r++)
|
|
out[r][c] = TFlt((double(X_scaled[r][m_i_start + c]) * m_iqrs[c]) + m_medians[c]);
|
|
}
|
|
|
|
//---
|
|
return true;
|
|
}
|
|
}
|
|
#endif // SCALERBYLEO_SRC_SCALER_RSCALER_RSCALAR_MQH
|
|
//+------------------------------------------------------------------+
|