NeuroNetworksBook/Include/realization/bufferdouble.mqh

355 lines
25 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 16:12:34 +02:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| BufferDouble.mqh |
//| Copyright 2021, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| >4:;NG05< 181;8>B5:8 |
//+------------------------------------------------------------------+
#include <Arrays\Array.mqh>
#ifndef Defines
#include "defines.mqh"
#endif
#include "opencl.mqh"
//+------------------------------------------------------------------+
//| Class CBufferDouble |
//| 07=0G5=85: ;0AA 48=0<8G5A:>3> 1CD5@0 40==KE |
//+------------------------------------------------------------------+
class CBufferDouble : public CObject
{
protected:
CMyOpenCL *m_cOpenCL; // 1J5:B :>=B5:AB0 OpenCL
int m_myIndex; // =45:A 1CD5@0 40==KE 2 :>=B5:AB5
public:
CBufferDouble(void);
~CBufferDouble(void);
//---
MATRIX m_mMatrix;
//--- 5B>4 8=8F80;870F88 1CD5@0 =0G0;L=K<8 7=0G5=8O<8
virtual bool BufferInit(const ulong rows, const ulong columns, const double value = 0);
//--- !;>65=85 25:B>@>2
virtual bool SumArray(const CBufferDouble *src);
//--- !>740=885 =>2>3> 1CD5@0 2 :>=B5:AB5 OpenCL
virtual bool BufferCreate(CMyOpenCL *opencl);
//--- #40;5=85 1CD5@0 2 :>=B5:AB5 OpenCL
virtual bool BufferFree(void);
//--- 'B5=85 40==KE 1CD5@0 87 :>=B5:AB0 OpenCL
virtual bool BufferRead(void);
//--- 0?8AL 40==KE 1CD5@0 2 :>=B5:AB OpenCL
virtual bool BufferWrite(void);
//--- >;CG5=85 8=45:A0 1CD5@0
virtual int GetIndex(void);
//--- 7<5=5=85 8=45:A0 1CD5@0
virtual bool SetIndex(int index)
{
if(!m_cOpenCL.BufferFree(m_myIndex))
return false;
m_myIndex = index;
return true;
}
//--- >?8@>20=85 40==KE 1CD5@0 2 <0AA82
virtual int GetData(double &values[], bool load = true);
virtual int GetData(MATRIX &values, bool load = true);
virtual int GetData(CBufferDouble *values, bool load = true);
//--- 0AAGQB A@54=53> 7=0G5=8O 1CD5@0 40==KE
virtual double MathMean(void);
//--- 0AHB018@>20=85 7=0G5=89 1CD5@0
virtual int Scaling(double value);
//--- <5B>4K @01>BK A D09;0<8
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- 45=B8D8:0B>@ :;0AA0
virtual int Type(void) const { return defBufferDouble; }
ulong Rows(void) const { return m_mMatrix.Rows(); }
ulong Cols(void) const { return m_mMatrix.Cols(); }
uint Total(void) const { return (uint)(m_mMatrix.Rows() * m_mMatrix.Cols()); }
double At(uint index) const { return m_mMatrix.Flat(index); }
double operator[](ulong index) const { return m_mMatrix.Flat(index); }
bool Update(uint index, double value)
{
if(index >= Total())
return false;
m_mMatrix.Flat(index, value);
return true;
}
bool Update(uint row, uint col, double value)
{
if(row >= Rows() || col >= Cols())
return false;
m_mMatrix[row, col] = value;
return true;
}
};
//+------------------------------------------------------------------+
//| >=AB@C:B>@ :;0AA0 |
//+------------------------------------------------------------------+
CBufferDouble::CBufferDouble(void) : m_myIndex(-1)
{
m_cOpenCL = NULL;
}
//+------------------------------------------------------------------+
//| 5AB@C:B>@ :;0AA0 |
//+------------------------------------------------------------------+
CBufferDouble::~CBufferDouble(void)
{
if(m_cOpenCL && m_myIndex >= 0)
{
if(m_cOpenCL.BufferFree(m_myIndex))
{
m_myIndex = -1;
m_cOpenCL = NULL;
}
}
}
//+------------------------------------------------------------------+
//| !>740=885 =>2>3> 1CD5@0 2 :>=B5:AB5 OpenCL |
//+------------------------------------------------------------------+
bool CBufferDouble::BufferCreate(CMyOpenCL *opencl)
{
//--- ;>: ?@>25@:8 8AE>4=KE 40==KE
if(!opencl)
{
BufferFree();
return false;
}
//--- A;8 ?>;CG5==K9 C:070B5;L A>2?0405B A @0=55 A>E@0=Q==K< ?@>AB> :>?8@C5< A>45@68<>5 1CD5@0 2 ?0<OBL :>=B5:AB0
if(opencl == m_cOpenCL && m_myIndex >= 0)
{
if(!BufferWrite())
return false;
return true;
}
//--- @>25@O5< =0;8G85 @0=55 A>E@0=Q==>3> C:070B5;O =0 :>=B5:AB OpenCL
//--- @8 =0;8G88, C40;O5< 1CD5@ 87 =58A?>;L7C5<>3> :>=B5:AB0
if(m_cOpenCL && m_myIndex >= 0)
{
if(m_cOpenCL.BufferFree(m_myIndex))
{
m_myIndex = -1;
m_cOpenCL = NULL;
}
else
return false;
}
//---
//--- !>740Q< =>2K9 1CD5@ 2 C:07==>< :>=B5:AB5 OpenCL
if((m_myIndex = opencl.AddBufferFromArray(m_mMatrix, 0, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR)) < 0)
return false;
m_cOpenCL = opencl;
//---
return true;
}
//+------------------------------------------------------------------+
//| 5B>4 C40;5=8O 1CD5@0 87 ?0<OB8 :>=B5:AB0 OpenCL |
//+------------------------------------------------------------------+
bool CBufferDouble::BufferFree(void)
{
//--- @>25@O5< =0;8G85 @0=55 A>E@0=Q==>3> C:070B5;O =0 :>=B5:AB OpenCL
//--- @8 =0;8G88, C40;O5< 1CD5@ 87 =58A?>;L7C5<>3> :>=B5:AB0
if(m_cOpenCL && m_myIndex >= 0)
if(m_cOpenCL.BufferFree(m_myIndex))
{
m_myIndex = -1;
m_cOpenCL = NULL;
return true;
}
if(m_myIndex >= 0)
m_myIndex = -1;
//---
return false;
}
//+------------------------------------------------------------------+
//| 5B>4 GB5=8O 40==KE 87 1CD5@0 :>=B5:AB0 OpenCL |
//+------------------------------------------------------------------+
bool CBufferDouble::BufferRead(void)
{
if(!m_cOpenCL || m_myIndex < 0)
return false;
//---
if(!m_cOpenCL.BufferRead(m_myIndex, m_mMatrix, 0))
return false;
//---
return true;
}
//+------------------------------------------------------------------+
//| 5B>4 70?8A8 40==KE 2 1CD5@0 :>=B5:AB0 OpenCL |
//+------------------------------------------------------------------+
bool CBufferDouble::BufferWrite(void)
{
if(!m_cOpenCL || m_myIndex < 0)
return false;
//---
return m_cOpenCL.BufferWrite(m_myIndex, m_mMatrix, 0);
}
//+------------------------------------------------------------------+
//| 5B>4 8=8F80;870F88 1CD5@0 =0G0;L=K<8 7=0G5=8O<8 |
//+------------------------------------------------------------------+
bool CBufferDouble::BufferInit(ulong rows, ulong columns, double value)
{
if(rows <= 0 || columns <= 0)
return false;
//---
if(!m_mMatrix.Init(rows, columns))
return false;
m_mMatrix.Fill(value);
if(m_cOpenCL)
return BufferCreate(m_cOpenCL);
//---
return true;
}
//+------------------------------------------------------------------+
//| 5B>4 ?>;CG5=8O 7=0G5=89 1CD5@0 |
//+------------------------------------------------------------------+
int CBufferDouble::GetData(double &values[], bool load = true)
{
if(load && !BufferRead())
return -1;
if(ArraySize(values) != Total() &&
ArrayResize(values, Total()) <= 0)
return false;
//---
for(uint i = 0; i < Total(); i++)
values[i] = m_mMatrix.Flat(i);
return (int)Total();
}
//+------------------------------------------------------------------+
//| 5B>4 ?>;CG5=8O 7=0G5=89 1CD5@0 |
//+------------------------------------------------------------------+
int CBufferDouble::GetData(MATRIX &values, bool load = true)
{
if(load && !BufferRead())
return -1;
//---
values = m_mMatrix;
return (int)Total();
}
//+------------------------------------------------------------------+
//| 5B>4 ?>;CG5=8O 7=0G5=89 1CD5@0 |
//+------------------------------------------------------------------+
int CBufferDouble::GetData(CBufferDouble *values, bool load = true)
{
if(!values)
return -1;
if(load && !BufferRead())
return -1;
values.m_mMatrix.Copy(m_mMatrix);
return (int)values.Total();
}
//+------------------------------------------------------------------+
//| 5B>4 AC<<8@>20=8O M;5<5=B>2 42CE 1CD5@>2 40==KE |
//+------------------------------------------------------------------+
bool CBufferDouble::SumArray(const CBufferDouble *src)
{
ulong num;
//--- @>25@:0 <0AA820 8AE>4=KE 60==KE
if(!src)
return(false);
//--- 575@28@>20=85 <5AB0 2 48=0<8G5A:>< <0AA825 4;O 70?8A8 @57C;LB0B>2
num = src.m_mMatrix.Rows();
if(m_mMatrix.Rows() < num)
{
if(!m_mMatrix.Resize(num, m_mMatrix.Cols(), 0))
return(false);
}
num = src.m_mMatrix.Cols();
if(m_mMatrix.Cols() < num)
if(!m_mMatrix.Resize(m_mMatrix.Rows(), num, 0))
return(false);
//--- C;>65=8O <0B@8F
m_mMatrix += src.m_mMatrix;
//---
return(true);
}
//+------------------------------------------------------------------+
//| 5B>4 2KG8A;5=8O A@54=53> 7=0G5=88O <0AA820 |
//+------------------------------------------------------------------+
double CBufferDouble::MathMean(void)
{
return m_mMatrix.Mean();
}
//+------------------------------------------------------------------+
//| >;CG5=8 8=45:A0 1CD5@0 2 :>=B5:AB5 OpenCL |
//+------------------------------------------------------------------+
int CBufferDouble::GetIndex(void)
{
if(!m_cOpenCL || m_myIndex < 0)
{
m_myIndex = -1;
return m_myIndex;
}
//---
if(!m_cOpenCL.CheckBuffer(m_myIndex))
m_myIndex = BufferCreate(m_cOpenCL);
//---
return m_myIndex;
}
//+------------------------------------------------------------------+
//| 5B>4 <0AHB018@>20=8O 40==KE (C<=>65=85 =0 :>=AB0=BC) |
//+------------------------------------------------------------------+
int CBufferDouble::Scaling(double value)
{
m_mMatrix *= value;
if(m_cOpenCL && !BufferWrite())
return false;
//---
return (int)Total();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CBufferDouble::Save(const int file_handle)
{
if(file_handle == INVALID_HANDLE)
return false;
if(m_myIndex >= 0)
if(!BufferRead())
return false;
//---
if(FileWriteInteger(file_handle, Type()) < INT_VALUE)
return false;
if(FileWriteLong(file_handle, Rows()) < sizeof(long))
return false;
if(FileWriteLong(file_handle, Cols()) < sizeof(long))
return false;
//---
for(ulong r = 0; r < Rows(); r++)
for(ulong c = 0; c < Cols(); c++)
if(FileWriteDouble(file_handle, m_mMatrix[r, c]) < sizeof(double))
return false;
//---
return true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CBufferDouble::Load(const int file_handle)
{
if(file_handle == INVALID_HANDLE)
return false;
if(FileReadInteger(file_handle) != Type())
return false;
//---
ulong rows = FileReadLong(file_handle);
ulong cols = FileReadLong(file_handle);
if(!m_mMatrix.Init(rows, cols))
return false;
for(ulong r = 0; r < rows; r++)
for(ulong c = 0; c < cols; c++)
m_mMatrix[r, c] = FileReadDouble(file_handle);
//---
if(m_myIndex >= 0)
{
if(!BufferCreate(m_cOpenCL))
return false;
}
//---
return true;
}
//+------------------------------------------------------------------+