SimLayer.H

Go to the documentation of this file.
00001 /*!@file ModelNeuron/SimLayer.H Class declarations for partial 
00002 implementations of SimStruture for 2-D simulation units.  */
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 J Berg <dberg@usc.edu>
00035 // $HeadURL: svn://isvn.usc.edu:/software/invt/trunk/saliency/src/ModelNeuron/SimLayer.H $
00036 
00037 #ifndef MODELNEURON_SIMLAYER_H_DEFINED
00038 #define MODELNEURON_SIMLAYER_H_DEFINED
00039 
00040 #include "Util/SimTime.H"
00041 #include "ModelNeuron/SimUnit.H"
00042 #include "ModelNeuron/SimStructure.H"
00043 #include "ModelNeuron/NeuralSimUtils.H"
00044 
00045 class Location;
00046 // ######################################################################
00047 /*! This partial implementation of SimStructure represents a container for
00048 // SimUnits (See SimUnit.H) that takes 2D input, gives 2D output, and evolves
00049 // the internal states of its SimUnits. This class may have sub structures, but
00050 // this implementation only allows 1 input and output (ie, trying to input or 
00051 // get output to a layer > 0 will fail). See Structure.H for a class which 
00052 // implements sub structures such that they can be input to our output from.
00053 //
00054 // After a call to evolve(time), the modules internal time will be simulated up
00055 // to 'time' and a call to getOutput() will represent the output of the system
00056 // at 'time'. The logic is the same as SimUnit (see SimUnit.H). Sub structures
00057 // are not required to be simulated at the same time step. */
00058 //######################################################################
00059 class SimLayer : public SimStructure
00060 {
00061 public:  
00062   //! constructor
00063   SimLayer(const SimTime& timestep, const uint width, const uint height,
00064            const std::string name = "", const std::string units = "");
00065   
00066   //!destructor 
00067   virtual ~SimLayer() { };
00068   
00069   // ######################################################################
00070 // i/o and simulation functions
00071 // ######################################################################  
00072 
00073   //!set the input
00074   void input(const Image<double>& in, const int pos = -1);
00075 
00076   //!set the excitatory input
00077   void inputExc(const Image<double>& in, const int pos = -1);
00078 
00079   //!set the inhibitory input
00080   void inputInh(const Image<double>& in, const int pos = -1);
00081   
00082   //!get the current output 
00083   Image<double> getOutput(const int pos = -1) const;
00084 
00085   //!evolve up to specified time
00086   void evolve(const SimTime& simtime);
00087 
00088 // ######################################################################
00089 // get/set unit functions
00090 // ######################################################################  
00091 
00092   //!set the type of neural simulation module to use
00093   virtual void setModule(const SimUnit& mod) = 0;
00094   
00095   //!set the type of neural simulation module to use, at a specific
00096   //!position 
00097   virtual void setModule(const SimUnit& mod, const Location& pos) = 0;
00098 
00099 // ######################################################################
00100 // change state functions
00101 // ######################################################################  
00102 
00103   //reset all counters, output and call doInit() to reset all subclasses
00104   void initialize();
00105 
00106   //set the time
00107   void setTime(const SimTime& time, const bool recurse = true);
00108 
00109 // ######################################################################
00110 // get state functions
00111 // ######################################################################  
00112 
00113   //!get current time
00114   const SimTime getTime() const;
00115 
00116 
00117   //!get simulation time step
00118   const SimTime getTimeStep() const;
00119 
00120   //!clone the module
00121   virtual SimLayer* clone() const = 0;
00122 
00123 protected:
00124   //protect copy and asignment, use clone
00125   SimLayer(const SimLayer& nlc);
00126   SimLayer& operator=(const SimLayer& nlc);
00127 
00128   //the output
00129   Image<double>  itsOutput;
00130 
00131 private:
00132   //!integrate one time step
00133   virtual void doIntegrate(const SimTime& dt, const Image<double>& inpe, const Image<double>& inpi) = 0;
00134   
00135   //!an initializer
00136   virtual void doInit() = 0;
00137   
00138   SimTime itsTimeStep, itsT;
00139   uint itsSampScale;
00140   Image<double> itsInpExc, itsInpInh;
00141 };
00142 
00143 // ######################################################################
00144 //!A class to derive from to create new SimLayers. New
00145 //SimLayer derived types can derive from this class to
00146 //inherit the doClone() function if desired. 
00147 /*
00148   Programmer Note: This class uses the 'quriously recursive template
00149   pattern' to simplify creation of new classes for the programmer. As
00150   such, to create a new simulation module, classes should adhear the
00151   following convention:
00152   
00153   class mymodule : public SimLayerDerived<mymodule>
00154   {
00155       mymodule(//params//) : SimLayer<mymodule>(//params//) { };
00156       //...rest of functions
00157   }
00158 */
00159 // ######################################################################
00160 template <class Derived>
00161 class SimLayerDerived : public SimLayer
00162 {
00163 protected:
00164   SimLayerDerived(const SimTime& timestep, const uint width, const uint height,
00165                          const std::string name = "", const std::string units = "") : 
00166     SimLayer(timestep, width, height, name, units) { };
00167   
00168   virtual ~SimLayerDerived() { };
00169   
00170 private:
00171   Derived* clone() const { return new Derived(dynamic_cast<const Derived&>(*this)); }
00172 };
00173 
00174 
00175 // ######################################################################
00176 // SimLayer implementation
00177 // ######################################################################
00178 inline
00179 SimLayer::SimLayer(const SimTime& timestep, 
00180                                  const uint width, 
00181                                  const uint height,
00182                                  const std::string name, 
00183                                  const std::string units) :
00184   SimStructure(width, height, name, units),
00185   itsOutput(width, height, ZEROS), itsTimeStep(timestep), 
00186   itsT(SimTime::ZERO()), itsSampScale(1), 
00187   itsInpExc(width, height, ZEROS), itsInpInh(width, height, ZEROS)
00188 { }
00189 
00190 // ######################################################################
00191 inline
00192 SimLayer::SimLayer(const SimLayer& rhs) :
00193   SimStructure(rhs),
00194   itsOutput(rhs.itsOutput), itsTimeStep(rhs.itsTimeStep), itsT(rhs.itsT), 
00195   itsSampScale(rhs.itsSampScale), itsInpExc(rhs.itsInpExc), itsInpInh(rhs.itsInpInh)
00196 { }
00197 
00198 // ######################################################################
00199 inline
00200 SimLayer& SimLayer::operator=(const SimLayer& rhs)
00201 { 
00202   if (this != &rhs)
00203     {
00204       SimStructure::operator=(rhs);
00205       
00206       itsOutput = rhs.itsOutput;
00207       itsTimeStep = rhs.itsTimeStep;
00208       itsT = rhs.itsT;
00209       itsSampScale = rhs.itsSampScale;
00210       itsInpExc = rhs.itsInpExc;
00211       itsInpInh = rhs.itsInpInh;
00212     }
00213   return *this;
00214 }
00215 
00216 // ######################################################################
00217 inline 
00218 void SimLayer::input(const Image<double>& inp, const int pos)
00219 {
00220   ASSERT(inp.getDims() == itsOutput.getDims()); ASSERT(pos < 1);
00221   SimStructure::splitExcInh(inp, itsInpExc, itsInpInh);
00222 }
00223 
00224 // ######################################################################
00225 inline 
00226 void SimLayer::inputExc(const Image<double>& inp, const int pos)
00227 {
00228   ASSERT(inp.getDims() == itsOutput.getDims()); ASSERT(pos < 1);
00229   itsInpExc += inp;
00230 }
00231 
00232 // ######################################################################
00233 inline 
00234 void SimLayer::inputInh(const Image<double>& inp, const int pos)
00235 {
00236   ASSERT(inp.getDims() == itsOutput.getDims()); ASSERT(pos < 1);
00237   itsInpInh += inp;
00238 }
00239 
00240 // ######################################################################
00241 inline 
00242 Image<double> SimLayer::getOutput(const int pos) const
00243 {
00244   ASSERT(pos < 1);
00245   return itsOutput;
00246 }
00247 
00248 // ######################################################################
00249 inline
00250 void SimLayer::evolve(const SimTime& t)
00251 {
00252   // we run our difference equations with a time step of itsTimeStep;
00253   // let's here figure out how many iterations we will need to go from
00254   // itsT to t in an equal number of steps. Each step will be as close
00255   // to itsTimeStep as possible so that we end up at time t after
00256   // iterating for an integer number of time steps. 
00257   const SimTime interval(t - itsT);
00258   const int64 nsteps = interval.nsecs() / itsTimeStep.nsecs();
00259   const int steps = (int)nsteps;  
00260   SimTime currTimeStep;
00261 
00262   if (steps <= 0)
00263     ++itsSampScale;//keep track of how many times we don't integrate
00264   else
00265     {
00266       //set our current time step 
00267       currTimeStep = SimTime::NSECS(interval.nsecs() / nsteps);  
00268       
00269       if (itsSampScale > 1)
00270         {      
00271           //rescale our inputs
00272           itsInpExc /= itsSampScale;
00273           itsInpInh /= itsSampScale;
00274           itsSampScale = 1;
00275         }
00276       
00277       for (int ii = 0; ii < steps; ++ii)
00278         {      
00279           //update our current time
00280           itsT += currTimeStep;
00281 
00282           //integrate our internals
00283           doIntegrate(currTimeStep, itsInpExc, itsInpInh);
00284         }
00285 
00286       //reset our input after we evolve to the current time step
00287       itsInpExc.clear(0.0);
00288       itsInpInh.clear(0.0);
00289     }
00290 }
00291 
00292 // ######################################################################
00293 inline
00294 void SimLayer::initialize()
00295 {
00296  itsT = SimTime::ZERO();
00297  itsSampScale = 1;
00298  itsInpExc.clear(0.0);
00299  itsInpInh.clear(0.0);
00300  itsOutput.clear(0.0);
00301  doInit();
00302 }
00303 
00304 // ######################################################################
00305 inline
00306 const SimTime SimLayer::getTime() const
00307 {
00308   return itsT;
00309 }
00310 
00311 // ######################################################################
00312 inline
00313 void SimLayer::setTime(const SimTime& time, const bool recurse)
00314 {
00315   itsT = time;
00316   if (recurse)
00317     for (uint ii = 0; ii < numSubs(); ++ii)
00318       editSub(ii).setTime(time);
00319 }
00320 
00321 // ######################################################################
00322 inline
00323 const SimTime SimLayer::getTimeStep() const
00324 {
00325   return itsTimeStep;
00326 }
00327 
00328 #endif
00329 // ######################################################################
00330 /* So things look consistent in everyone's emacs... */
00331 /* Local Variables: */
00332 /* indent-tabs-mode: nil */
00333 /* End: */
Generated on Sun May 8 08:41:01 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3