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 }