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_NEURALCOLUMN_H_DEFINED
00039 #define MODELNEURON_NEURALCOLUMN_H_DEFINED
00040
00041 #include "ModelNeuron/NeuralSimUtils.H"
00042 #include "ModelNeuron/SimUnit.H"
00043
00044 typedef SimUnit::RateType RateType;
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 template<class T>
00057 class NeuralColumn : public SimUnit
00058 {
00059 public:
00060
00061 NeuralColumn(const SimTime& timestep, const RateType ratetype = SimUnit::NORMAL,
00062 const std::string& name = "", const std::string& units = "");
00063
00064
00065 virtual ~NeuralColumn();
00066
00067
00068 const uint numSubs() const;
00069
00070
00071 const SimUnit& getSub(const uint i) const;
00072
00073
00074 void addSub(const SimUnit& sub, uint repeat = 1);
00075
00076
00077
00078
00079 void addWeight(const int from, const int to, const float weight);
00080
00081 protected:
00082
00083 SimUnit& editSub(const uint i);
00084
00085
00086 private:
00087 struct Weights
00088 {
00089 int from, to;
00090 float str;
00091 };
00092
00093 typedef typename nsu::vector<T> vector;
00094 typedef typename std::vector<Weights> weights_vector;
00095 typedef typename nsu::vector<T>::Type cast_type;
00096
00097
00098 const double doIntegrate(const SimTime& dt, const double& exc, const double& inh);
00099
00100
00101 virtual void doExtraIntegrate(const SimTime& dt, const double& exc, const double& inh);
00102
00103
00104
00105 virtual void combineOutput(double& total, const double& value, const double& parameter);
00106
00107
00108 void doInit();
00109
00110
00111 NeuralColumn* doClone() const;
00112
00113
00114
00115 void addSub(const SimUnit& sub, nsu::Int2Type<false>);
00116 void addSub(const SimUnit& sub, nsu::Int2Type<true>);
00117
00118 vector itsM;
00119
00120
00121 weights_vector itsInputW, itsW, itsOutputW;
00122 };
00123
00124
00125
00126
00127 template<class T> inline
00128 NeuralColumn<T>::NeuralColumn(const SimTime& timestep,
00129 const RateType ratetype,
00130 const std::string& name,
00131 const std::string& units) :
00132 SimUnit(timestep, ratetype, name, units), itsM(),
00133 itsInputW(), itsW(), itsOutputW()
00134 { }
00135
00136
00137 template<class T> inline
00138 NeuralColumn<T>::~NeuralColumn()
00139 { }
00140
00141
00142 template<class T> inline
00143 const uint NeuralColumn<T>::numSubs() const
00144 {
00145 return (uint)itsM.size();
00146 }
00147
00148
00149 template<class T>
00150 const SimUnit& NeuralColumn<T>::getSub(const uint i) const
00151 {
00152 if (i < itsM.size())
00153 {
00154 return itsM[i];
00155 }
00156 else
00157 {
00158 LFATAL("no units added to this column");
00159 return itsM[0];
00160 }
00161 }
00162
00163
00164 template<class T>
00165 SimUnit& NeuralColumn<T>::editSub(const uint i)
00166 {
00167 if (i < itsM.size())
00168 {
00169 return itsM[i];
00170 }
00171 else
00172 {
00173 LFATAL("no units added to this column");
00174 return itsM[0];
00175 }
00176 }
00177
00178
00179 template <class T> inline
00180 void NeuralColumn<T>::addSub(const SimUnit& sub, uint repeat)
00181 {
00182 for (uint i = 0; i < repeat; ++i)
00183 addSub(sub, nsu::Int2Type<nsu::vector<T>::isPointer >());
00184 }
00185
00186
00187 template <class T> inline
00188 void NeuralColumn<T>::addSub(const SimUnit& sub, nsu::Int2Type<false>)
00189 {
00190 const cast_type temp = dynamic_cast<const cast_type&>(sub);
00191 itsM.push_back(temp);
00192 }
00193
00194
00195 template <class T> inline
00196 void NeuralColumn<T>::addSub(const SimUnit& sub, nsu::Int2Type<true>)
00197 {
00198 itsM.push_back(sub);
00199 }
00200
00201
00202 template <class T>
00203 void NeuralColumn<T>::addWeight(const int from, const int to,
00204 const float weight)
00205 {
00206 if ( (from == to) && (from == -1) )
00207 LFATAL("It doesn't make since to map inputs directly to outputs");
00208
00209 if ( (from < (int)itsM.size()) && (to < (int)itsM.size()) )
00210 {
00211 Weights temp = {from, to, weight};
00212 if (to == -1)
00213 itsOutputW.push_back(temp);
00214 else if (from == -1)
00215 itsInputW.push_back(temp);
00216 else
00217 itsW.push_back(temp);
00218 }
00219 else
00220 LFATAL("A weight between these two modules cannot be added as at least "
00221 "one of them is out of range.");
00222 }
00223
00224
00225 template <class T>
00226 const double NeuralColumn<T>::doIntegrate(const SimTime& dt,
00227 const double& exc, const double& inh)
00228 {
00229
00230 typename weights_vector::const_iterator iter(itsInputW.begin());
00231 while (iter != itsInputW.end())
00232 {
00233 itsM[iter->to].inputExc( exc * (iter)->str );
00234 itsM[iter->to].inputInh( inh * (iter)->str );
00235 ++iter;
00236 }
00237
00238
00239 iter = itsW.begin();
00240 while (iter != itsW.end())
00241 {
00242 itsM[iter->to].input( itsM[iter->from].getOutput() * iter->str );
00243 ++iter;
00244 }
00245
00246
00247 doExtraIntegrate(dt, exc, inh);
00248
00249
00250 typename vector::iterator ii(itsM.begin()), end(itsM.end());
00251 while (ii != end)
00252 (ii++)->evolve(getTime());
00253
00254
00255 double out = 0.0;
00256 iter = itsOutputW.begin();
00257 while (iter != itsOutputW.end())
00258 {
00259 combineOutput(out, itsM[(iter)->from].getOutput(), iter->str);
00260 ++iter;
00261 }
00262 return out;
00263 }
00264
00265
00266 template <class T>
00267 void NeuralColumn<T>::doExtraIntegrate(const SimTime& dt, const double& exc, const double& inh)
00268 { }
00269
00270
00271 template <class T>
00272 void NeuralColumn<T>::combineOutput(double& total, const double& value, const double& parameter)
00273 {
00274 total += value * parameter;
00275 }
00276
00277
00278 template <class T>
00279 void NeuralColumn<T>::doInit()
00280 {
00281 itsInputW.clear();
00282 itsW.clear();
00283 itsOutputW.clear();
00284
00285 typename vector::iterator ii(itsM.begin()), end(itsM.end());
00286 while (ii != end)
00287 (ii++)->initialize();
00288 }
00289
00290
00291 template <class T> inline
00292 NeuralColumn<T>* NeuralColumn<T>::doClone() const
00293 {
00294 return new NeuralColumn(*this);
00295 }
00296
00297 #endif
00298
00299
00300
00301
00302