integer.h

Go to the documentation of this file.
00001 
00002 
00003 
00016 
00017 // Copyright (C) 1997-2010 by Pawel Pilarczyk.
00018 //
00019 // This file is part of the Homology Library.  This library is free software;
00020 // you can redistribute it and/or modify it under the terms of the GNU
00021 // General Public License as published by the Free Software Foundation;
00022 // either version 2 of the License, or (at your option) any later version.
00023 //
00024 // This library is distributed in the hope that it will be useful,
00025 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027 // GNU General Public License for more details.
00028 //
00029 // You should have received a copy of the GNU General Public License along
00030 // with this software; see the file "license.txt".  If not, write to the
00031 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00032 // MA 02111-1307, USA.
00033 
00034 // Started in December 1999. Last revision: July 4, 2005.
00035 
00036 
00037 #ifndef _CHOMP_STRUCT_INTEGER_H_
00038 #define _CHOMP_STRUCT_INTEGER_H_
00039 
00040 #include "chomp/system/config.h"
00041 #include "chomp/system/textfile.h"
00042 
00043 #include <iostream>
00044 
00045 namespace chomp {
00046 namespace homology {
00047 
00048 
00049 // classes defined in this module (in this order):
00050 class primeint;
00051 class integer;
00052 
00053 
00054 // --------------------------------------------------
00055 // ------------------ prime number ------------------
00056 // --------------------------------------------------
00057 
00060 class primeint
00061 {
00062 public:
00065         primeint (int_t k = 0);
00066 
00068         primeint &operator = (const primeint &p);
00069 
00072         primeint &operator = (int_t k);
00073 
00076         operator int_t () const;
00077 
00078 private:
00080         int_t n;
00081 
00082 }; /* class primeint */
00083 
00084 // --------------------------------------------------
00085 
00086 inline primeint::operator int_t () const
00087 {
00088         return n;
00089 } /* primeint::operator int_t */
00090 
00091 inline primeint &primeint::operator = (const primeint &p)
00092 {
00093         n = p. n;
00094         return *this;
00095 } /* primeint::operator = */
00096 
00097 // --------------------------------------------------
00098 
00100 inline std::ostream &operator << (std::ostream &out, const primeint &p)
00101 {
00102         out << static_cast<int_t> (p);
00103         return out;
00104 } /* operator << */
00105 
00109 inline std::istream &operator >> (std::istream &in, primeint &p)
00110 {
00111         int_t n;
00112         in >> n;
00113         p = n;
00114         return in;
00115 } /* operator >> */
00116 
00117 
00118 // --------------------------------------------------
00119 // -------------------- integer ---------------------
00120 // --------------------------------------------------
00121 
00127 typedef signed short numbertype;
00128 
00134 class integer
00135 {
00136 public:
00137         // default constructor
00138         //      explicit integer (int n = 0);
00139 
00140                 // The destructor.
00141         //      ~integer (void);
00142 
00143                 // copying constructor
00144         //      integer (const integer &e);
00145 
00146                 // assignment operator(s)
00147                 integer &operator = (int n);
00148         //      integer &operator = (const integer &e);
00149 
00150                 // initialize the integers:
00151                 // define integers modulo p or set p to 0 (default)
00152                 static int initialize (int n);
00153 
00154                 // the function "delta": equal to 0 on 0,
00155                 // equal to 1 on invertibles, otherwise > 1
00156                 int delta (void) const;
00157 
00158                 // a normalized number (a better representant for homology)
00159                 integer normalized () const;
00160 
00161                 // several operators
00162                 integer operator - () const;
00163                 integer &operator += (const integer &n);
00164                 integer &operator *= (const integer &n);
00165                 integer operator + (const integer &n) const;
00166                 integer operator * (const integer &n) const;
00167                 integer operator / (const integer &n) const;
00168                 integer operator % (const integer &n) const;
00169                 int operator == (const integer &n) const;
00170 
00171                 static const char *ringname ();
00172                 static const char *ringsymbol ();
00173 
00174                 friend std::ostream &operator << (std::ostream &out, const integer &n);
00175                 friend bool operator < (const integer &x, const integer &y);
00176                 friend bool operator > (const integer &x, const integer &y);
00177 
00178         protected:
00179                 // the number modulo which the computations are performed
00180                 static int p;
00181 
00182                 // the integer number
00183                 numbertype num;
00184 
00185                 // various additional procedures
00186                 static int cut_down (int n);
00187                 static int is_prime (int n);
00188                 static int prime_number (int n);
00189                 static unsigned invert (unsigned n, unsigned q);
00190 
00191 }; /* class integer */
00192 
00193 // --------------------------------------------------
00194 
00195 inline int integer::cut_down (int n)
00196 {
00197         if (n >= 0)
00198                 if (n < p)
00199                         return n;
00200                 else
00201                         return (n % p);
00202         else
00203         {
00204                 int num = p - ((-n) % p);
00205                 if (num == p)
00206                         return 0;
00207                 else
00208                         return num;
00209         }
00210 } /* cut_down */
00211 
00212 /* inline integer::integer (int n)
00213 {
00214         if (p)
00215                 num = (numbertype) cut_down (n);
00216         else
00217         {
00218                 num = (numbertype) n;
00219                 if ((long) num != (long) n)
00220                         throw "Number out of range at initialization.";
00221         }
00222         return;
00223 } */ /* integer::integer */
00224 
00225 /* inline integer::~integer ()
00226 {
00227         return;
00228 } */ /* integer::~integer */
00229 
00230 /* inline integer::integer (const integer &e)
00231 {
00232         num = e. num;
00233         return;
00234 } */ /* integer::integer */
00235 
00236 /* inline integer &integer::operator = (const integer &e)
00237 {
00238         num = e. num;
00239         return *this;
00240 } */ /* integer::operator = */
00241 
00242 inline integer &integer::operator = (int n)
00243 {
00244         if (p)
00245                 num = (numbertype) cut_down (n);
00246         else
00247         {
00248                 num = (numbertype) n;
00249                 if ((long) num != (long) n)
00250                         throw "Number out of range at assignment.";
00251         }
00252         return *this;
00253 } /* integer::operator = */
00254 
00255 inline integer integer::operator / (const integer &n) const
00256 {
00257         integer result;
00258         if (p)
00259                 result = num * (int) invert (n. num, p);
00260         else
00261                 result. num = (numbertype) (num / n. num);
00262         return result;
00263 } /* integer::operator / */
00264 
00265 inline integer integer::operator % (const integer &n) const
00266 {
00267         integer result;
00268         if (p)
00269                 result. num = 0;
00270         else
00271                 result = num % n. num;
00272         return result;
00273 } /* operator % */
00274 
00275 inline integer integer::operator - () const
00276 {
00277         if (p)
00278         {
00279                 integer negative;
00280                 negative. num = (numbertype) (p - num);
00281                 return negative;
00282         }
00283         else
00284         {
00285                 numbertype result = (numbertype) -num;
00286                 if ((long) result + (long) num != 0)
00287                         throw "Number out of range (unary -).";
00288                 integer intresult;
00289                 intresult = result;
00290                 return intresult;
00291         }
00292 } /* integer::operator - (unary) */
00293 
00294 inline integer &integer::operator += (const integer &n)
00295 {
00296         if (!p)
00297                 if (((n. num >= 0) && (num + n. num < num)) ||
00298                         ((n. num < 0) && (num + n. num > num)))
00299                         throw "Number out of range (+).";
00300         num += n. num;
00301         if (p)
00302                 if (num >= p)
00303                         num -= (numbertype) p;
00304         return *this;
00305 } /* integer::operator += */
00306 
00307 inline integer &integer::operator *= (const integer &n)
00308 {
00309         if (p)
00310         {
00311                 long result = (long) num * (long) n. num;
00312                 if (result >= 0)
00313                         num = (numbertype) (result % p);
00314                 else
00315                 {
00316                         num = (numbertype) (p - ((-result) % p));
00317                         if (num == p)
00318                                 num = 0;
00319                 }
00320         }
00321         else
00322         {
00323                 long result = (long) num * (long) (n. num);
00324                 num = (numbertype) result;
00325                 if ((long) num != result)
00326                         throw "Number out of range (*).";
00327         }
00328         return *this;
00329 } /* integer::operator *= */
00330 
00331 inline integer integer::operator + (const integer &n) const
00332 {
00333         integer m (n);
00334         m += *this;
00335         return m;
00336 } /* operator + */
00337 
00338 inline integer integer::operator * (const integer &n) const
00339 {
00340         integer m (n);
00341         m *= *this;
00342         return m;
00343 } /* operator * */
00344 
00345 inline int integer::operator == (const integer &n) const
00346 {
00347         return (n. num == num);
00348 } /* operator == */
00349 
00350 inline std::ostream &operator << (std::ostream &out, const integer &n)
00351 {
00352         out << (long) n. num;
00353         return out;
00354 } /* operator << */
00355 
00356 inline std::istream &operator >> (std::istream &in, integer &n)
00357 {
00358         long number;
00359         in >> number;
00360         if (!in)
00361                 return in;
00362         n = number;
00363         return in;
00364 } /* operator >> */
00365 
00366 inline int operator != (const integer &n, const integer &m)
00367 {
00368         return (!(n == m));
00369 } /* operator != */
00370 
00371 inline int operator == (const integer &n, int m)
00372 {
00373         integer intm;
00374         intm = m;
00375         return (n == intm);
00376 } /* operator == */
00377 
00378 inline int operator != (const integer &n, int m)
00379 {
00380         return !(n == m);
00381 } /* operator != */
00382 
00383 inline integer operator - (const integer &n, const integer &m)
00384 {
00385         return (n + -m);
00386 } /* operator - */
00387 
00388 inline int integer::initialize (int n)
00389 {
00390         p = prime_number (n);
00391         return p;
00392 } /* integer::initialize */
00393 
00394 inline int integer::delta (void) const
00395 {
00396         if (p)
00397                 return (num ? 1 : 0);
00398         else
00399                 return ((num >= 0) ? num : -num);
00400 } /* integer::delta */
00401 
00402 inline integer integer::normalized (void) const
00403 {
00404         integer n;
00405         if (num < 0)
00406                 n. num = (numbertype) (-num);
00407         else
00408                 n. num = num;
00409         return n;
00410 } /* integer::normalized */
00411 
00412 inline bool operator < (const integer &x, const integer &y)
00413 {
00414         return (x. num < y. num);
00415 } /* operator < */
00416 
00417 inline bool operator > (const integer &x, const integer &y)
00418 {
00419         return (x. num > y. num);
00420 } /* operator > */
00421 
00422 
00423 } // namespace homology
00424 } // namespace chomp
00425 
00426 #endif // _CHOMP_STRUCT_INTEGER_H_
00427 
00429