Location.H

Go to the documentation of this file.
00001 /*!@file ModelNeuron/Location.H Class to represent a location in a
00002    StrucureModule or Layer. */
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/Location.H $
00036 
00037 
00038 #ifndef MODELNEURON_LOCATION_H_DEFINED
00039 #define MODELNEURON_LOCATION_H_DEFINED
00040 
00041 #ifdef INVT_USE_CPPOX//we need c++ 0X features for this to work
00042 #include "Util/log.H"
00043 #include <vector>
00044 
00045 // ######################################################################
00046 // a class to represent a N-D location in a Structure or layer
00047 //
00048 // This class represents an N-D location stired as an integer. One of the dimensions can be
00049 // 'Location::ALL', which will indicate that we want to represent all elements
00050 // along that dimension. 
00051 
00052 // clean me up
00053 // we assume that the point lives in an N-D hypercube, we can also set the dimensions of this hypercube so that we can get a linear index to the position. 
00054 // ######################################################################
00055 class Location 
00056 {
00057 public:
00058   //to represent every location
00059   enum {ALL = -1, NONE = -1};
00060   
00061   //!default constructor
00062   Location();
00063   
00064   //!set Location for various dimensions from constructor
00065   template <typename... NDPoint>
00066   Location(const NDPoint... dims);
00067   
00068   //!set Location for from a vector
00069   Location(const std::vector<int>& pos);
00070     
00071   //!destructor
00072   ~Location();
00073   
00074   //!get the number of dimensions
00075   const size_t size() const;
00076   
00077   //!get the value at N'th pos
00078   const int getDim(const uint pos) const;
00079   
00080   //!set/reset the position of the location
00081   template <typename... Dims>
00082   void setLocation(const Dims... dims);
00083 
00084   //!set Location for from a vector
00085   void setLocation(const std::vector<int>& pos);
00086 
00087   //!set Location for from a vector, but not the dimensions
00088   void setLocation(const Location& loc);
00089   
00090   //!get the positions in a linear format
00091   const std::vector<int>& getLinearPos();
00092 
00093   //!get the positions in a linear format given the dimensions of the hypercube
00094   //!in which the location exists
00095   template <typename... Dims>
00096   const std::vector<int>& getLinearPos(const Dims... dims);
00097 
00098   //!set the dimensions ahead of time to precompute positions
00099   template <typename... Dims>
00100   void setHyperCubeDims(const Dims... dims);
00101 
00102   //!set the dimensions ahead of time to precompute positions
00103   void setHyperCubeDims(const std::vector<int>& hypercubedims);
00104 
00105   //are we equal?
00106   bool operator==(const Location& rhs);  
00107 private:
00108   //compute the linear position given the dimensions
00109   void computePos();
00110 
00111   //add the dims
00112   template <typename Head, typename... Tail> 
00113   bool add(std::vector<int>& vector, const bool allow_neg, uint count, const Head head, const Tail... tail);
00114   bool add(std::vector<int>& vector, const bool allow_neg, uint count) { return false; };//base case in recursion
00115 
00116   //add the dims as a vector
00117   bool addVector(std::vector<int>& vector, const bool allow_neg, const std::vector<int>& dims);
00118 
00119   //assign, and return true if there was a change
00120   bool assign(const std::vector<int>& src, std::vector<int>& dst);
00121 
00122   std::vector<int> itsLocation, itsHyperCube, itsLinearPos;
00123   int itsFreeDim;
00124 };
00125 
00126 // ######################################################################
00127 // implementation of location
00128 // ######################################################################
00129 Location::Location() :itsLocation(), itsHyperCube(), itsLinearPos(), itsFreeDim(Location::NONE)
00130 { }
00131 
00132 // ######################################################################
00133 template <typename... Dims> 
00134 Location::Location(const Dims... dims) : itsLocation(), itsHyperCube(), itsLinearPos(), itsFreeDim(Location::NONE)
00135 { 
00136   add(itsLocation, true, 0, dims...);
00137 }
00138 
00139 // ######################################################################
00140 Location::Location(const std::vector<int>& pos) : itsLocation(), itsHyperCube(), itsLinearPos(), itsFreeDim(Location::NONE)
00141 {
00142   addVector(itsLocation, true, pos);
00143 }
00144 
00145 // ######################################################################
00146 bool Location::operator==(const Location& rhs) 
00147 { 
00148   return ( (itsLocation == rhs.itsLocation) && 
00149            (itsHyperCube == rhs.itsHyperCube) && 
00150            (itsLinearPos == rhs.itsLinearPos) );
00151 };
00152 
00153 // ######################################################################
00154 Location::~Location() { };
00155 
00156 // ######################################################################
00157 const size_t Location::size() const { return itsLocation.size(); }
00158 
00159 // ######################################################################
00160 const int Location::getDim(const uint pos) const {return itsLocation[pos]; }
00161 
00162 // ######################################################################
00163 template <typename... Dims> 
00164 void Location::setLocation(const Dims... dims)
00165 {
00166   itsLocation.resize(0);
00167   itsFreeDim = Location::NONE;
00168   if (add(itsLocation, true, 0, dims...) && (itsLocation.size() > 0) && (itsHyperCube.size() > 0))
00169     computePos();
00170 }
00171 
00172 // ######################################################################
00173 void Location::setLocation(const std::vector<int>& pos)
00174 {
00175   itsFreeDim = Location::NONE;
00176   if (addVector(itsLocation, true, pos) && (itsLocation.size() > 0) && (itsHyperCube.size() > 0))
00177     computePos();
00178 }
00179 
00180 // ######################################################################
00181 void Location::setLocation(const Location& loc)
00182 {
00183   itsFreeDim = loc.itsFreeDim;
00184   if (assign(loc.itsLocation, itsLocation) && (itsLocation.size() > 0) && (itsHyperCube.size() > 0))
00185     computePos();
00186 }
00187 
00188 // ######################################################################
00189 const std::vector<int>& Location::getLinearPos()
00190 {
00191   return itsLinearPos;
00192 }
00193 
00194 // ######################################################################
00195 template <typename... Dims> 
00196 const std::vector<int>& Location::getLinearPos(const Dims... dims)
00197 {
00198   setHyperCubeDims(dims...);
00199   return itsLinearPos;
00200 }
00201 
00202 // ######################################################################
00203 template <typename... Dims> 
00204 void Location::setHyperCubeDims(const Dims... dims)
00205 {
00206   std::vector<int> temp;
00207   add(temp, false, 0, dims...); 
00208   if (assign(temp, itsHyperCube) && (itsLocation.size() > 0) && (itsHyperCube.size() > 0))
00209     computePos();
00210 }
00211 
00212 // ######################################################################
00213 void Location::setHyperCubeDims(const std::vector<int>& hypercubedims)
00214 {
00215   if (assign(hypercubedims,itsHyperCube) && (itsLocation.size() > 0) && (itsHyperCube.size() > 0))
00216     computePos();
00217 }
00218 
00219 // ######################################################################
00220 void Location::computePos()
00221 {
00222   itsLinearPos.clear();
00223   const int dsize = (int)itsHyperCube.size();
00224   const int psize = (int)itsLocation.size();
00225 
00226   //make sure everything has the right dimensions  
00227   const int diff = dsize - psize;  
00228   const uint shortest = (diff < 0) ? dsize : psize;
00229 
00230   const bool invalid = (diff < 0) ? diff * -1 > 2 : diff  > 2;
00231   if (invalid || ( (diff > 0) && (itsFreeDim != Location::NONE) ))
00232     LFATAL("HyperCube dimensions and location position mismatch");
00233   
00234   //get cumulative product of dimensions 
00235   uint dims[dsize]; dims[0] = 1;
00236   for (int c = 0; c < dsize-1; ++c)
00237     dims[c+1] = itsHyperCube[c]*dims[c];
00238   
00239   //if the point is fewer dims than the space it lives in, 
00240   //just travel along the dims in face of the space in common
00241   //if the point has more dims than the space it lives in,
00242   //the cut the extra dims
00243   if ( (itsFreeDim < 0) || (itsFreeDim >= (int)itsHyperCube.size()) )//no freedims
00244     {
00245       uint pos = 0;
00246       for (uint c = 0; c < shortest; ++c)
00247         if (itsLocation[c] < itsHyperCube[c])
00248           pos += itsLocation[c]*dims[c];
00249         else 
00250           LFATAL("Location out of dimensions");
00251       
00252       itsLinearPos.push_back(pos);
00253     }
00254   else 
00255     {
00256       //loop over all positions in that dimension
00257       for (int i = 0; i < itsHyperCube[itsFreeDim]; ++i)
00258         {
00259           //convert everything to 1d representation
00260           uint pos = 0;
00261           for (uint c = 0; c < shortest; ++c)
00262             if (itsLocation[c] < itsHyperCube[c])
00263               pos += (c == (uint)itsFreeDim) ? i*dims[c] : itsLocation[c]*dims[c];
00264             else 
00265               LFATAL("Location out of dimensions");
00266           
00267           itsLinearPos.push_back(pos);
00268         }
00269     }    
00270 }
00271 
00272 // ######################################################################
00273 bool Location::addVector(std::vector<int>& vector, const bool allow_neg, const std::vector<int>& dims)
00274 {
00275   bool change = false;
00276   std::vector<int>::const_iterator iter(dims.begin());
00277   const uint end = vector.size();
00278   uint count = 0;
00279   while (iter != dims.end())
00280     {
00281       //fail if out of range
00282       if (!allow_neg && (*iter < 0) && (*iter > -2))
00283         LFATAL("cannot have negative dimensions.");
00284       
00285       //make sure we are not aleady set a free dim before setting a matched one
00286       if (*iter == Location::ALL) {
00287         if (itsFreeDim != Location::NONE)
00288           LFATAL("cannot have more than one dimension in the Location as free.");
00289           
00290         itsFreeDim = count;
00291       }
00292       
00293       if (count < end) {//if we are an existing vector check for equality
00294         if (vector[count] != *iter){
00295           change = true;
00296           vector[count] = *iter;
00297         }
00298       }
00299       else {//otherwise push back a new item
00300         vector.push_back(*iter);
00301         change = true;
00302       }
00303       
00304       ++count;
00305       ++iter;
00306     }
00307   return change;
00308 }
00309 
00310 // ######################################################################
00311 template <typename Head, typename... Tail> 
00312 bool Location::add(std::vector<int>& vector, const bool allow_neg, uint count, const Head head, const Tail... tail)
00313 {
00314   //check for validity of value
00315   if (!allow_neg && (head < 0) && ((int)head > -2))
00316     LFATAL("cannot have negative dimensions.");
00317   
00318   //check for free dims
00319   if ((int)head == Location::ALL) {
00320     if (itsFreeDim != Location::NONE)
00321       LFATAL("cannot have more than one dimension in the Location as free.");
00322     
00323     itsFreeDim = count;
00324   }
00325 
00326   bool change = false;
00327   if (count < vector.size()) {//if we are an existing vector, check if the values are equal
00328     if (vector[count] != (int)head) {
00329       change = true;
00330       vector[count] = head;
00331     }
00332   }
00333   else {//else push it to the back
00334     vector.push_back(head);
00335     change = true;
00336   }
00337 
00338   const bool didchange = add(vector, allow_neg, ++count, tail...);
00339   return (didchange) ? true : change;
00340 }
00341 
00342 // ######################################################################
00343 bool Location::assign(const std::vector<int>& src, std::vector<int>& dst)
00344 {
00345   bool change = false;
00346   if (src.size() != dst.size())
00347     {
00348       dst = src;
00349       change = true;
00350     }
00351   else
00352     {
00353       std::vector<int>::const_iterator srciter(src.begin());
00354       std::vector<int>::iterator dstiter(dst.begin());
00355       while (srciter != src.end())
00356         {
00357           if (*srciter != *dstiter)
00358             change = true;
00359           
00360           *dstiter++ = *srciter++;
00361         }
00362     }
00363   return change;
00364 }
00365 
00366 // ######################################################################
00367 // free functions
00368 // ######################################################################
00369 //! format is "<int>,<int>"
00370 std::string convertToString(const Location& val);
00371 
00372 //! format is "<int>,<int>"
00373 void convertFromString(const std::string& str, Location& val);
00374 
00375 #endif
00376 #endif
00377 // ######################################################################
00378 /* So things look consistent in everyone's emacs... */
00379 /* Local Variables: */
00380 /* indent-tabs-mode: nil */
00381 /* End: */
Generated on Sun May 8 08:05:21 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3