WinnerTakeAllStdOptim.C

Go to the documentation of this file.
00001 /*!@file Neuro/WinnerTakeAllStdOptim.C Optimized version of WinnerTakeAllStd */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Neuro/WinnerTakeAllStdOptim.C $
00035 // $Id: WinnerTakeAllStdOptim.C 10729 2009-02-02 03:44:27Z itti $
00036 //
00037 
00038 #ifndef NEURO_WINNERTAKEALLSTDOPTIM_C_DEFINED
00039 #define NEURO_WINNERTAKEALLSTDOPTIM_C_DEFINED
00040 
00041 #include "Neuro/WinnerTakeAllStdOptim.H"
00042 
00043 #include "Util/JobWithSemaphore.H"
00044 #include "Util/MainJobServer.H"
00045 #include "rutz/trace.h"
00046 
00047 struct WinnerTakeAllStdOptim::EvolveJob : public JobWithSemaphore
00048 {
00049   EvolveJob(Image<float>::iterator vitr_,
00050             Image<float>::iterator vstop_,
00051             Image<float>::const_iterator initr_,
00052             const float ginput_,
00053             const float dt_c_,
00054             const float gsum_,
00055             const float isum_,
00056             const float Ei_,
00057             const float Vth_)
00058     :
00059     vitr(vitr_),
00060     vstop(vstop_),
00061     initr(initr_),
00062     ginput(ginput_),
00063     dt_c(dt_c_),
00064     gsum(gsum_),
00065     isum(isum_),
00066     Ei(Ei_),
00067     Vth(Vth_),
00068     vwinner()
00069   {}
00070 
00071   virtual ~EvolveJob()
00072   {}
00073 
00074   virtual void run()
00075   {
00076     while (vitr != vstop)
00077       {
00078         const float Iin = ginput * (*initr++);
00079 
00080         // Integrate :    all units MKSA
00081         (*vitr) += dt_c * (Iin - (*vitr) * gsum + isum);
00082 
00083         // Check if the potential is lower than Ei -> if so, then clamp:
00084         if ((*vitr) < Ei) (*vitr) = Ei;
00085 
00086         // Check if voltage has exceeded threshold -> if so, then fire:
00087         if ((*vitr) >= Vth) { vwinner = vitr; *vitr = 0.0F; }
00088 
00089         ++vitr;
00090       }
00091 
00092     this->markFinished();
00093   }
00094 
00095   virtual const char* jobType() const
00096   { return "WinnerTakeAllStdOptimEvolveJob"; }
00097 
00098   Image<float>::iterator vitr;
00099   Image<float>::iterator vstop;
00100   Image<float>::const_iterator initr;
00101   const float ginput;
00102   const float dt_c;
00103   const float gsum;
00104   const float isum;
00105   const float Ei;
00106   const float Vth;
00107   Image<float>::iterator vwinner;
00108 };
00109 
00110 // ######################################################################
00111 // ######################################################################
00112 // ########## WinnerTakeAllStdOptim implementation
00113 // ######################################################################
00114 // ######################################################################
00115 
00116 WinnerTakeAllStdOptim::WinnerTakeAllStdOptim(OptionManager& mgr,
00117                                              const std::string& descrName,
00118                                              const std::string& tagName) :
00119   WinnerTakeAllAdapter(mgr, descrName, tagName),
00120   itsTimeStep(SimTime::SECS(0.0001)),
00121   itsEl(0.0F),
00122   itsEe(100.0e-3F),
00123   itsEi(-20.0e-3F),
00124   itsC(1.0E-9F),
00125   itsVth(0.001F),
00126   itsV(),
00127   itsT(),
00128   itsGleak(1.0e-8F),
00129   itsGinh(1.0e-2F),
00130   itsGinput(5.0e-8F),
00131   itsGIN_Gl(1.0e-8F),       // in Siemens
00132   itsGIN_Ge(0.0F),          // in Siemens
00133   itsGIN_El(0.0F),          // in Volts
00134   itsGIN_Ee(100.0e-3F),     // in Volts
00135   itsGIN_Ei(-20.0e-3F),     // in Volts
00136   itsGIN_C(1.0E-9F),        // in Farads
00137   itsGIN_Vth(0.001F),       // in Volts
00138   itsGIN_V(itsGIN_Ei),
00139   itsInputCopy()
00140 {
00141 GVX_TRACE(__PRETTY_FUNCTION__);
00142 }
00143 
00144 // ######################################################################
00145 WinnerTakeAllStdOptim::~WinnerTakeAllStdOptim()
00146 {
00147 GVX_TRACE(__PRETTY_FUNCTION__);
00148 }
00149 
00150 // ######################################################################
00151 void WinnerTakeAllStdOptim::reset1()
00152 {
00153 GVX_TRACE(__PRETTY_FUNCTION__);
00154   itsV.freeMem();
00155   itsInputCopy.freeMem();
00156   itsT = SimTime::ZERO();
00157 
00158   WinnerTakeAllAdapter::reset1();
00159 }
00160 
00161 // ######################################################################
00162 void WinnerTakeAllStdOptim::input(const Image<float>& in)
00163 {
00164 GVX_TRACE(__PRETTY_FUNCTION__);
00165   if (itsV.initialized() == false)
00166     {
00167       // first input, let's initialize our array
00168       itsV.resize(in.getDims(), NO_INIT);
00169       itsV.clear(itsEi);
00170 
00171       itsGe = 0.0F;
00172       itsGi = itsGinh;
00173     }
00174 
00175   // keep a copy of the input for use in evolve():
00176   itsInputCopy = in;
00177 }
00178 
00179 // ######################################################################
00180 void WinnerTakeAllStdOptim::integrate(const SimTime& t, Point2D<int>& winner)
00181 {
00182 GVX_TRACE(__PRETTY_FUNCTION__);
00183   winner.i = -1;
00184 
00185   // the array of neurons receive excitatory inputs from outside.
00186   // here we update the inputs and let the neurons evolve
00187 
00188   // we run our difference equations with a time step of itsTimeStep;
00189   // let's here figure out how many iterations we will need to go from
00190   // itsT to t. We will iterate for a number of equal steps, with each
00191   // step as close to itsTimeStep as possible to that we end up at
00192   // time tt after iterating for an integer number of time steps:
00193   const SimTime dt = SimTime::computeDeltaT(t - itsT, itsTimeStep);
00194   const float dt_c = float(dt.secs()) / itsC;
00195 
00196   for (SimTime tt = itsT; tt < t; tt += dt)
00197     {
00198       if (tt == SimTime::ZERO())
00199         continue;
00200 
00201       ASSERT(dt != SimTime::ZERO());
00202 
00203       const float gsum = itsGleak + itsGe + itsGi;
00204       const float isum = itsGleak * itsEl + itsGe * itsEe + itsGi * itsEi;
00205 
00206       JobServer& srv = getMainJobServer();
00207 
00208       const unsigned int ntiles = srv.getParallelismHint();
00209 
00210       std::vector<rutz::shared_ptr<EvolveJob> > jobs;
00211 
00212       for (unsigned int i = 0; i < ntiles; ++i)
00213         {
00214           const int start = (i*itsV.getSize()) / ntiles;
00215           const int end = ((i+1)*itsV.getSize()) / ntiles;
00216 
00217           jobs.push_back
00218             (rutz::make_shared(new EvolveJob
00219                                (itsV.beginw() + start,
00220                                 itsV.beginw() + end,
00221                                 itsInputCopy.begin() + start,
00222                                 itsGinput,
00223                                 dt_c,
00224                                 gsum,
00225                                 isum,
00226                                 itsEi,
00227                                 itsVth)));
00228 
00229           srv.enqueueJob(jobs.back());
00230         }
00231 
00232       for (size_t i = 0; i < jobs.size(); ++i)
00233         {
00234           jobs[i]->wait();
00235 
00236           if (jobs[i]->vwinner != Image<float>::iterator())
00237             {
00238               const size_t offset = jobs[i]->vwinner - itsV.beginw();
00239               winner.i = offset % itsV.getWidth();
00240               winner.j = offset / itsV.getWidth();
00241 
00242               // we got a winner, so let's trigger the global inhibition:
00243               itsGIN_Ge = itsGleak * 10.0F;
00244             }
00245         }
00246 
00247       itsGe = 0.0F;
00248       itsGi = 0.0F;
00249 
00250       // when the global inhibition fires, it triggers inhibitory
00251       // conductances for one time step in the array of excited
00252       // neurons, shuts off excitatory conductances, and turns itself
00253       // off:
00254 
00255       // Integrate GIN
00256       const float dt_c2 = float(dt.secs()) / itsGIN_C;
00257 
00258       itsGIN_V += dt_c2 *
00259         (- itsGIN_Gl * (itsGIN_V - itsGIN_El)
00260          - itsGIN_Ge * (itsGIN_V - itsGIN_Ee));
00261 
00262       // Check if the GIN potential is lower than Ei -> if so, then clamp:
00263       if (itsGIN_V < itsGIN_Ei) itsGIN_V = itsGIN_Ei;
00264 
00265       // Check if GIN voltage has exceeded threshold -> if so, then fire:
00266       if (itsGIN_V >= itsGIN_Vth)
00267         {
00268           itsGIN_V = 0.0F;
00269           this->inhibit();
00270         }
00271     }
00272 
00273   // we are done, just keep track of new current time:
00274   itsT = t;
00275 }
00276 
00277 // ######################################################################
00278 Image<float> WinnerTakeAllStdOptim::getV() const
00279 {
00280 GVX_TRACE(__PRETTY_FUNCTION__);
00281   return itsV;
00282 }
00283 
00284 // ######################################################################
00285 void WinnerTakeAllStdOptim::inhibit()
00286 {
00287 GVX_TRACE(__PRETTY_FUNCTION__);
00288   itsGe = 0.0F;
00289   itsGi = itsGinh;
00290   itsGIN_Ge = 0.0F;
00291   LDEBUG("WTA inhibition firing...");
00292 }
00293 
00294 // ######################################################################
00295 void WinnerTakeAllStdOptim::saccadicSuppression(const bool on)
00296 {
00297 GVX_TRACE(__PRETTY_FUNCTION__);
00298   if (itsUseSaccadicSuppression.getVal() == false) return;
00299   if (on) inhibit();
00300   LINFO("------- WTA saccadic suppression %s -------", on ? "on":"off");
00301 }
00302 
00303 // ######################################################################
00304 void WinnerTakeAllStdOptim::blinkSuppression(const bool on)
00305 {
00306 GVX_TRACE(__PRETTY_FUNCTION__);
00307   if (itsUseBlinkSuppression.getVal() == false) return;
00308   if (on) inhibit();
00309   LINFO("------- WTA blink suppression %s -------", on ? "on":"off");
00310 }
00311 
00312 // ######################################################################
00313 /* So things look consistent in everyone's emacs... */
00314 /* Local Variables: */
00315 /* mode: c++ */
00316 /* indent-tabs-mode: nil */
00317 /* End: */
00318 
00319 #endif // NEURO_WINNERTAKEALLSTDOPTIM_C_DEFINED
Generated on Sun May 8 08:41:07 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3