Structure.H

Go to the documentation of this file.
00001 /*!@file ModelNeuron/Structure.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/Structure.H $
00036 
00037 #ifndef MODELNEURON_STRUCTURE_H_DEFINED
00038 #define MODELNEURON_STRUCTURE_H_DEFINED
00039 
00040 #include "Util/SimTime.H"
00041 #include "Image/ImageSet.H"
00042 #include "Image/ImageSetOps.H"
00043 #include "ModelNeuron/SimStructure.H"
00044 #include "ModelNeuron/SimUnit.H"
00045 #include "ModelNeuron/NeuralSimUtils.H"
00046 
00047 class StructurePlot;
00048 class Location;
00049 // ######################################################################
00050 //  Structure
00051 //  ######################################################################
00052 //  A SimStructure which is a collection of SimStructures. Derive from this
00053 //  class and use addmodule to set up the structure and and override interact to
00054 //  implement interactions between sub modules.
00055 //
00056 //  when using the getSimUnit and editSimUnit functions, the N-D location 
00057 //  argument is interpreted as the position in a 3-D volume, where the 
00058 //  third dimensions is the sub module number. This recursivly dives down
00059 //  sub modules so the return vector may have many units if the structure's
00060 //  sub modules have sub modules. 
00061 //
00062 //  if not all the layers of the exact same type, then derive from or use
00063 //  Structure<SimStructure*> which will inact the virtual mode
00064 //
00065 // The second template paramter is the return type fo the access functions, this
00066 // could be the same type as T, or any base class of T, or SimStruture base.
00067 //  ######################################################################
00068 template <class T>
00069 class Structure : public SimStructure
00070 {
00071 public:
00072   //! constructor
00073   Structure(const SimTime& timeStep, const uint w = 40, const uint h = 30, 
00074             const std::string name = "", const std::string units = "");
00075   
00076   //!default assignment and copy constructor OK
00077 
00078   virtual ~Structure() { };
00079 
00080   //!set the input
00081   void input(const Image<double>& in, const int pos = -1);
00082 
00083   //!set the input
00084   void inputExc(const Image<double>& in, const int pos = -1);
00085 
00086   //!set the input
00087   void inputInh(const Image<double>& in, const int pos = -1);
00088   
00089   //!get the current output
00090   virtual Image<double> getOutput(const int pos = -1) const;
00091   
00092   //!get the current display output 
00093   virtual Image<double> getDisplayOutput(const int pos = -1) const;
00094 
00095   //!set the default input and output modules
00096   void setDefaultIO(const uint input_pos, const uint output_pos);
00097   
00098   //!evolve up to specified time
00099   void evolve(const SimTime& simtime);
00100 
00101   //!reset/initialize
00102    void initialize();
00103 
00104   //!get unit(s) at desired location
00105   void getSimUnit(const Location& loc, std::vector<const SimUnit*>& units);
00106   
00107   //!edit unit(s) at the desired output position
00108   void editSimUnit(const Location& loc, std::vector<SimUnit*>& units);
00109   
00110   //set the current time
00111   void setTime(const SimTime& time, const bool recursive = true);
00112 
00113   //get the number of sub modules
00114   const uint numSubs() const;
00115   
00116   //get a referene to a sub module const version
00117   const typename nsu::TypeTraits<T>::PointeeType& getSub(const uint sub) const;
00118   
00119   //!get the unit at desired position mutable version
00120   typename nsu::TypeTraits<T>::PointeeType& editSub(const uint pos);
00121 
00122   //get the simulation time
00123   const SimTime getTime() const;
00124 
00125   //get the simulation time step
00126   const SimTime getTimeStep() const;
00127 
00128   //!clone the module
00129   virtual Structure* clone() const = 0;
00130 
00131 protected:
00132   //protect copy and asignment, use clone
00133   Structure(const Structure<T>& nlc);
00134   Structure<T>& operator=(const Structure<T>& nlc);
00135   
00136   //!add a sub module
00137   void addSub(const typename nsu::TypeTraits<T>::PointeeType& structure);
00138   
00139 private:
00140   //do our class specific interactions
00141   virtual void interact() = 0;
00142   
00143   //do any class specific inititialization;
00144   virtual void doInit() { };
00145   
00146   int itsInpPos, itsOutPos;
00147   nsu::vector<T> itsSubs;
00148   ImageSet<double> itsInpExc, itsInpInh;
00149   SimTime itsTimeStep, itsT;
00150   uint itsSampleScale;
00151   bool isSet;
00152 };
00153 
00154 // ######################################################################
00155 //!A class to derive from to create new Structures. New
00156 //Structure derived types can derive from this class to
00157 //inherit the doClone() function if desired. 
00158 /*
00159   Programmer Note: This class uses the 'quriously recursive template
00160   pattern' to simplify creation of new classes for the programmer. As
00161   such, to create a new simulation module, classes should adhear the
00162   following convention:
00163   
00164   class mymodule : public StructureDerived<mymodule>
00165   {
00166       mymodule(//params//) : Structure<mymodule>(//params//) { };
00167       //...rest of functions
00168   }
00169 */
00170 // ######################################################################
00171 template <class T, class Derived>
00172 class StructureDerived : public Structure<T>
00173 {
00174 protected:
00175   StructureDerived(const SimTime& timestep, const uint width, const uint height,
00176                    const std::string name = "", const std::string units = "") : 
00177     Structure<T>(timestep, width, height, name, units) { };
00178   
00179   virtual ~StructureDerived() { };
00180   
00181 private:
00182   Derived* clone() const { return new Derived(dynamic_cast<const Derived&>(*this)); }
00183 };
00184 
00185 // ######################################################################
00186 // Structure implementation
00187 // ######################################################################
00188 template <class T>
00189 Structure<T>::Structure(const SimTime& timestep,const uint w, const uint h, 
00190                         const std::string name, const std::string units) :
00191   SimStructure(w, h, name, units), itsInpPos(-1), itsOutPos(-1), itsSubs(),
00192   itsInpExc(), itsInpInh(),
00193   itsTimeStep(timestep), itsT(SimTime::ZERO()), itsSampleScale(1), isSet(false)
00194 { }
00195 
00196 // ######################################################################
00197 template <class T>
00198 Structure<T>::Structure(const Structure<T>& rhs) : SimStructure(rhs), itsInpPos(rhs.itsInpPos), 
00199                                                    itsOutPos(rhs.itsOutPos), itsSubs(rhs.itsSubs),
00200                                                    itsInpExc(rhs.itsInpExc), itsInpInh(rhs.itsInpInh),
00201                                                    itsTimeStep(rhs.itsTimeStep), itsT(rhs.itsT), 
00202                                                    itsSampleScale(rhs.itsSampleScale), isSet(rhs.isSet)
00203 { }
00204 
00205 // ######################################################################
00206 template <class T>
00207 Structure<T>& Structure<T>::operator=(const Structure<T>& rhs)
00208 {
00209   if (this != &rhs)
00210     {
00211       SimStructure::operator=(rhs);
00212       itsInpPos = rhs.itsInpPos;
00213       itsOutPos = rhs.itsOutPos;
00214       itsSubs = rhs.itsSubs;
00215       itsInpExc = rhs.itsInpExc; 
00216       itsInpInh = rhs.itsInpInh;
00217       itsTimeStep = rhs.itsTimeStep; 
00218       itsT = rhs.itsT;
00219       itsSampleScale = rhs.itsSampleScale;
00220       isSet = rhs.isSet;
00221     }
00222   return *this;
00223 }
00224 
00225 // ######################################################################
00226 template <class T> 
00227 void Structure<T>::input(const Image<double>& in, const int pos)
00228 {   
00229   int p = (pos >= 0) ? pos : itsInpPos;
00230   
00231   if (p < (int)itsInpExc.size())
00232     SimStructure::splitExcInh(in, itsInpExc[p], itsInpInh[p]);
00233   else
00234     LFATAL("This Structure has no %d'th sub module", p);
00235 }
00236 
00237 // ######################################################################
00238 template <class T> 
00239 void Structure<T>::inputExc(const Image<double>& in, const int pos)
00240 { 
00241   int p = (pos >= 0) ? pos : itsInpPos;
00242   
00243   if (p < (int)itsInpExc.size())
00244     itsInpExc[p] = in;
00245   else
00246     LFATAL("This Structure has no %d'th sub module", p);
00247 }
00248 
00249 // ######################################################################
00250 template <class T> 
00251 void Structure<T>::inputInh(const Image<double>& in, const int pos)
00252 { 
00253   int p = (pos >= 0) ? pos : itsInpPos;
00254 
00255   if (p < (int)itsInpInh.size())
00256     itsInpInh[p] = in;
00257   else
00258     LFATAL("This Structure has no %d'th sub module", p);
00259 }
00260   
00261 // ######################################################################
00262 template <class T> 
00263 Image<double> Structure<T>::getOutput(const int pos) const
00264 {
00265   int p = (pos >= 0) ? pos : itsInpPos;
00266 
00267   if (p >= (int)numSubs())
00268     LFATAL("This Structure has no %d'th sub module", p);
00269   
00270   return itsSubs[p].getOutput();
00271 }
00272   
00273 // ######################################################################
00274 template <class T> 
00275 Image<double> Structure<T>::getDisplayOutput(const int pos) const
00276 {
00277   int p = (pos >= 0) ? pos : itsInpPos;
00278 
00279   if (p >= (int)numSubs())
00280     LFATAL("This Structure has no %d'th sub module", p);
00281   
00282   return itsSubs[p].getDisplayOutput();
00283 }
00284 
00285 // ######################################################################
00286 template <class T> 
00287 void Structure<T>::setDefaultIO(const uint input_pos, const uint output_pos)
00288 {
00289   itsInpPos = input_pos;
00290   itsOutPos = output_pos;
00291   if (getUnits().empty())
00292     setUnits(itsSubs[itsOutPos].getUnits());
00293   isSet = true;
00294 }
00295 
00296 // ######################################################################
00297 template <class T> 
00298 void Structure<T>::evolve(const SimTime& t)
00299 {
00300   const SimTime interval(t - itsT);
00301   const int64 nsteps = interval.nsecs() / itsTimeStep.nsecs();
00302   const int steps = (int)nsteps;  
00303   SimTime currTimeStep;
00304 
00305   if (steps <= 0)
00306     ++itsSampleScale;//keep track of how many times we don't integrate
00307   else
00308     {
00309       //set our current time step 
00310       currTimeStep = SimTime::NSECS(interval.nsecs() / nsteps);  
00311       
00312       if (itsSampleScale > 1)
00313         {      
00314           //rescale our inputs
00315           itsInpExc /= (double)itsSampleScale;
00316           itsInpInh /= (double)itsSampleScale;
00317           itsSampleScale = 1;
00318         }
00319       
00320       for (int ii = 0; ii < steps; ++ii)
00321         {      
00322           //update our current time
00323           itsT += currTimeStep;
00324 
00325           //do sub interactions
00326           interact();
00327           
00328           //pass the input around and evolve
00329           for (uint ii = 0; ii < numSubs(); ++ii)
00330             {
00331               itsSubs[ii].inputExc(itsInpExc[ii]);
00332               itsSubs[ii].inputInh(itsInpInh[ii]);
00333               itsSubs[ii].evolve(itsT);
00334             }
00335         }
00336       
00337       //reset our input after we evolve to the current time step
00338       for (uint ii = 0; ii < numSubs(); ++ii)
00339         {
00340           itsInpExc[ii].clear();
00341           itsInpInh[ii].clear();
00342         }
00343     }
00344 }
00345 
00346 // ######################################################################
00347 template <class T> 
00348 void Structure<T>::initialize()
00349 {
00350   itsT = SimTime::ZERO();
00351   
00352   typename nsu::vector<T>::iterator iter(itsSubs.begin());
00353   while (iter != itsSubs.end())
00354     (iter++)->initialize();
00355   
00356   doInit();
00357 }
00358 
00359 // ######################################################################
00360 template <class T> 
00361 void Structure<T>::setTime(const SimTime& time, const bool recursive)
00362 {
00363   itsT = time;
00364   for (uint ii = 0; ii < numSubs(); ++ii)
00365     editSub(ii).setTime(time);
00366 }
00367 
00368 // ######################################################################
00369 template <class T> 
00370 void Structure<T>::getSimUnit(const Location& loc, std::vector<const SimUnit*>& units)
00371 {
00372   //recurse through the subs, eventually someone will deal with it
00373   for (uint ii = 0; ii < numSubs(); ++ii)
00374     editSub(ii).getSimUnit(loc, units);
00375 }
00376   
00377 // ######################################################################
00378 template <class T> 
00379 void Structure<T>::editSimUnit(const Location& loc, std::vector<SimUnit*>& units) 
00380 {
00381   //recurse through the subs, eventually someone will deal with it
00382   for (uint ii = 0; ii < numSubs(); ++ii)
00383     editSub(ii).editSimUnit(loc, units);
00384 }
00385 
00386 // ######################################################################
00387 template <class T> 
00388 const uint Structure<T>::numSubs() const
00389 {
00390   return (uint)itsSubs.size();
00391 }
00392 
00393 // ######################################################################
00394 template <class T> 
00395 const typename nsu::TypeTraits<T>::PointeeType& Structure<T>::getSub(const uint sub) const
00396 {
00397   return itsSubs[sub];
00398 }
00399 
00400 // ######################################################################
00401 template <class T> 
00402 typename nsu::TypeTraits<T>::PointeeType& Structure<T>::editSub(const uint pos)
00403 {
00404   return itsSubs[pos];
00405 }
00406 
00407 // ######################################################################
00408 template <class T> 
00409 const SimTime Structure<T>::getTime() const
00410 {
00411   return itsT;
00412 }
00413 
00414 // ######################################################################
00415 template <class T> 
00416 const SimTime Structure<T>::getTimeStep() const
00417 {
00418   return itsTimeStep;
00419 }
00420 
00421 // ######################################################################
00422 template <class T> 
00423 void Structure<T>::addSub(const typename nsu::TypeTraits<T>::PointeeType& structure)
00424 {
00425   itsSubs.push_back(structure);
00426   itsInpExc.push_back(Image<double>(structure.getOutDims(), ZEROS));
00427   itsInpInh.push_back(Image<double>(structure.getOutDims(), ZEROS));
00428 
00429   if (~isSet)
00430     {
00431       itsInpPos = 0;
00432       ++itsOutPos;
00433       if (getUnits().empty())
00434         setUnits(itsSubs[itsOutPos].getUnits());
00435     }
00436 }
00437 
00438 #endif
00439 // ######################################################################
00440 /* So things look consistent in everyone's emacs... */
00441 /* Local Variables: */
00442 /* indent-tabs-mode: nil */
00443 /* End: */
Generated on Sun May 8 08:41:01 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3