/// <inheritdoc/> public void Recompute(bool collectStatistics) { //Spike leak handling if (OutputData._spikingSignal > 0) { //Spike during previous cycle, so reset the counter OutputData._afterFirstSpike = true; OutputData._spikeLeak = 0; } ++OutputData._spikeLeak; double normalizedActivation; if (_activationFn.TypeOfActivation == ActivationType.Spiking) { //Spiking activation AFSpikingBase af = (AFSpikingBase)_activationFn; OutputData._spikingSignal = af.Compute(_tStimuli); //OutputData._analogSignal = OutputData._spikingSignal; _activationState = af.InternalState; normalizedActivation = OutputRange.Rescale(af.InternalState, af.InternalStateRange).Bound(OutputRange.Min, OutputRange.Max); OutputData._analogSignal = normalizedActivation; } else { //Analog activation _activationState = (_analogRetainmentStrength * _activationState) + (1d - _analogRetainmentStrength) * _activationFn.Compute(_tStimuli); normalizedActivation = OutputRange.Rescale(_activationState, _activationFn.OutputRange).Bound(OutputRange.Min, OutputRange.Max); double activationDifference = _histActivationsQueue == null ? ((normalizedActivation - OutputData._analogSignal)) : (_histActivationsQueue.Full ? (normalizedActivation - _histActivationsQueue.Dequeue()) : (normalizedActivation - 0.5d)); //Firing event decision bool firingEvent = activationDifference > _analogFiringThreshold; //Enqueue last normalized activation _histActivationsQueue?.Enqueue(normalizedActivation); //New output data OutputData._analogSignal = normalizedActivation; OutputData._spikingSignal = firingEvent ? 1d : 0d; } //Update predictors _predictorsProvider?.Update(_activationState, normalizedActivation, (OutputData._spikingSignal > 0)); //Update statistics if (collectStatistics) { Statistics.Update(_iStimuli, _rStimuli, _tStimuli, _activationState, OutputData._analogSignal, OutputData._spikingSignal); } return; }