• Main Page
  • Classes
  • Files
  • File List
  • File Members

chaincon/comblinmap.h

Go to the documentation of this file.
00001 /////////////////////////////////////////////////////////////////////////////
00002 ///
00003 /// \file
00004 ///
00005 /// A combinatorial linear map (for coefficients in Z_2).
00006 ///
00007 /////////////////////////////////////////////////////////////////////////////
00008 
00009 // Copyright (C) 2009-2011 by Pawel Pilarczyk.
00010 //
00011 // This file is part of my research software package. This is free software:
00012 // you can redistribute it and/or modify it under the terms of the GNU
00013 // General Public License as published by the Free Software Foundation,
00014 // either version 3 of the License, or (at your option) any later version.
00015 //
00016 // This software is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU General Public License
00022 // along with this software; see the file "license.txt". If not,
00023 // please, see <http://www.gnu.org/licenses/>.
00024 
00025 // Started on March 24, 2009. Last revision: March 6, 2011.
00026 
00027 
00028 #ifndef _CHAINCON_COMBLINMAP_H_
00029 #define _CHAINCON_COMBLINMAP_H_
00030 
00031 
00032 // include some standard C++ header files
00033 #include <istream>
00034 #include <ostream>
00035 
00036 // include selected header files from the CHomP library
00037 #include "chomp/system/config.h"
00038 #include "chomp/struct/hashsets.h"
00039 #include "chomp/struct/multitab.h"
00040 
00041 // include relevant local header files
00042 #include "chaincon/combchain.h"
00043 #include "chaincon/combtensor.h"
00044 
00045 
00046 // --------------------------------------------------
00047 // ------------ combinatorial linear map ------------
00048 // --------------------------------------------------
00049 
00050 /// A combinatorial linear map.
00051 /// This is in fact a finite set of cells mapped to a chain each.
00052 /// It corresponds to a linear map on the vector space
00053 /// generated by the cells over the coefficients field F_2 (a.k.a. Z_2).
00054 template <class CellDomT, class CellImgT>
00055 class tCombLinMap
00056 {
00057 public:
00058         /// The type of cells in the domain of the combinatorial linear map.
00059         typedef CellDomT CellDomType;
00060 
00061         /// The type of cells in the images of the combinatorial linear map.
00062         typedef CellImgT CellImgType;
00063 
00064         /// The default constructor.
00065         tCombLinMap ();
00066 
00067         /// Adds a cell to the image of the given cell.
00068         void add (const CellDomT &c, const CellImgT &d);
00069 
00070         /// Adds a chain to the image of the given cell.
00071         void add (const CellDomT &c, const tCombChain<CellImgT> &ch);
00072 
00073         /// Adds another map to the given map.
00074         void add (const tCombLinMap<CellDomT,CellImgT> &f);
00075 
00076         /// Removes the given cell from the domain of the map.
00077         /// Note that this may change the order of cells in the domain.
00078         void removenum (int_t n);
00079 
00080         /// Removes the given cell from the domain of the map.
00081         /// Note that this may change the order of cells in the domain.
00082         void remove (const CellDomT &c);
00083 
00084         /// Returns the image of the given cell.
00085         const tCombChain<CellImgT> &operator () (int_t n) const;
00086 
00087         /// Returns the image of the given cell.
00088         tCombChain<CellImgT> operator () (const CellDomT &c) const;
00089 
00090         /// Computes the image of the given chain.
00091         tCombChain<CellImgT> operator ()
00092                 (const tCombChain<CellDomT> &ch) const;
00093 
00094         /// Computes the image of the given tensor.
00095         tCombTensor<CellImgT> operator ()
00096                 (const tCombTensor<CellDomT> &ch) const;
00097 
00098         /// Returns the number of elements in the domain
00099         /// of the combinatorial map. Note that the images
00100         /// of some of the elements might be zero.
00101         int_t size () const;
00102 
00103         /// Returns the n-th element of the domain of the combinatorial map.
00104         const CellDomT &operator [] (int_t n) const;
00105 
00106         /// Returns the image of the given cell for editing.
00107         tCombChain<CellImgT> &getImage (int_t n);
00108 
00109         /// Returns the image of the given cell for editing.
00110         tCombChain<CellImgT> &getImage (const CellDomT &c);
00111 
00112         /// Verifies if the two combinatorial linear map are the same.
00113         bool operator == (const tCombLinMap<CellDomT,CellImgT> &f) const;
00114 
00115         /// Swaps the data with another combinatorial linear map.
00116         void swap (tCombLinMap<CellDomT,CellImgT> &f);
00117 
00118 private:
00119         /// The domain of the map.
00120         chomp::homology::hashedset<CellDomT> domain;
00121 
00122         /// The chains in the images of each domain element.
00123         chomp::homology::multitable<tCombChain<CellImgT> > images;
00124 
00125 }; /* class tCombLinMap */
00126 
00127 // --------------------------------------------------
00128 
00129 template <class CellDomT, class CellImgT>
00130 inline tCombLinMap<CellDomT,CellImgT>::tCombLinMap ():
00131         domain (1000), images (256)
00132 {
00133         return;
00134 } /* tCombLinMap::tCombLinMap */
00135 
00136 template <class CellDomT, class CellImgT>
00137 inline void tCombLinMap<CellDomT,CellImgT>::add
00138         (const CellDomT &c, const CellImgT &d)
00139 {
00140         int_t n = domain. getnumber (c);
00141         if (n < 0)
00142         {
00143                 n = domain. size ();
00144                 domain. add (c);
00145         }
00146         images [n]. add (d);
00147         return;
00148 } /* tCombLinMap::add */
00149 
00150 template <class CellDomT, class CellImgT>
00151 inline void tCombLinMap<CellDomT,CellImgT>::add
00152         (const CellDomT &c, const tCombChain<CellImgT> &ch)
00153 {
00154         int_t n = domain. getnumber (c);
00155         if (n < 0)
00156         {
00157                 n = domain. size ();
00158                 domain. add (c);
00159         }
00160         images [n]. add (ch);
00161         return;
00162 } /* tCombLinMap::add */
00163 
00164 template <class CellDomT, class CellImgT>
00165 inline void tCombLinMap<CellDomT,CellImgT>::add
00166         (const tCombLinMap<CellDomT,CellImgT> &f)
00167 {
00168         int_t size = f. domain. size ();
00169         for (int_t i = 0; i < size; ++ i)
00170         {
00171                 if (f. images [i]. empty ())
00172                         continue;
00173                 this -> add (f. domain [i], f. images [i]);
00174         }
00175         return;
00176 } /* tCombLinMap::add */
00177 
00178 template <class CellDomT, class CellImgT>
00179 inline void tCombLinMap<CellDomT,CellImgT>::removenum (int_t n)
00180 {
00181         domain. removenum (n);
00182         tCombChain<CellImgT> empty;
00183         images [n] = empty;
00184         if (n != domain. size ())
00185                 images [n]. swap (images [domain. size ()]);
00186         return;
00187 } /* tCombLinMap::removenum */
00188 
00189 template <class CellDomT, class CellImgT>
00190 inline void tCombLinMap<CellDomT,CellImgT>::remove (const CellDomT &c)
00191 {
00192         int_t n = domain. getnumber (c);
00193         if (n >= 0)
00194                 removenum (n);
00195         return;
00196 } /* tCombLinMap::remove */
00197 
00198 template <class CellDomT, class CellImgT>
00199 inline const tCombChain<CellImgT> &
00200         tCombLinMap<CellDomT,CellImgT>::operator () (int_t n) const
00201 {
00202         return images [n];
00203 } /* tCombLinMap::operator () */
00204 
00205 template <class CellDomT, class CellImgT>
00206 inline tCombChain<CellImgT> tCombLinMap<CellDomT,CellImgT>::operator ()
00207         (const CellDomT &c) const
00208 {
00209         int_t n = domain. getnumber (c);
00210         if (n >= 0)
00211                 return images [n];
00212         else
00213                 return tCombChain<CellImgT> ();
00214 } /* tCombLinMap::operator () */
00215 
00216 template <class CellDomT, class CellImgT>
00217 inline tCombChain<CellImgT> tCombLinMap<CellDomT,CellImgT>::operator ()
00218         (const tCombChain<CellDomT> &ch) const
00219 {
00220         tCombChain<CellImgT> image;
00221         int_t size = ch. size ();
00222         for (int_t i = 0; i < size; ++ i)
00223         {
00224                 int_t n = domain. getnumber (ch [i]);
00225                 if (n >= 0)
00226                         image. add (images [n]);
00227         }
00228         return image;
00229 } /* tCombLinMap::operator () */
00230 
00231 template <class CellDomT, class CellImgT>
00232 inline tCombTensor<CellImgT> tCombLinMap<CellDomT,CellImgT>::operator ()
00233         (const tCombTensor<CellDomT> &ch) const
00234 {
00235         tCombTensor<CellImgT> image;
00236         int_t size = ch. size ();
00237         for (int_t i = 0; i < size; ++ i)
00238         {
00239                 int_t n1 = domain. getnumber (ch. left (i));
00240                 int_t n2 = domain. getnumber (ch. right (i));
00241                 if ((n1 >= 0) && (n2 >= 0))
00242                         image. add (images [n1], images [n2]);
00243         }
00244         return image;
00245 } /* tCombLinMap::operator () */
00246 
00247 template <class CellDomT, class CellImgT>
00248 inline int_t tCombLinMap<CellDomT,CellImgT>::size () const
00249 {
00250         return domain. size ();
00251 } /* tCombLinMap::size */
00252 
00253 template <class CellDomT, class CellImgT>
00254 inline const CellDomT &tCombLinMap<CellDomT,CellImgT>::operator []
00255         (int_t n) const
00256 {
00257         return domain [n];
00258 } /* tCombLinMap::operator [] */
00259 
00260 template <class CellDomT, class CellImgT>
00261 inline tCombChain<CellImgT> &tCombLinMap<CellDomT,CellImgT>::getImage
00262         (int_t n)
00263 {
00264         return images [n];
00265 } /* tCombLinMap::getImage */
00266 
00267 template <class CellDomT, class CellImgT>
00268 inline tCombChain<CellImgT> &tCombLinMap<CellDomT,CellImgT>::getImage
00269         (const CellDomT &c)
00270 {
00271         int_t n = domain. getnumber (c);
00272         if (n < 0)
00273         {
00274                 n = domain. size ();
00275                 domain. add (c);
00276         }
00277         return images [n];
00278 } /* tCombLinMap::getImage */
00279 
00280 template <class CellDomT, class CellImgT>
00281 inline bool tCombLinMap<CellDomT,CellImgT>::operator ==
00282         (const tCombLinMap<CellDomT,CellImgT> &f) const
00283 {
00284         int_t thisSize = domain. size ();
00285         for (int_t i = 0; i < thisSize; ++ i)
00286         {
00287                 const CellDomT &x = domain [i];
00288                 const tCombChain<CellImgT> &y = images [i];
00289                 if (y. empty ())
00290                         continue;
00291                 int_t n = f. domain. getnumber (x);
00292                 if (n < 0)
00293                         return false;
00294                 if (!(y == f. images [n]))
00295                         return false;
00296         }
00297         int_t fSize = f. domain. size ();
00298         for (int_t i = 0; i < fSize; ++ i)
00299         {
00300                 const CellDomT &x = f. domain [i];
00301                 const tCombChain<CellImgT> &y = f. images [i];
00302                 if (y. empty ())
00303                         continue;
00304                 int_t n = domain. getnumber (x);
00305                 if (n < 0)
00306                         return false;
00307                 if (!(y == images [n]))
00308                         return false;
00309         }
00310         return true;
00311 } /* tCombLinMap::operator == */
00312 
00313 template <class CellDomT, class CellImgT>
00314 inline void tCombLinMap<CellDomT,CellImgT>::swap
00315         (tCombLinMap<CellDomT,CellImgT> &f)
00316 {
00317         domain. swap (f. domain);
00318         images. swap (f. images);
00319         return;
00320 } /* tCombLinMap::swap */
00321 
00322 // --------------------------------------------------
00323 
00324 /// Writes a combinatorial linear map to an output stream in the text mode.
00325 template <class CellDomT, class CellImgT>
00326 inline std::ostream &operator << (std::ostream &out,
00327         const tCombLinMap<CellDomT,CellImgT> &f)
00328 {
00329         int_t size = f. size ();
00330         for (int_t n = 0; n < size; ++ n)
00331         {
00332                 const tCombChain<CellImgT> &ch = f (n);
00333                 if (ch. empty ())
00334                         continue;
00335                 const CellDomT &c = f [n];
00336                 out << c << " -> " << ch << "\n";
00337         }
00338         return out;
00339 } /* operator << */
00340 
00341 /// Reads a combinatorial linear map from an input stream.
00342 template <class CellDomT, class CellImgT>
00343 inline std::istream &operator >> (std::istream &in,
00344         tCombLinMap<CellDomT,CellImgT> &f)
00345 {
00346         throw "Operator >> not implemented for tCombLinMap.";
00347         return in;
00348 } /* operator >> */
00349 
00350 // --------------------------------------------------
00351 
00352 /// Adds the identity map on the given domain to the map 'f'.
00353 template <class CellArray, class CellT>
00354 inline void addIdentity (const CellArray &domain,
00355         tCombLinMap<CellT,CellT> &f)
00356 {
00357         int_t size = domain. size ();
00358         for (int_t i = 0; i < size; ++ i)
00359         {
00360                 const CellT &c = domain [i];
00361                 f. add (c, c);
00362         }
00363         return;
00364 } /* addIdentity */
00365 
00366 /// Returns the identity map on the given domain.
00367 template <class CellArray, class CellT>
00368 inline tCombLinMap<CellT,CellT> identity (const CellArray &domain)
00369 {
00370         tCombLinMap<CellT,CellT> f;
00371         f. addIdentity (domain);
00372         return f;
00373 } /* identity */
00374 
00375 /// Computes the full boundary map for a cellular complex that contains
00376 /// the cells in a provided set and all their boundary cells.
00377 /// The map is assumed to be initially zero.
00378 template <class CellArray, class CellT>
00379 inline void computeBoundaryMap (const CellArray &cells,
00380         tCombLinMap<CellT,CellT> &f)
00381 {
00382         // prepare a set of cells whose boundaries yet have to be computed
00383         chomp::homology::hashedset<CellT> waiting;
00384 
00385         // process all the cells in the domain of the map
00386         // (note that the domain may increase during this process)
00387         int_t inputCellNumber = 0;
00388         const int_t inputCellCount = cells. size ();
00389         while (1)
00390         {
00391                 // determine whether a cell from the array should be used
00392                 bool useInput = (inputCellNumber < inputCellCount);
00393 
00394                 // if the input array has been used and the set
00395                 // of wating cells as well then exit the loop
00396                 if (!useInput && waiting. empty ())
00397                         break;
00398 
00399                 // take a cell for processing
00400                 int_t waitingPosition = waiting. size () - 1;
00401                 const CellT &c = useInput ? cells [inputCellNumber] :
00402                         waiting [waitingPosition];
00403 
00404                 // determine the length of the boundary of this cell
00405                 int length = c. boundaryLength ();
00406 
00407                 // process all the cells in its boundary
00408                 for (int b = 0; b < length; ++ b)
00409                 {
00410                         // create the subsequent boundary cell
00411                         CellT bc (c, b);
00412 
00413                         // add the boundary cell to the waiting list
00414                         if (bc. boundaryLength () &&
00415                                 f. getImage (bc). empty ())
00416                         {
00417                                 waiting. add (bc);
00418                         }
00419 
00420                         // add the boundary cell to the image of 'c'
00421                         f. add (c, bc);
00422                 }
00423 
00424                 // increase the counter of cells in the input array
00425                 if (useInput)
00426                         ++ inputCellNumber;
00427 
00428                 // or remove the waiting cell which was taken
00429                 else
00430                         waiting. removenum (waitingPosition);
00431         }
00432         return;
00433 } /* computeBoundaryMap */
00434 
00435 /// Computes the composition of the two given maps.
00436 /// More precisely, for each x in the domain of g,
00437 /// the new map on x is defined as f(g(x)).
00438 template <class CellXT, class CellYT, class CellZT>
00439 inline tCombLinMap<CellXT,CellZT> operator *
00440         (const tCombLinMap<CellYT,CellZT> &f,
00441         const tCombLinMap<CellXT,CellYT> &g)
00442 {
00443         tCombLinMap<CellXT,CellZT> result;
00444         int_t size = g. size ();
00445         for (int_t i = 0; i < size; ++ i)
00446         {
00447                 const CellXT &x = g [i];
00448                 const tCombChain<CellYT> &y = g (i);
00449                 const tCombChain<CellZT> z = f (y);
00450                 if (z. empty ())
00451                         continue;
00452                 result. add (x, z);
00453         }
00454         return result;
00455 } /* operator * */
00456 
00457 
00458 #endif // _CHAINCON_COMBLINMAP_H_
00459 

Generated on Tue Apr 5 2011 00:06:32 for Chain Contraction Software by  doxygen 1.7.2