//+------------------------------------------------------------------+ //| NeuronPrimitives.mqh | //| AnimateDread | //| https://www.mql5.com | //+------------------------------------------------------------------+ //| CConnection/CArrayCon - the per-synapse weight (+ Adam moment) | //| storage and its owning array, used by the CPU-only CNeuronBase/ | //| CNeuron neuron family (AI\NeuronCPU.mqh) as their fallback last- | //| resort weight representation (no DLL import, no OpenCL/DirectML).| //| Extracted verbatim out of AI\Network.mqh's own god-file (SOLID | //| cleanup) - no logic changes, this is the exact original code. | //+------------------------------------------------------------------+ #include class CConnection : public CObject { public: double weight; double deltaWeight; double mt; double vt; CConnection(double w) { weight = w; deltaWeight = 0; mt = 0; vt = 0; } ~CConnection() {}; //--- methods for working with files virtual bool Save(int const file_handle); virtual bool Load(int const file_handle); virtual int Type(void) const { return defConnect; } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CConnection::Save(int file_handle) { if(file_handle == INVALID_HANDLE) return false; //--- if(FileWriteDouble(file_handle, weight) <= 0) return false; if(FileWriteDouble(file_handle, deltaWeight) <= 0) return false; if(FileWriteDouble(file_handle, mt) <= 0) return false; if(FileWriteDouble(file_handle, vt) <= 0) return false; //--- return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CConnection::Load(int file_handle) { if(file_handle == INVALID_HANDLE) return false; //--- weight = FileReadDouble(file_handle); deltaWeight = FileReadDouble(file_handle); mt = FileReadDouble(file_handle); vt = FileReadDouble(file_handle); //--- return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CArrayCon : public CArrayObj { public: CArrayCon(void) {}; ~CArrayCon(void) {}; //--- Fan-in-scaled element factory. Deliberately NOT named CreateElement: see the override below. bool CreateElementScaled(int const index, double weighScale); //--- MUST keep CArrayObj::CreateElement's EXACT signature so it really overrides the base virtual - //--- CArrayObj::Load() dispatches through it when reading a saved CNeuronBase's connection array. In //--- MQL5 an added parameter (even a defaulted one) turns this into a separate hiding method and //--- leaves the base's `return(false)` stub in the vtable, which silently breaks every load. Same trap //--- as CLayer::CreateElement - see the long note there. virtual bool CreateElement(const int index) { return CreateElementScaled(index, -1.0); } virtual void IncreaseTotal() { m_data_total++; } virtual int Type(void) const { return defArrayConnects; } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CArrayCon::CreateElementScaled(int index, double weighScale) { if(index < 0 || index >= m_data_max) return false; //--- // Fan-in-scaled to match the CNeuronBaseOCL/CNeuronConvOCL/CNeuronLSTMOCL weight-init sites - // callers now compute their own He/LeCun-uniform weighScale (same rationale as those) and pass it // down through CNeuronBase::Init(), since this per-connection constructor has no visibility into // its owning neuron's fan-in on its own. weighScale < 0 (no caller opinion) keeps the old flat // draw as a safe default. double weigh; if(weighScale > 0.0) weigh = ((MathRand() + 1) / 32768.0 - 0.5) * 2.0 * weighScale; else weigh = (MathRand() + 1) / 32768.0 - 0.5; if(weigh == 0) weigh = 0.001; m_data[index] = new CConnection(weigh); if(CheckPointer(m_data[index]) == POINTER_INVALID) return false; //--- return (true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+