//+------------------------------------------------------------------+ //| MatrixProcessor.mqh | //| Copyright 2022, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ template class Transformer { protected: virtual void act(T &m) = 0; public: static void transform(T &m, Transformer &actor) { actor.act(m); } }; template class MatrixTransformer: public Transformer> { public: virtual void process(matrix &m) { m.Init(m.Rows(), m.Cols(), transform, this); } }; template class VectorTransformer: public Transformer> { public: virtual void process(vector &v) { v.Init(v.Size(), transform, this); } }; template class MatrixNormalizer: public MatrixTransformer { public: const int d; MatrixNormalizer(const int _d = -1): d(_d == -1 ? _Digits : _d) { } void act(matrix &m) override { for(ulong i = 0; i < m.Rows() * m.Cols(); ++i) { m.Flat(i, (T)NormalizeDouble(m.Flat(i), d)); } } }; template void Normalize(matrix &m, const int d = -1) { MatrixNormalizer normalizer(d); normalizer.process(m); } template class VectorNormalizer: public VectorTransformer { public: const int d; VectorNormalizer(const int _d = -1): d(_d == -1 ? _Digits : _d) { } void act(vector &v) override { for(ulong i = 0; i < v.Size(); ++i) { v[i] = (T)NormalizeDouble(v[i], d); } } }; template void Normalize(vector &v, const int d = -1) { VectorNormalizer normalizer(d); normalizer.process(v); } template class VectorExporter: public VectorTransformer { public: S array[]; VectorExporter(S &source[]) { ArraySwap(source, array); } void act(vector &v) override { ArrayResize(array, (int)v.Size()); for(ulong i = 0; i < v.Size(); ++i) { array[i] = (S)v[i]; } } }; // If a vector is not needed anymore, better use vector.Swap(array); // but Swap requires the same types of vector and array, // whereas Export can do convertion: // for example GraphPlot requires doubles and can't use floats template void Export(vector &v, S &target[]) { VectorExporter exporter(target); exporter.process(v); ArraySwap(target, exporter.array); } //+------------------------------------------------------------------+ /* Usage: matrix rates; rates.CopyRates(_Symbol, _Period, COPY_RATES_OPEN | COPY_RATES_CLOSE, 0, 100); Normalize(rates); */ //+------------------------------------------------------------------+