Layer.H

Go to the documentation of this file.
00001 /*!@file ModelNeuron/Layer.H Class declarations for a layer of
00002    SimUnits that supports lateral interactions, in a 2D grid. */
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: David Berg <dberg@usc.edu>
00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/ModelNeuron/Layer.H $
00036 
00037 #ifndef MODELNEURON_LAYER_H_DEFINED
00038 #define MODELNEURON_LAYER_H_DEFINED
00039 
00040 #include "ModelNeuron/SimLayer.H"
00041 #include "ModelNeuron/Location.H"
00042 #include "ModelNeuron/Weights.H"
00043 #include "ModelNeuron/SimUnit.H"
00044 #include "ModelNeuron/NeuralSimUtils.H"
00045 
00046 // ######################################################################
00047 //  Layer
00048 //  ######################################################################
00049 //  A SimLayer (see SimLayer.H) that models a
00050 //  2-dimensional layer of cortex. Neurons are placed on a grid, with
00051 //  laterial interactions computed by a Weights (see Weights.H)
00052 //  object.
00053 //  ######################################################################
00054 template<class T, class W>
00055 class Layer : public SimLayer
00056 {
00057 public:
00058   //! constructor
00059   Layer(const SimTime& timestep, const uint width, const uint height,
00060         const std::string& name = "", const std::string& units = "");
00061 
00062   //! constructor for weights with 1 param
00063   Layer(const double& param1, const SimTime& timestep, const uint width, const uint height,
00064         const std::string& name = "", const std::string& units = "");
00065 
00066   //! constructor for weights with two params, center and boarder options
00067   Layer(const double& param1,  const double& param2,
00068         const bool doSubCenter, const BorderPolicy bp, 
00069         const SimTime& timestep, const uint width, const uint height,
00070         const std::string& name = "", const std::string& units = "");
00071 
00072   //! constructor for weights with three params, center and boarder options
00073   Layer(const double& param1, const double& param2, 
00074         const double& param3, const bool doSubCenter,
00075         const BorderPolicy bp, 
00076         const SimTime& timestep, const uint width, const uint height,
00077         const std::string& name = "", const std::string& units = "");
00078 
00079   //! constructor for weights with three params, center and boarder options
00080   Layer(const double& param1, const double& param2,  
00081         const double& param3, const double& param4,
00082         const bool subCenter, const BorderPolicy bp,
00083         const SimTime& timestep, const uint width, const uint height,
00084         const std::string& name = "", const std::string& units = "");
00085 
00086   //!copy constructor
00087   Layer(const Layer& nlc);
00088 
00089   //assignment
00090   Layer& operator=(const Layer& nlc);
00091   
00092   //!destructor 
00093   virtual ~Layer();
00094 
00095   //!get the current display output 
00096   Image<double> getDisplayOutput(const int pos = -1) const;
00097   
00098   //!get unit(s) at desired location
00099   void getSimUnit(const Location& loc, std::vector<const SimUnit*>& units);
00100   
00101   //!edit unit(s) at the desired output position
00102   void editSimUnit(const Location& loc, std::vector<SimUnit*>& units);
00103   
00104   //!number of simunits - just returns getOutSize()
00105   const uint numSimUnits() const;
00106   
00107   //!get the unit at desired position [pos / w, pos % w],
00108   //!(where '/' is integer division, '%' is modulus, and w is the
00109   //!width of the layer)
00110   const SimUnit& getSimUnit(const uint pos) const;
00111   
00112   //get the unit, mutable version
00113   SimUnit& editSimUnit(const uint pos);
00114   
00115   //!set type of simulation module
00116   void setModule(const SimUnit& nsm);
00117   
00118   //!set type of simulation module at the position 
00119   void setModule(const SimUnit& nsm, const Location& p);
00120 
00121   //!set the time of this structure and all contained SimUnits if true
00122   void setTime(const SimTime& time, const bool recursive = true);
00123 
00124   //!set the lateral interaction weights, which describe how activity
00125   //!is spread throughout the layer.
00126   void setWeights(const W& weights);
00127 
00128   //clone the object
00129   Layer<T,W>* clone () const;
00130   
00131 private:
00132   //!integrate one time step
00133   void doIntegrate(const SimTime& dt, const Image<double>& inpe, const Image<double>& inpi);
00134    
00135   //!reset this object and all the SimUnits in the layer
00136   void doInit();
00137   
00138   //!is our layer full?
00139   const bool isFull(const Location& pos = Location(-1));
00140 
00141   //set the module non-polymorphic
00142   void setModule(const SimUnit& nsm, nsu::Int2Type<false>);
00143   void setModule(const SimUnit& nsm, const Location& pos, nsu::Int2Type<false>);
00144   
00145   //set the module polymorphic
00146   void setModule(const SimUnit& nsm, nsu::Int2Type<true>);
00147   void setModule(const SimUnit& nsm, const Location& pos, nsu::Int2Type<true>);
00148 
00149   template <class U> struct non_pointer_type { typedef U Type; };
00150   template <class U> struct non_pointer_type<U*> { typedef U Type; };
00151 
00152   //! an iterator into the layer
00153   typedef typename nsu::vector<T>::iterator iterator;
00154   typedef typename nsu::vector<T>::const_iterator const_iterator;
00155 
00156   //!iterator for images
00157   typedef typename Image<double>::iterator d_iterator;
00158   typedef typename Image<double>::const_iterator const_d_iterator;
00159 
00160   //if we are polymorhic, get the pointee type
00161   typedef typename non_pointer_type<T>::Type cast_type;
00162 
00163   nsu::vector<T> itsL; //the layer
00164   W itsW; //weight interaction
00165 
00166   std::vector<bool> itsFilled; //vector of which units are assigned modules
00167   bool itsFull; //true if the entire layer is filled
00168 
00169   Location itsProbe; //copy of the probe, if one
00170 };
00171 
00172 // ######################################################################
00173 // Layer implementation
00174 // ######################################################################
00175 template<class T, class W>
00176 Layer<T,W>::Layer(const SimTime& timestep, const uint width, const uint height,
00177                   const std::string& name, const std::string& units) :
00178   SimLayer(timestep, width, height, name, units), 
00179   itsL(), itsW(), itsFilled(width * height, false), 
00180   itsFull(false), itsProbe() { itsProbe.setHyperCubeDims(width, height); }
00181 
00182 // ######################################################################
00183 template<class T, class W>
00184 Layer<T,W>::Layer(const double& param1, const SimTime& timestep,
00185                   const uint width, const uint height,
00186                   const std::string& name, const std::string& units)
00187   : SimLayer(timestep, width, height, name, units), 
00188     itsL(), itsW(param1), itsFilled(width * height, false), itsFull(false), itsProbe() 
00189 { itsProbe.setHyperCubeDims(width, height); }
00190     
00191 // ######################################################################
00192 template<class T, class W>
00193 Layer<T,W>::Layer(const double& param1,  const double& param2,
00194                   const bool doSubCenter, const BorderPolicy bp, 
00195                   const SimTime& timestep,
00196                   const uint width, const uint height,
00197                   const std::string& name, const std::string& units)
00198   : SimLayer(timestep, width, height, name, units), 
00199     itsL(), itsW(param1,param2,doSubCenter,bp), 
00200     itsFilled(width * height, false), itsFull(false), itsProbe() 
00201 { itsProbe.setHyperCubeDims(width, height); }
00202 
00203 // ######################################################################
00204 template<class T, class W>
00205 Layer<T,W>::Layer(const double& param1, const double& param2, 
00206                   const double& param3, const bool doSubCenter,
00207                   const BorderPolicy bp, const SimTime& timestep,
00208                   const uint width, const uint height,
00209                   const std::string& name, const std::string& units)
00210   : SimLayer(timestep, width, height, name, units), 
00211     itsL(), itsW(param1,param2,param3,doSubCenter,bp), 
00212     itsFilled(width * height, false), itsFull(false), itsProbe() 
00213 { itsProbe.setHyperCubeDims(width, height); }
00214 
00215 // ######################################################################
00216 template<class T, class W>
00217 Layer<T,W>::Layer(const double& param1, const double& param2,  
00218                   const double& param3, const double& param4,
00219                   const bool doSubCenter, 
00220                   const BorderPolicy bp,const SimTime& timestep,
00221                   const uint width, const uint height,
00222                   const std::string& name, 
00223                   const std::string& units) :
00224   SimLayer(timestep, width, height, name, units), 
00225   itsL(), itsW(param1,param2,param3,param4,doSubCenter,bp), 
00226   itsFilled(width * height, false), itsFull(false), itsProbe() 
00227 { itsProbe.setHyperCubeDims(width, height); }
00228 
00229 // ######################################################################
00230 template<class T, class W>
00231 Layer<T,W>::Layer(const Layer<T,W>& rhs) :
00232   SimLayer(rhs), itsL(rhs.itsL), itsW(rhs.itsW), 
00233   itsFilled(rhs.itsFilled), itsFull(rhs.itsFull), itsProbe(rhs.itsProbe)
00234 { }
00235 
00236 // ######################################################################
00237 template<class T, class W>
00238 Layer<T,W>& Layer<T,W>::operator=(const Layer<T,W>& rhs)
00239 {
00240   if (this != &rhs)
00241     {
00242       SimLayer::operator=(rhs);
00243       itsL = rhs.itsL;
00244       itsW = rhs.itsW;
00245       itsFilled = rhs.itsFilled;
00246       itsFull = rhs.itsFull;
00247       itsProbe = rhs.itsProbe;
00248     }
00249   return *this;
00250 }
00251 
00252 // ######################################################################
00253 template<class T, class W>
00254 Layer<T,W>::~Layer()
00255 { }
00256 
00257 // ######################################################################
00258 template<class T, class W>
00259 Image<double> Layer<T,W>::getDisplayOutput(const int pos) const
00260 {
00261   ASSERT(pos < 1);
00262   Image<double> out(getOutDims(), NO_INIT);
00263   if (itsFull)
00264     {
00265       d_iterator outiter(out.beginw());    
00266       const_iterator nsmptr(itsL.begin()), end(itsL.end());
00267       
00268       while (nsmptr != end) 
00269         *outiter++ = (nsmptr++)->getDisplayOutput();
00270     }
00271   return out;
00272 }
00273 
00274 // ######################################################################
00275 template<class T, class W> 
00276 void Layer<T,W>::getSimUnit(const Location& loc, std::vector<const SimUnit*>& units)
00277 {
00278   //update our location and get the vector of points, the hypercube dims have been set already
00279   itsProbe.setLocation(loc);
00280   const std::vector<int>& locs = itsProbe.getLinearPos();
00281 
00282   //loop through all the locations
00283   std::vector<int>::const_iterator iter(locs.begin());
00284   while (iter != locs.end())
00285     units.push_back(&getSimUnit(*iter++));
00286 }
00287   
00288 // ######################################################################
00289 template<class T, class W> 
00290 void Layer<T,W>::editSimUnit(const Location& loc, std::vector<SimUnit*>& units)
00291 {
00292   //update our location and get the vector of points, the hypercube dims have been set already
00293   itsProbe.setLocation(loc);
00294   const std::vector<int>& locs = itsProbe.getLinearPos();
00295   
00296   std::vector<int>::const_iterator iter(locs.begin());
00297   while (iter != locs.end())
00298     units.push_back(&editSimUnit(*iter++));
00299 }
00300 
00301 // ######################################################################
00302 template<class T, class W> 
00303 const uint Layer<T,W>::numSimUnits() const
00304 {
00305   return getOutSize();
00306 }
00307 
00308 // ######################################################################
00309 template<class T, class W> 
00310 const SimUnit& Layer<T,W>::getSimUnit(const uint pos) const
00311 {
00312   if (pos > itsL.size())
00313     if (itsL.isNull(pos))
00314       LFATAL("That unit has not yet been assigned");
00315   return itsL[pos];
00316 }
00317 
00318 // ######################################################################
00319 template<class T, class W> 
00320 SimUnit& Layer<T,W>::editSimUnit(const uint pos)
00321 {
00322   if (pos > itsL.size())
00323     if (itsL.isNull(pos))
00324       LFATAL("That unit has not yet been assigned");
00325   return itsL[pos];
00326 }
00327 // ######################################################################
00328 template<class T, class W> 
00329 void Layer<T,W>::setModule(const SimUnit& mod)
00330 { 
00331   setModule(mod, nsu::Int2Type<nsu::TypeTraits<T>::isPointer >());
00332 }
00333 
00334 
00335 // ######################################################################
00336 template<class T, class W> 
00337 void Layer<T,W>::setModule(const SimUnit& mod, const Location& pos)
00338 {
00339   setModule(mod, pos, nsu::Int2Type<nsu::TypeTraits<T>::isPointer >());
00340 }
00341 
00342 // ######################################################################
00343 template<class T, class W> 
00344 void Layer<T,W>::setWeights(const W& weights)
00345 {
00346   itsW = weights;
00347 }
00348 
00349 // ######################################################################
00350 template<class T, class W> 
00351 void Layer<T,W>::setTime(const SimTime& time, const bool recursive)
00352 {
00353   //call the base class version, but with no recursion since we wont have any subs. 
00354   SimLayer::setTime(time, false);
00355 
00356   if (recursive)
00357     {
00358       iterator nsmptr(itsL.begin()), end(itsL.end());
00359       std::vector<bool>::const_iterator fptr(itsFilled.begin());
00360 
00361       while (nsmptr != end) 
00362         {
00363           if (*fptr)
00364             nsmptr->setTime(time, true);
00365           
00366           ++fptr; ++nsmptr;
00367         }
00368     }
00369 }
00370 
00371 // ######################################################################
00372 template<class T, class W>
00373 void Layer<T,W>::doIntegrate(const SimTime& dt, const Image<double>& inpe, const Image<double>& inpi)
00374 {
00375   if (itsFull && itsW.initialized())
00376     {      
00377       //compute any neighborhood activity
00378       const Image<double> neighborhood  = itsW.compute( itsOutput );
00379       const_d_iterator i_n(neighborhood.begin());
00380 
00381       //get an iterator for our layer
00382       iterator i_l(itsL.begin()), end(itsL.end());
00383 
00384       //output iterator
00385       d_iterator i_out(itsOutput.beginw());
00386 
00387       //input iterators
00388       const_d_iterator i_exc(inpe.begin()), i_inh(inpi.begin());
00389 
00390       //update each of our SimUnits input and evolve
00391       while (i_l != end) 
00392         {
00393           //inputs need to be seperated as excitatory and inhibitory
00394           //are dealt with differently
00395           i_l->input(*i_n++);
00396           i_l->inputExc(*i_exc++);
00397           i_l->inputInh(*i_inh++);
00398           i_l->evolve(getTime());
00399           *i_out++ = (i_l++)->getOutput();
00400         }      
00401     }
00402   else
00403     { LFATAL("All positions in the layer have not been filled with modules"
00404              " or the weights have not yet been setup"); 
00405     }
00406 }
00407 
00408 // ######################################################################
00409 template<class T, class W>
00410 void Layer<T,W>::doInit()
00411 {
00412   for (uint i = 0; i < itsL.size(); ++i)
00413     if (~itsL.isNull(i))
00414       itsL[i].initialize();
00415 }
00416 
00417 // ######################################################################
00418 template<class T, class W> 
00419 Layer<T,W>* Layer<T,W>::clone () const
00420 { return new Layer<T,W>(*this); };
00421 
00422 // ######################################################################
00423 template<class T, class W>
00424 void Layer<T,W>::setModule(const SimUnit& nsm, nsu::Int2Type<false>)
00425 {
00426   this->setUnits(nsm.getUnits());
00427   const cast_type temp = dynamic_cast<const cast_type&>(nsm);
00428   itsL.clear();
00429   for (uint i = 0; i < getOutSize(); ++i)
00430     itsL.push_back(temp);
00431   itsFull = true;
00432   itsFilled = std::vector<bool>(itsFilled.size(), true);
00433 }
00434 
00435 // ######################################################################
00436 template<class T, class W>
00437 void Layer<T,W>::setModule(const SimUnit& nsm, nsu::Int2Type<true>)
00438 {
00439   this->setUnits(nsm.getUnits());
00440   itsL.clear();
00441   for (uint i = 0; i < getOutSize(); ++i)
00442     itsL.push_back(nsm);
00443   itsFull = true;
00444   itsFilled = std::vector<bool>(itsFilled.size(), true);
00445 }
00446 
00447 // ######################################################################
00448 template<class T, class W>
00449 void Layer<T,W>::setModule(const SimUnit& nsm, const Location& pos, nsu::Int2Type<false>)
00450 {
00451   const cast_type temp = dynamic_cast<const cast_type&>(nsm);
00452   Location p = pos;
00453   const std::vector<int>& locs = p.getLinearPos(getOutWidth(), getOutHeight());
00454   std::vector<int>::const_iterator iter(locs.begin());
00455   while (iter != locs.end())
00456     {
00457       if (*iter < (int)itsL.size())
00458         itsL.set_at(*iter, temp);
00459       else
00460         for (int i = itsL.size(); i <= *iter; ++i)
00461           itsL.push_back(temp);
00462       
00463       itsFilled[*iter++] = true;
00464     }
00465   itsFull = isFull();
00466 }
00467 
00468 // ######################################################################
00469 template<class T, class W>
00470 void Layer<T,W>::setModule(const SimUnit& nsm, const Location& pos, nsu::Int2Type<true>)
00471 {
00472   Location p = pos;
00473   const std::vector<int>& locs = p.getLinearPos(getOutWidth(), getOutHeight());
00474   std::vector<int>::const_iterator iter(locs.begin());
00475   while (iter != locs.end())
00476     {
00477       if (*iter < (int)itsL.size())
00478         itsL.set_at(*iter, nsm);
00479       else
00480         for (int i = (int)itsL.size(); i <= *iter; ++i)
00481           itsL.push_back(nsm);
00482 
00483       itsFilled[*iter++] = true;
00484     }
00485   itsFull = isFull();
00486 }
00487 
00488 // ######################################################################
00489 template<class T, class W>
00490 const bool Layer<T,W>::isFull(const Location& pos)
00491 {
00492   std::vector<bool>::const_iterator i(itsFilled.begin()), end(itsFilled.end());
00493   while (i != end)
00494     if (*i++ == false)
00495       return false;
00496   
00497   return true;
00498 }
00499 
00500 #endif
00501   
00502 // ######################################################################
00503 /* So things look consistent in everyone's emacs... */
00504 /* Local Variables: */
00505 /* indent-tabs-mode: nil */
00506 /* End: */
Generated on Sun May 8 08:41:01 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3