/// <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; }
/// <summary> /// Computes neuron's new output signal and updates statistics /// </summary> /// <param name="collectStatistics">Specifies whether to update internal statistics</param> 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 (_activation.TypeOfActivation == ActivationType.Spiking) { //Spiking activation OutputData._spikingSignal = _activation.Compute(_tStimuli); //OutputData._analogSignal = OutputData._spikingSignal; _activationState = _activation.InternalState; normalizedActivation = _outputRange.Rescale(_activation.InternalState, _activation.InternalStateRange).Bound(_outputRange.Min, _outputRange.Max); OutputData._analogSignal = normalizedActivation; } else { //Analog activation double newState = _activation.Compute(_tStimuli); _activationState = (_analogRetainmentStrength * _activationState) + (1d - _analogRetainmentStrength) * newState; normalizedActivation = _outputRange.Rescale(_activationState, _activation.OutputRange).Bound(_outputRange.Min, _outputRange.Max); bool firingEvent = _histActivationsQueue == null ? ((normalizedActivation - OutputData._analogSignal) > _analogFiringThreshold) : (_histActivationsQueue.Full ? (normalizedActivation - _histActivationsQueue.Dequeue()) > _analogFiringThreshold : (normalizedActivation - 0.5d) > _analogFiringThreshold); _histActivationsQueue?.Enqueue(normalizedActivation); //New output data OutputData._analogSignal = normalizedActivation; OutputData._spikingSignal = firingEvent ? 1d : 0d; } //Update predictors _predictors?.Update(_activationState, normalizedActivation, (OutputData._spikingSignal > 0)); //Update statistics if (collectStatistics) { Statistics.Update(_iStimuli, _rStimuli, _tStimuli, _activationState, OutputData._analogSignal, OutputData._spikingSignal); } return; }