001        package com.croftsoft.core.ai.neuro.imp;
002    
003        import com.croftsoft.core.ai.neuro.Channel;
004        import com.croftsoft.core.ai.neuro.Neuron;
005        import com.croftsoft.core.lang.NullException;
006        import com.croftsoft.core.sim.DeltaClock;
007        import com.croftsoft.core.sim.Sim;
008        import com.croftsoft.core.util.seq.Seq;
009    
010        /***********************************************************************
011        * Integrate and tire neuron.
012        * 
013        * Similar to integrate and fire neuron but hyperpolarizes after firing.
014        * 
015        * @version
016        *   $Id: TireNeuron.java,v 1.16 2008/08/09 02:16:34 croft Exp $
017        * @since
018        *   2008-07-06
019        * @author
020        *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
021        ***********************************************************************/
022    
023        public final class  TireNeuron
024          implements Neuron, Sim
025        ////////////////////////////////////////////////////////////////////////
026        ////////////////////////////////////////////////////////////////////////
027        {
028          
029        private final Seq<Channel>  channelSeq;
030        
031        private final DeltaClock    deltaClock;
032        
033        //
034          
035        private boolean  spiking;
036          
037        private double
038          deltaMembraneVoltage,
039          depolarized,
040          leakConductance,
041          leakReversalPotential,
042          hyperpolarized,
043          membraneCapacitance,
044          membraneVoltage,
045          threshold;
046        
047        ////////////////////////////////////////////////////////////////////////
048        ////////////////////////////////////////////////////////////////////////
049        
050        public  TireNeuron (
051          final Seq<Channel>  channelSeq,
052          final DeltaClock    deltaClock,
053          final double        depolarized,
054          final double        hyperpolarized,
055          final double        leakConductance,
056          final double        leakReversalPotential,
057          final double        membraneCapacitance,
058          final double        membraneVoltage,
059          final boolean       spiking,
060          final double        threshold )
061        ////////////////////////////////////////////////////////////////////////
062        {
063          NullException.check (
064            this.deltaClock = deltaClock,
065            this.channelSeq = channelSeq );
066          
067          this.depolarized           = depolarized;
068          
069          this.hyperpolarized        = hyperpolarized;
070          
071          this.leakConductance       = leakConductance;
072          
073          this.leakReversalPotential = leakReversalPotential;
074         
075          this.membraneCapacitance   = membraneCapacitance;
076          
077          this.membraneVoltage       = membraneVoltage;
078          
079          this.spiking               = spiking;
080          
081          this.threshold             = threshold;
082        }
083        
084        public  TireNeuron (
085          final Seq<Channel>  channelSeq,
086          final DeltaClock    deltaClock )
087        ////////////////////////////////////////////////////////////////////////
088        {
089          this (
090            channelSeq,
091            deltaClock,
092             1.0,   // depolarized
093            -1.0,   // hyperpolarized
094             0.1,   // leakConductance
095             0.0,   // leakReversalPotential
096             1.0,   // membraneCapacitance
097             0.0,   // membraneVoltage
098            false,  // spiking
099             0.5 ); // threshold
100        }
101        
102        ////////////////////////////////////////////////////////////////////////
103        // accessor methods
104        ////////////////////////////////////////////////////////////////////////
105        
106        public double  getDepolarized ( )
107        ////////////////////////////////////////////////////////////////////////
108        {
109          return depolarized;
110        }
111        
112        public double  getHyperpolarized ( )
113        ////////////////////////////////////////////////////////////////////////
114        {
115          return hyperpolarized;
116        }
117        
118        public double  getLeakConductance ( )
119        ////////////////////////////////////////////////////////////////////////
120        {
121          return leakConductance;
122        }
123        
124        public double  getLeakReversalPotential ( )
125        ////////////////////////////////////////////////////////////////////////
126        {
127          return leakReversalPotential;
128        }
129        
130        public double  getMembraneCapacitance ( )
131        ////////////////////////////////////////////////////////////////////////
132        {
133          return membraneCapacitance;
134        }
135        
136        public double  getMembraneVoltage ( )
137        ////////////////////////////////////////////////////////////////////////
138        {
139          return membraneVoltage;
140        }
141          
142        public boolean  isSpiking ( )
143        ////////////////////////////////////////////////////////////////////////
144        {
145          return spiking;
146        }
147        
148        public double  getThreshold ( )
149        ////////////////////////////////////////////////////////////////////////
150        {
151          return threshold;
152        }
153        
154        ////////////////////////////////////////////////////////////////////////
155        // mutator methods
156        ////////////////////////////////////////////////////////////////////////
157        
158        public void  setDepolarized ( final double  depolarized )
159        ////////////////////////////////////////////////////////////////////////
160        {
161          this.depolarized = depolarized;
162        }
163        
164        public void  setHyperpolarized ( final double  hyperpolarized )
165        ////////////////////////////////////////////////////////////////////////
166        {
167          this.hyperpolarized = hyperpolarized;
168        }
169        
170        public void  setLeakConductance ( final double  leakConductance )
171        ////////////////////////////////////////////////////////////////////////
172        {
173          this.leakConductance = leakConductance;
174        }
175        
176        public void  setLeakReversalPotential (
177          final double  leakReversalPotential )
178        ////////////////////////////////////////////////////////////////////////
179        {
180          this.leakReversalPotential = leakReversalPotential;
181        }
182        
183        public void  setMembraneCapacitance (
184          final double  membraneCapacitance )
185        ////////////////////////////////////////////////////////////////////////
186        {
187          this.membraneCapacitance = membraneCapacitance;
188        }
189        
190        public void  setMembraneVoltage ( final double  membraneVoltage )
191        ////////////////////////////////////////////////////////////////////////
192        {
193          this.membraneVoltage = membraneVoltage;
194        }
195        
196        public void  setSpiking ( final boolean  spiking )
197        ////////////////////////////////////////////////////////////////////////
198        {
199          this.spiking = spiking;
200        }
201        
202        public void  setThreshold ( final double  threshold )
203        ////////////////////////////////////////////////////////////////////////
204        {
205          this.threshold = threshold;
206        }
207        
208        ////////////////////////////////////////////////////////////////////////
209        // lifecycle methods
210        ////////////////////////////////////////////////////////////////////////
211        
212        public void  access ( )
213        ////////////////////////////////////////////////////////////////////////
214        {
215          final double  deltaTime = deltaClock.getDeltaTime ( );
216            
217          final int  size = channelSeq.size ( );
218            
219          double  capacitiveCurrent = 0;
220            
221          for ( int  i = 0; i < size; i++ )
222          {
223            final Channel  channel = channelSeq.get ( i );
224              
225            if ( channel.isOpen ( ) )
226            {
227              final double  channelCurrent = channel.getConductance ( )
228                * ( membraneVoltage - channel.getReversalPotential ( ) );
229              
230              capacitiveCurrent += channelCurrent;
231            }
232          }
233            
234          final double  leakCurrent
235            = leakConductance * ( membraneVoltage - leakReversalPotential );
236          
237          capacitiveCurrent += leakCurrent;
238            
239          final double  deltaCharge = deltaTime * -capacitiveCurrent;
240              
241          deltaMembraneVoltage = deltaCharge / membraneCapacitance;
242        }
243        
244        public void  mutate ( )
245        ////////////////////////////////////////////////////////////////////////
246        {
247          if ( spiking )
248          {
249            spiking = false;
250            
251            membraneVoltage = hyperpolarized;
252          }
253          else
254          {
255            membraneVoltage += deltaMembraneVoltage;
256            
257            if ( membraneVoltage >= threshold )
258            {
259              spiking = true;
260            
261              membraneVoltage = depolarized;
262            }
263          }
264        }
265          
266        ////////////////////////////////////////////////////////////////////////
267        ////////////////////////////////////////////////////////////////////////
268        }