00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef MODELNEURON_LOWPASS_H_DEFINED
00039 #define MODELNEURON_LOWPASS_H_DEFINED
00040
00041 #include "ModelNeuron/SimUnit.H"
00042
00043 #include<cmath>
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 class LowPassFwdEuler
00071 {
00072 public:
00073 static const SimUnit::RateType RateType = SimUnit::NORMAL;
00074
00075 LowPassFwdEuler(const double& timestep, const double& h, const double& tau) :
00076 H(h), Tau(tau), itsTimeStep(timestep) { };
00077
00078 ~LowPassFwdEuler() { };
00079
00080
00081 void update(const double& in, double& g) const
00082 { g = g + itsTimeStep * (-1.0 * g + in + H) / Tau; };
00083
00084
00085 void update_nodecay_input(const double& in, double& g) const
00086 { g = g + itsTimeStep * (-1.0 * g + H) / Tau + in; };
00087
00088
00089 double H, Tau;
00090
00091 private:
00092 double itsTimeStep;
00093 };
00094
00095
00096
00097
00098 class LowPassExpEuler
00099 {
00100 public:
00101 static const SimUnit::RateType RateType = SimUnit::STRICT;
00102
00103 LowPassExpEuler(const double& timestep, const double& h, const double& tau) :
00104 H(h), Tau(tau), B(1.0/Tau), E(exp(-1.0 * B * timestep)), E1(1 - E) { };
00105
00106 ~LowPassExpEuler() { };
00107
00108
00109 void update(const double& in, double& g) const
00110 {
00111 double A = (H + in) / Tau;
00112 g = g * E + (A / B) * E1;
00113 };
00114
00115
00116 void update_nodecay_input(const double& in, double& g) const
00117 {
00118 double A = H / Tau + in;
00119 g = g * E + (A / B) * E1;
00120 };
00121
00122
00123 double H, Tau;
00124
00125 private:
00126 double B;
00127 double E;
00128 double E1;
00129 };
00130
00131
00132
00133
00134
00135 namespace RateFunctions
00136 {
00137
00138
00139
00140 struct EmptyFunction
00141 {
00142
00143 EmptyFunction() { };
00144
00145 ~EmptyFunction() { };
00146
00147 static const char* name() { return ""; };
00148
00149 const double operator()(const double& in) const { return in; }
00150 };
00151
00152
00153
00154
00155
00156
00157
00158 struct FullRectifyFunction
00159 {
00160
00161 FullRectifyFunction() { };
00162
00163 ~FullRectifyFunction() { };
00164
00165 static const char* name() { return "FullRectify"; };
00166
00167 const double operator()(const double& in) const
00168 {
00169 return (in >= 0.0) ? in : -1.0 * in;
00170 }
00171 };
00172
00173
00174
00175
00176
00177
00178
00179 struct RectifyFunction
00180 {
00181
00182 RectifyFunction(const double& thresh) :
00183 Thresh(thresh) { };
00184
00185 ~RectifyFunction() { };
00186
00187 static const char* name() { return "Rectify"; };
00188
00189 const double operator()(const double& in) const
00190 {
00191 return (in > Thresh) ? in : 0.0;
00192 }
00193
00194 double Thresh;
00195 };
00196
00197
00198
00199
00200
00201
00202
00203
00204 struct MaxRectFunction
00205 {
00206
00207 MaxRectFunction(const double& thresh, const double& max) :
00208 Thresh(thresh), Max(max) { };
00209
00210 ~MaxRectFunction() { };
00211
00212 static const char* name() { return "MaxRect"; };
00213
00214 const double operator()(const double& in) const
00215 {
00216 if (in <= Thresh)
00217 return 0.0;
00218 else if (in > Max)
00219 return Max;
00220 else
00221 return in;
00222 }
00223
00224 double Thresh, Max;
00225 };
00226
00227
00228
00229
00230
00231
00232 struct StepFunction
00233 {
00234
00235 StepFunction(const double& thresh, const double& max) :
00236 Thresh(thresh), Max(max) { };
00237
00238 ~StepFunction() { };
00239
00240 static const char* name() { return "Step"; };
00241
00242 const double operator()(const double& in) const
00243 {
00244 if (in <= Thresh)
00245 return 0.0;
00246 else
00247 return Max;
00248 }
00249
00250 double Thresh, Max;
00251 };
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 struct LogThreshFunction
00265 {
00266
00267 LogThreshFunction(const double& theta) : Thresh(theta) { };
00268
00269 ~LogThreshFunction() { };
00270
00271 static const char* name() { return "LogThresh"; };
00272
00273 const double operator()(const double& in) const
00274 {
00275 if (in < Thresh)
00276 return 0.0;
00277 else
00278 return log(in / Thresh);
00279 }
00280
00281 double Thresh;
00282 };
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 struct SigmoidFunction
00293 {
00294
00295 SigmoidFunction(const double& thresh, const double& slope) :
00296 Thresh(thresh), Slope(slope) { };
00297
00298 ~SigmoidFunction() { };
00299
00300 static const char* name() { return "Sigmoid"; };
00301
00302 const double operator()(const double& in) const
00303 {
00304 return 1 / ( 1 + exp(-1.0 * Slope * (in - Thresh)) );
00305 }
00306
00307 double Thresh, Slope;
00308 };
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 template <class RateFunc = RateFunctions::EmptyFunction,
00326 class IntType = LowPassExpEuler>
00327 class LowPassFilter: public SimUnit, public IntType
00328 {
00329 public:
00330
00331 LowPassFilter(const double& tau,
00332 const double& h,
00333 const SimTime& timestep,
00334 const std::string& name = "Lowpass",
00335 const std::string& units = "pA");
00336
00337
00338 LowPassFilter(const double& tau,
00339 const double& h,
00340 const double& param1,
00341 const SimTime& timestep,
00342 const std::string& name = "Lowpass",
00343 const std::string& units = "pA");
00344
00345
00346 LowPassFilter(const double& tau,
00347 const double& h,
00348 const double& param1,
00349 const double& param2,
00350 const SimTime& timestep,
00351 const std::string& name = "Lowpass",
00352 const std::string& units = "pA");
00353
00354
00355 ~LowPassFilter() { };
00356
00357
00358 const double getDisplayOutput() const;
00359
00360 private:
00361
00362 const double doIntegrate(const SimTime& dt,
00363 const double& ine, const double& inh);
00364
00365
00366 void doInit();
00367
00368
00369 LowPassFilter<RateFunc, IntType>* doClone() const;
00370
00371 double itsG;
00372 RateFunc firingRate;
00373 };
00374
00375
00376
00377
00378 typedef
00379 LowPassFilter<RateFunctions::EmptyFunction, LowPassExpEuler> LowPass;
00380 typedef
00381 LowPassFilter<RateFunctions::RectifyFunction, LowPassExpEuler> LowPassRectify;
00382 typedef
00383 LowPassFilter<RateFunctions::FullRectifyFunction, LowPassExpEuler> LowPassFullRectify;
00384 typedef
00385 LowPassFilter<RateFunctions::StepFunction, LowPassExpEuler> LowPassStep;
00386 typedef
00387 LowPassFilter<RateFunctions::MaxRectFunction, LowPassExpEuler> LowPassMaxRect;
00388 typedef
00389 LowPassFilter<RateFunctions::LogThreshFunction, LowPassExpEuler> LowPassLog;
00390 typedef
00391 LowPassFilter<RateFunctions::SigmoidFunction, LowPassExpEuler> LowPassSigmoid;
00392
00393
00394
00395
00396 namespace
00397 {
00398 typedef SimUnit::Factory LPFactory;
00399 typedef SimUnit::Creator LPCreator;
00400
00401 struct RegisterLowPassFilter
00402 {
00403 RegisterLowPassFilter()
00404 {
00405 const double tau = 50.0;
00406 const SimTime time = SimTime::MSECS(1.0);
00407 LPFactory::instance().add("LowPass",
00408 LPCreator::make<LowPass>(tau, -0.5, time));
00409 LPFactory::instance().add("LowPassRectify",
00410 LPCreator::make<LowPassRectify>(tau, -0.5, 0.0, time));
00411 LPFactory::instance().add("LowPassFullRectify",
00412 LPCreator::make<LowPassFullRectify>(tau, 0.0, time));
00413 LPFactory::instance().add("LowPassStep",
00414 LPCreator::make<LowPassStep>(tau, -0.5, 0.0, 1.0, time));
00415 LPFactory::instance().add("LowPassMaxRect",
00416 LPCreator::make<LowPassMaxRect>(tau, -0.5, 0.0, 1.0, time));
00417 LPFactory::instance().add("LowPassLog",
00418 LPCreator::make<LowPassLog>(tau, 0.0, 0.1, time));
00419 LPFactory::instance().add("LowPassSigmoid",
00420 LPCreator::make<LowPassSigmoid>(tau, -0.5, 0.55, 12.0, time));
00421 }
00422 };
00423 static RegisterLowPassFilter registerlpf;
00424 }
00425
00426
00427
00428
00429
00430
00431
00432 template <class RateFunc, class IntType> inline
00433 LowPassFilter<RateFunc, IntType>::LowPassFilter(const double& tau,
00434 const double& h,
00435 const SimTime& timestep,
00436 const std::string& name,
00437 const std::string& units) :
00438 SimUnit(timestep, IntType::RateType, name+RateFunc::name(), units),
00439 IntType(timestep.msecs(), h, tau), itsG(h), firingRate() { };
00440
00441
00442
00443
00444 template <class RateFunc, class IntType> inline
00445 LowPassFilter<RateFunc, IntType>::LowPassFilter(const double& tau,
00446 const double& h,
00447 const double& param1,
00448 const SimTime& timestep,
00449 const std::string& name,
00450 const std::string& units) :
00451 SimUnit(timestep, IntType::RateType, name+RateFunc::name(), units),
00452 IntType(timestep.msecs(), h, tau), itsG(h), firingRate(param1) { };
00453
00454
00455
00456
00457 template <class RateFunc, class IntType> inline
00458 LowPassFilter<RateFunc, IntType>::LowPassFilter(const double& tau,
00459 const double& h,
00460 const double& param1,
00461 const double& param2,
00462 const SimTime& timestep,
00463 const std::string& name,
00464 const std::string& units) :
00465 SimUnit(timestep, IntType::RateType, name+RateFunc::name(), units),
00466 IntType(timestep.msecs(), h, tau), itsG(h), firingRate(param1, param2) { };
00467
00468
00469 template <class RateFunc, class IntType> inline
00470 const double LowPassFilter<RateFunc, IntType>::getDisplayOutput() const
00471 {
00472 return itsG;
00473 }
00474
00475
00476 template <class RateFunc, class IntType> inline
00477 const double LowPassFilter<RateFunc, IntType>::doIntegrate(const SimTime& dt,
00478 const double& ine,
00479 const double& inh)
00480 {
00481 IntType::update(ine + inh, itsG);
00482 return firingRate(itsG);
00483 }
00484
00485
00486 template <class RateFunc, class IntType> inline
00487 void LowPassFilter<RateFunc, IntType>::doInit()
00488 {
00489 itsG = IntType::H;
00490 }
00491
00492
00493 template <class RateFunc, class IntType> inline
00494 LowPassFilter<RateFunc, IntType>*
00495 LowPassFilter<RateFunc, IntType>::doClone() const
00496 {
00497 return new LowPassFilter<RateFunc, IntType>(*this);
00498 }
00499
00500 #endif
00501
00502
00503
00504
00505