//Constructor /// <summary> /// Creates initialized instance /// </summary> /// <param name="sourceNeuron">Source neuron</param> /// <param name="targetNeuron">Target neuron</param> /// <param name="weight">Synapse initial weight</param> public BaseSynapse(INeuron sourceNeuron, INeuron targetNeuron, double weight ) { //Neurons to be connected SourceNeuron = sourceNeuron; TargetNeuron = targetNeuron; //Euclidean distance Distance = EuclideanDistance.Compute(SourceNeuron.Placement.ReservoirCoordinates, TargetNeuron.Placement.ReservoirCoordinates); //Weight sign rules if (SourceNeuron.Role == NeuronCommon.NeuronRole.Input) { if (TargetNeuron.TypeOfActivation == ActivationType.Analog) { //No change of the weight sign Weight = weight; } else { //Target is spiking neuron //Weight must be always positive Weight = Math.Abs(weight); } } else { //Weight sign is dependent on source neuron role Weight = Math.Abs(weight) * (SourceNeuron.Role == NeuronCommon.NeuronRole.Excitatory ? 1d : -1d); } //Efficacy statistics EfficacyStat = new BasicStat(false); return; }
//Constructor /// <summary> /// Creates initialized instance /// </summary> /// <param name="sourceNeuron">Source neuron</param> /// <param name="targetNeuron">Target neuron</param> /// <param name="weight">Synapse weight</param> public BaseSynapse(INeuron sourceNeuron, INeuron targetNeuron, double weight ) { //Neurons to be connected SourceNeuron = sourceNeuron; TargetNeuron = targetNeuron; //Euclidean distance Distance = EuclideanDistance.Compute(SourceNeuron.Placement.ReservoirCoordinates, TargetNeuron.Placement.ReservoirCoordinates); //Weight sign and signal range conversion rules if (SourceNeuron.Role == CommonEnums.NeuronRole.Input) { //Source is input neuron if (TargetNeuron.OutputType == CommonEnums.NeuronSignalType.Spike) { //Target is spiking //Ensure positive weight Weight = Math.Abs(weight); //Convert signal to <0,1> _add = -SourceNeuron.OutputRange.Min; _div = SourceNeuron.OutputRange.Span; } else { //Target is also analog //Weight is unchanged Weight = weight; //No signal conversion _add = 0; _div = 1; } } else { //Source is reservoir neuron if (SourceNeuron.OutputType == CommonEnums.NeuronSignalType.Spike) { //Source reservoir neuron is spiking if (TargetNeuron.OutputType == CommonEnums.NeuronSignalType.Spike) { //Target is also spiking //Weight dependent on source neuron role Weight = Math.Abs(weight) * ((SourceNeuron.Role == CommonEnums.NeuronRole.Excitatory) ? 1 : -1); //No signal conversion _add = 0; _div = 1; } else { //Target is analog //Weight is unchanged Weight = weight; //Convert signal to target neuron range _add = (TargetNeuron.OutputRange.Min - SourceNeuron.OutputRange.Min); _div = (SourceNeuron.OutputRange.Span / TargetNeuron.OutputRange.Span); } } else { //Source reservoir neuron is analog if (TargetNeuron.OutputType == CommonEnums.NeuronSignalType.Spike) { //Target is spiking //Weight dependent on source neuron role Weight = Math.Abs(weight) * ((SourceNeuron.Role == CommonEnums.NeuronRole.Excitatory) ? 1 : -1); //Convert signal to <0,1> _add = -SourceNeuron.OutputRange.Min; _div = SourceNeuron.OutputRange.Span; } else { //Target is also analog //Weight is unchanged Weight = weight; //No signal conversion _add = 0; _div = 1; } } } //Set Delay to 0 as default. It can be changed later by SetDelay method. Delay = 0; //Efficacy statistics EfficacyStat = new BasicStat(false); return; }
//Constructor /// <summary> /// Creates initialized instance /// </summary> /// <param name="sourceNeuron">Source neuron</param> /// <param name="targetNeuron">Target neuron</param> /// <param name="role">Synapse role</param> /// <param name="synapseCfg">Synapse general configuration</param> /// <param name="rand">Random object</param> public Synapse(INeuron sourceNeuron, INeuron targetNeuron, SynRole role, SynapseSettings synapseCfg, Random rand ) { //Neurons to be connected SourceNeuron = sourceNeuron; TargetNeuron = targetNeuron; //Synapse role Role = role; //Euclidean distance Distance = EuclideanDistance.Compute(SourceNeuron.Location.ReservoirCoordinates, TargetNeuron.Location.ReservoirCoordinates); //The rest _efficacyComputer = null; if (TargetNeuron.TypeOfActivation == ActivationType.Spiking) { //Spiking target if (Role == SynRole.Input) { DelayMethod = synapseCfg.SpikingTargetCfg.InputSynCfg.DelayMethod; _maxDelay = synapseCfg.SpikingTargetCfg.InputSynCfg.MaxDelay; if (SourceNeuron.TypeOfActivation == ActivationType.Analog) { //Analog source Weight = rand.NextDouble(synapseCfg.SpikingTargetCfg.InputSynCfg.AnalogSourceCfg.WeightCfg); } else { //Spiking source Weight = rand.NextDouble(synapseCfg.SpikingTargetCfg.InputSynCfg.SpikingSourceCfg.WeightCfg); _efficacyComputer = PlasticityCommon.GetEfficacyComputer(SourceNeuron, synapseCfg.SpikingTargetCfg.InputSynCfg.SpikingSourceCfg.PlasticityCfg.DynamicsCfg ); } } else if (Role == SynRole.Excitatory) { DelayMethod = synapseCfg.SpikingTargetCfg.ExcitatorySynCfg.DelayMethod; _maxDelay = synapseCfg.SpikingTargetCfg.ExcitatorySynCfg.MaxDelay; if (SourceNeuron.TypeOfActivation == ActivationType.Analog) { //Analog source Weight = rand.NextDouble(synapseCfg.SpikingTargetCfg.ExcitatorySynCfg.AnalogSourceCfg.WeightCfg); } else { //Spiking source Weight = rand.NextDouble(synapseCfg.SpikingTargetCfg.ExcitatorySynCfg.SpikingSourceCfg.WeightCfg); _efficacyComputer = PlasticityCommon.GetEfficacyComputer(SourceNeuron, synapseCfg.SpikingTargetCfg.ExcitatorySynCfg.SpikingSourceCfg.PlasticityCfg.DynamicsCfg ); } } else if (Role == SynRole.Inhibitory) { DelayMethod = synapseCfg.SpikingTargetCfg.InhibitorySynCfg.DelayMethod; _maxDelay = synapseCfg.SpikingTargetCfg.InhibitorySynCfg.MaxDelay; if (SourceNeuron.TypeOfActivation == ActivationType.Analog) { //Analog source Weight = -rand.NextDouble(synapseCfg.SpikingTargetCfg.InhibitorySynCfg.AnalogSourceCfg.WeightCfg); } else { //Spiking source Weight = -rand.NextDouble(synapseCfg.SpikingTargetCfg.InhibitorySynCfg.SpikingSourceCfg.WeightCfg); _efficacyComputer = PlasticityCommon.GetEfficacyComputer(SourceNeuron, synapseCfg.SpikingTargetCfg.InhibitorySynCfg.SpikingSourceCfg.PlasticityCfg.DynamicsCfg ); } } else { throw new ArgumentException($"Invalid synapse role {role}.", "role"); } } else { //Analog target if (Role == SynRole.Input) { DelayMethod = synapseCfg.AnalogTargetCfg.InputSynCfg.DelayMethod; _maxDelay = synapseCfg.AnalogTargetCfg.InputSynCfg.MaxDelay; if (SourceNeuron.TypeOfActivation == ActivationType.Analog) { //Analog source Weight = rand.NextDouble(synapseCfg.AnalogTargetCfg.InputSynCfg.AnalogSourceCfg.WeightCfg); } else { //Spiking source Weight = rand.NextSign() * rand.NextDouble(synapseCfg.AnalogTargetCfg.InputSynCfg.SpikingSourceCfg.WeightCfg); _efficacyComputer = PlasticityCommon.GetEfficacyComputer(SourceNeuron, synapseCfg.AnalogTargetCfg.InputSynCfg.SpikingSourceCfg.PlasticityCfg.DynamicsCfg ); } } else if (Role == SynRole.Indifferent) { DelayMethod = synapseCfg.AnalogTargetCfg.IndifferentSynCfg.DelayMethod; _maxDelay = synapseCfg.AnalogTargetCfg.IndifferentSynCfg.MaxDelay; if (SourceNeuron.TypeOfActivation == ActivationType.Analog) { //Analog source Weight = rand.NextSign() * rand.NextDouble(synapseCfg.AnalogTargetCfg.IndifferentSynCfg.AnalogSourceCfg.WeightCfg); } else { //Spiking source Weight = rand.NextSign() * rand.NextDouble(synapseCfg.AnalogTargetCfg.IndifferentSynCfg.SpikingSourceCfg.WeightCfg); _efficacyComputer = PlasticityCommon.GetEfficacyComputer(SourceNeuron, synapseCfg.AnalogTargetCfg.IndifferentSynCfg.SpikingSourceCfg.PlasticityCfg.DynamicsCfg ); } } else { throw new ArgumentException($"Invalid synapse role {role}.", "role"); } } //Source neuron - output data and signal index _sourceNeuronOutputData = SourceNeuron.OutputData; _analogSourceSignal = TargetNeuron.TypeOfActivation == ActivationType.Analog; //Efficacy statistics EfficacyStat = new BasicStat(false); Reset(true); return; }