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: */