algstruct.h

Go to the documentation of this file.
00001 
00002 
00003 
00014 
00015 // This file copyright (C) 1997-2010 by Pawel Pilarczyk.
00016 //
00017 // This file is part of the "chomp" program. It is free software;
00018 // you can redistribute it and/or modify it under the terms of the GNU
00019 // General Public License as published by the Free Software Foundation;
00020 // either version 2 of the License, or (at your option) any later version.
00021 //
00022 // This library is distributed in the hope that it will be useful,
00023 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025 // GNU General Public License for more details.
00026 //
00027 // You should have received a copy of the GNU General Public License along
00028 // with this software; see the file "license.txt".  If not, write to the
00029 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00030 // MA 02111-1307, USA.
00031 
00032 // Started in March 2006. Last revision: April 19, 2006.
00033 
00034 
00035 #ifndef _CAPD_HOMENGIN_ALGSTRUCT_H_ 
00036 #define _CAPD_HOMENGIN_ALGSTRUCT_H_ 
00037 
00038 #include "chomp/system/config.h"
00039 #include "chomp/system/textfile.h"
00040 #include "chomp/system/timeused.h"
00041 #include "chomp/system/arg.h"
00042 #include "chomp/homology/homtools.h"
00043 
00044 #include "capd/auxil/CRef.h"
00045 #include "capd/homologicalAlgebra/HomologySignature.h"
00046 
00047 #include <cstdlib>
00048 #include <ctime>
00049 #include <new>
00050 #include <exception>
00051 #include <iostream>
00052 #include <fstream>
00053 #include <iomanip>
00054 #include <vector>
00055 #include <sstream>
00056 
00057 
00058 namespace chomp {
00059 namespace homengin {
00060 
00061 // --------------------------------------------------
00062 // -------------- ALGEBRAIC STRUCTURE ---------------
00063 // --------------------------------------------------
00064 
00067 template<class euclidom>
00068 class algstruct
00069 {
00070 public:
00072         algstruct ();
00073 
00075         ~algstruct ();
00076 
00079         int countLevels () const;
00080 
00082         void setBetti (int level, int number);
00083 
00085         void addBetti (int level, int howmuch);
00086 
00088         int getBetti (int level) const;
00089 
00091         void addTorsion (int level, euclidom coef);
00092 
00094         const euclidom &getTorsion (int level, int n) const;
00095 
00097         int countTorsion (int level) const;
00098 
00100         std::ostream &describe (std::ostream &out) const;
00101 
00103         std::ostream &showBetti (std::ostream &out) const;
00104 
00105 private:
00107         std::vector<int> betti;
00108         
00110         std::vector<std::vector<euclidom> > torsion;
00111 }; /* class algstruct */
00112 
00113 // --------------------------------------------------
00114 
00115 template <class euclidom>
00116 inline algstruct<euclidom>::algstruct ()
00117 {
00118         return;
00119 } /* algstruct::algstruct */
00120 
00121 template <class euclidom>
00122 inline algstruct<euclidom>::~algstruct ()
00123 {
00124         return;
00125 } /* algstruct::~algstruct */
00126 
00127 // --------------------------------------------------
00128 
00129 template <class euclidom>
00130 inline int algstruct<euclidom>::countLevels () const
00131 {
00132         int nBetti = betti. size ();
00133         int nTorsion = torsion. size ();
00134         return (nBetti > nTorsion) ? nBetti : nTorsion;
00135 } /* algstruct::countLevels */
00136 
00137 template <class euclidom>
00138 inline void algstruct<euclidom>::setBetti (int level, int number)
00139 {
00140         if (level < 0)
00141                 return;
00142         if (number <= 0)
00143                 return;
00144         for (int nBetti = betti. size (); nBetti < level; ++ nBetti)
00145                 betti. push_back (0);
00146         if (static_cast<unsigned> (level) < betti. size ())
00147                 betti [level] = number;
00148         else
00149                 betti. push_back (number);
00150         return;
00151 } /* algstruct::setBetti */
00152 
00153 template <class euclidom>
00154 inline void algstruct<euclidom>::addBetti (int level, int howmuch)
00155 {
00156         if (level < 0)
00157                 return;
00158         if (static_cast<unsigned> (level) < betti. size ())
00159                 betti [level] += howmuch;
00160         else
00161                 setBetti (level, howmuch);
00162         return;
00163 } /* algstruct::addBetti */
00164 
00165 template <class euclidom>
00166 inline int algstruct<euclidom>::getBetti (int level) const
00167 {
00168         if (level < 0)
00169                 return 0;
00170         if (static_cast<unsigned> (level) < betti. size ())
00171                 return betti [level];
00172         else
00173                 return 0;
00174 } /* algstruct::getBetti */
00175 
00176 template <class euclidom>
00177 inline void algstruct<euclidom>::addTorsion (int level, euclidom coef)
00178 {
00179         if (level < 0)
00180                 return;
00181         std::vector<euclidom> empty;
00182         for (int nTorsion = torsion. size (); nTorsion <= level; ++ nTorsion)
00183                 torsion. push_back (empty);
00184         torsion [level]. push_back (coef);
00185         return;
00186 } /* algstruct::addTorsion */
00187 
00188 template <class euclidom>
00189 inline const euclidom &algstruct<euclidom>::getTorsion (int level, int n)
00190         const
00191 {
00192         static euclidom e;
00193 
00194         if ((level < 0) || (n < 0))
00195                 return e;
00196         if ((static_cast<unsigned> (level) < torsion. size ()) &&
00197                 (static_cast<unsigned> (n) < torsion [level]. size ()))
00198                 return torsion [level] [n];
00199         else
00200                 return e;
00201 } /* algstruct::getTorsion */
00202 
00203 template <class euclidom>
00204 inline int algstruct<euclidom>::countTorsion (int level) const
00205 {
00206         if (level < 0)
00207                 return 0;
00208         if (static_cast<unsigned> (level) < torsion. size ())
00209                 return torsion [level]. size ();
00210         return;
00211 } /* algstruct::countTorsion */
00212 
00213 
00214 // --------------------------------------------------
00215 
00216 template <class euclidom>
00217 inline const char *ringsymbol ()
00218 {
00219         return euclidom::ringsymbol ();
00220 } /* ringsymbol */
00221 
00222 template <>
00223 inline const char *ringsymbol<int> ()
00224 {
00225         return "Z";
00226 } /* ringsymbol */
00227 
00228 template <class euclidom>
00229 std::ostream &algstruct<euclidom>::describe (std::ostream &out) const
00230 {
00231         int nBetti = betti. size ();
00232         int nTorsion = torsion. size ();
00233         for (int i = 0; (i < nBetti) || (i < nTorsion); ++ i)
00234         {
00235                 if (i)
00236                         out << ", ";
00237                 else
00238                         out << '(';
00239                 bool zero = true;
00240                 if ((i < nBetti) && (betti [i] > 0))
00241                 {
00242                         zero = false;
00243                         out << ringsymbol<euclidom> ();
00244                         if (betti [i] > 1)
00245                                 out << '^' << betti [i];
00246                         if ((i < nTorsion) && (torsion [i]. size ()))
00247                                 out << " + ";
00248                 }
00249                 if (i < nTorsion)
00250                 {
00251                         std::vector<euclidom> tor = torsion [i];
00252                         for (unsigned j = 0; j < tor. size (); ++ j)
00253                         {
00254                                 zero = false;
00255                                 if (j)
00256                                         out << " + ";
00257                                 out << ringsymbol<euclidom> () <<
00258                                         '_' << tor [j];
00259                         }
00260                 }
00261                 if (zero)
00262                         out << 0;
00263         }
00264         if (nBetti || nTorsion)
00265                 out << ')';
00266         else
00267                 out << '0';
00268         return out;
00269 } /* algstruct::describe */
00270 
00271 template <class euclidom>
00272 std::ostream &algstruct<euclidom>::showBetti (std::ostream &out) const
00273 {
00274         bool first = true;
00275         for (std::vector<int>::const_iterator it = betti. begin ();
00276                 it != betti. end (); ++ it)
00277         {
00278                 if (first)
00279                         first = false;
00280                 else
00281                         out << ' ';
00282                 out << *it;
00283         }
00284         return out;
00285 } /* algstruct::showBetti */
00286 
00288 template <class euclidom>
00289 inline std::ostream &operator << (std::ostream &out,
00290         const algstruct<euclidom> &s)
00291 {
00292         return s. describe (out);
00293 } /* operator << */
00294 
00296 template <class euclidom>
00297 void hom2struct (const chomp::homology::chain<euclidom> *hom, int maxlevel,
00298         algstruct<euclidom> &h)
00299 {
00300         for (int q = 0; q <= maxlevel; ++ q)
00301         {
00302                 const chomp::homology::chain<euclidom> &c = hom [q];
00303                 for (int i = 0; i < c. size (); ++ i)
00304                 {
00305                         const euclidom &e = c. coef (i);
00306                         if (e. delta () == 1)
00307                                 h. addBetti (q, 1);
00308                         else
00309                                 h. addTorsion (q, e);
00310                 }
00311         }
00312         return;
00313 } /* hom2struct */
00314 
00315 template <class euclidom>
00316 void sign2struct (const CRef<HomologySignature> &homSignCR,
00317         algstruct<euclidom> &h)
00318 {
00319         int dim = (*homSignCR). topDim ();
00320         for (int i = 0; i <= dim; ++ i)
00321         {
00322                 h. setBetti (i, (*homSignCR). bettiNumber (i));
00323                 FGAGrpSignature &s = (*homSignCR) [i];
00324                 for (int j = 0; j < s. numberOfTorsionCoefs (); ++ j)
00325                 {
00326                         euclidom e;
00327                         e = s. torsionCoef (j);
00328                         h. addTorsion (i, e);
00329                 }
00330         }
00331         return;
00332 } /* sign2struct */
00333 
00334 
00335 } // namespace homengin
00336 } // namespace chomp
00337 
00338 #endif // _CAPD_HOMENGIN_ALGSTRUCT_H_ 
00339 
00341