CoCoALib-0.9905 date: 23 May 2007


matrix.H

Go to the documentation of this file.
00001 #ifndef CoCoA_matrix_H
00002 #define CoCoA_matrix_H
00003 
00004 //   Copyright (c)  2005  John Abbott
00005 
00006 //   This file is part of the source of CoCoALib, the CoCoA Library.
00007 
00008 //   CoCoALib is free software; you can redistribute it and/or modify
00009 //   it under the terms of the GNU General Public License (version 2)
00010 //   as published by the Free Software Foundation.  A copy of the full
00011 //   licence may be found in the file COPYING in this directory.
00012 
00013 //   CoCoALib is distributed in the hope that it will be useful,
00014 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 //   GNU General Public License for more details.
00017 
00018 //   You should have received a copy of the GNU General Public License
00019 //   along with CoCoA; if not, write to the Free Software
00020 //   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 
00022 
00023 #include "CoCoA/ring.H"
00024 #include "CoCoA/ZZ.H"
00025 
00026 #include <iosfwd>
00027 //using std::ostream;
00028 #include <cstddef>
00029 //using std::size_t;
00030 #include <vector>
00031 //using std::vector;
00032 
00033 
00034 namespace CoCoA
00035 {
00036 
00037   class OpenMathOutput; // forward declaration -- defined in OpenMath.H
00038 
00039 //   class MatrixVectorBase
00040 //   {
00041 //   public:
00042 //     ~MatrixVectorBase(); // needed by inherited classes
00043 //     std::size_t myNumCompts() = 0;
00044 //     RingRawValue& myRawEntry(std::size_t i) = 0;
00045 //     void myEntry(RingElem& r, std::size_t i) = 0;
00046 //     void mySetEntry(std::size_t i, const RefRingElem& r) = 0;
00047 //   };
00048 
00049 //   class MatrixVector
00050 //   {
00051 //   public:
00052 //     MatrixVectorBase* operator->();
00053 //     RingElem operator[](std::size_t i);
00054 //     friend const ring& owner(const MatrixVector& v);
00055 //     friend void set(MatrixVector& v, std::size_t i, const RefRingElem& r);
00056 //   private:
00057 //     ring myR;
00058 //     MatrixVectorBase& myCoords;
00059 //   };
00060 
00061 
00062   /*-----------------------------------------------------------------*/
00063   /** \include matrix.txt  */
00064   /*-----------------------------------------------------------------*/
00065 
00066 
00067   class MatrixBase; // forward declaration
00068   class ConstMatrixBase; // forward declaration
00069 
00070   class ConstMatrix
00071   {
00072     // smart ref counted pointer class???
00073   public:
00074     explicit ConstMatrix(const ConstMatrixBase* MatPtr); // public???
00075     ConstMatrix(const ConstMatrix& M); // copy ctor
00076     ~ConstMatrix();  // ??? should this be virtual ????
00077     const ConstMatrixBase* myMatrixPtr() const;
00078     const ConstMatrixBase* operator->() const;
00079     ConstRefRingElem operator()(std::size_t i, std::size_t j) const;
00080   private: // disable assignment
00081     ConstMatrix& operator=(const ConstMatrix&); //  NEVER DEFINED -- ASSIGMENT DISABLED
00082   protected: // data member
00083     ConstMatrixBase const* myPtr;
00084   };
00085 
00086 
00087   class matrix: public ConstMatrix
00088   {
00089     // Data members inherited from ConstMatrix;
00090     // will actually cast the pointer to MatrixBase*
00091   public:
00092     matrix(MatrixBase* MatPtr); // public???
00093     matrix(const matrix& copy); // copy ctor (not a deep copy)
00094     // default dtor works fine
00095     MatrixBase* myMatrixPtr();
00096     MatrixBase* operator->();
00097   private: // disable assignment and defauilt copy ctor
00098     matrix& operator=(const matrix&); //  NEVER DEFINED -- assigment disabled
00099   };
00100 
00101 
00102 
00103   std::ostream& operator<<(std::ostream& out, ConstMatrix M);
00104   void AssignZero(matrix& M);
00105   void SetEntry(matrix& M, std::size_t i, std::size_t j, ConstRefRingElem r);
00106   void SetEntry(matrix& M, std::size_t i, std::size_t j, long n);
00107   void SetEntry(matrix& M, std::size_t i, std::size_t j, const ZZ& N);
00108   bool IsZeroRow(ConstMatrix M, std::size_t i);
00109   bool IsZeroCol(ConstMatrix M, std::size_t j);
00110   RingElem det(ConstMatrix M);
00111   std::size_t rank(ConstMatrix M);
00112 
00113 
00114 
00115 
00116   class ConstMatrixBase
00117   {
00118   private: // data members
00119     mutable std::size_t myRefCount; // every matrix has an intrusive reference count
00120   protected: // ref count fns accessible only to friends and derived classes.
00121     friend class ConstMatrix;
00122 //???    friend class matrix;      // so that matrix::~matrix() can call the dtor
00123     void myRefCountInc() const;
00124     void myRefCountDec() const;
00125     void myRefCountZero() const;
00126 
00127   protected:
00128     ConstMatrixBase();  // inline fn, just zeroes myRefCount
00129     virtual ~ConstMatrixBase(); // defined out of line, does nothing
00130   public:
00131     typedef std::vector<RingElem> vec;
00132     virtual const ring& myBaseRing() const = 0;
00133     virtual std::size_t myNumRows() const = 0;
00134     virtual std::size_t myNumCols() const = 0;
00135     virtual ConstRefRingElem myEntry(std::size_t i, std::size_t j) const = 0;
00136     virtual void myMulByRow(vec& lhs, const vec& v) const; ///< lhs = v*M -- vector-by-matrix product, default "dense" definition
00137     virtual void myMulByCol(vec& lhs, const vec& v) const; ///< lhs = M*v -- matrix-by-vector product, default "dense" definition
00138     virtual bool myIsZeroRow(std::size_t i) const; ///< tests whether row i is zero -- default "dense" definition
00139     virtual bool myIsZeroCol(std::size_t j) const; ///< tests whether col j is zero -- default "dense" definition
00140     virtual void myDet(RefRingElem d) const;                      // default method uses Gaussian reduction
00141     virtual size_t myRank() const;                                // default method uses Gaussian reduction
00142     virtual void myOutputSelf(std::ostream& out) const;           // has a default "dense" definition
00143     virtual void myOutputSelf(OpenMathOutput& OMOut) const; // has a default "dense" definition
00144     virtual void myCheckIndices(std::size_t i, std::size_t j, const char* where="") const;  // throws if indices are too large
00145   };
00146 
00147 
00148 
00149   class MatrixBase: public ConstMatrixBase
00150   {
00151     // Data members: myRefCount inherited from ConstMatrixBase
00152 
00153   protected:
00154     MatrixBase();
00155     friend class matrix; // so that matrix::~matrix() can call the dtor
00156     virtual ~MatrixBase();
00157   public:
00158     virtual MatrixBase* myZeroClone(const ring& R, std::size_t NumRows, std::size_t NumCols) const = 0;
00159     typedef std::vector<RingElem> vec;
00160     virtual void mySwap(matrix& M) = 0; // homogeneous swap
00161     virtual void myAssignZero() = 0; // sets all entries to zero
00162     virtual void mySetEntry(std::size_t i, std::size_t j, ConstRefRingElem r) = 0;
00163     virtual void mySetEntry(std::size_t i, std::size_t j, long n) = 0;
00164     virtual void mySetEntry(std::size_t i, std::size_t j, const ZZ& N) = 0;
00165     virtual void myRowMul(std::size_t i, ConstRefRingElem c) = 0; ///< row(i) = c*row(i)
00166     virtual void myColMul(std::size_t j, ConstRefRingElem c) = 0; ///< row(j) = c*row(j)
00167     virtual void myAddRowMul(std::size_t i1, std::size_t i2, ConstRefRingElem c) = 0; ///< row(i1) += c*row(i2)
00168     virtual void myAddColMul(std::size_t j1, std::size_t j2, ConstRefRingElem c) = 0; ///< row(j1) += c*row(j2)
00169     virtual void mySwapRows(std::size_t i1, std::size_t i2) = 0;
00170     virtual void mySwapCols(std::size_t j1, std::size_t j2) = 0;
00171   };
00172 
00173 
00174 
00175 
00176 
00177   /////////////////////////////////////////////////////////////////////////////
00178   // Inline functions
00179 
00180   inline void ConstMatrixBase::myRefCountInc() const { ++myRefCount; }
00181   inline void ConstMatrixBase::myRefCountDec() const { if (--myRefCount == 0) delete this; }
00182   inline void ConstMatrixBase::myRefCountZero() const { myRefCount = 0; }
00183 
00184 
00185 //   inline MatrixVectorBase* MatrixVector::operator->()
00186 //   {
00187 //     return &myCoords;
00188 //   }
00189 
00190 
00191 //   inline const ring& owner(const MatrixVector& v)
00192 //   {
00193 //     return v.myR;
00194 //   }
00195 
00196 
00197   inline ConstMatrix::ConstMatrix(const ConstMatrixBase* MatPtr):
00198       myPtr(MatPtr)
00199   {
00200     myPtr->myRefCountInc();
00201   }
00202 
00203 
00204   inline ConstMatrix::ConstMatrix(const ConstMatrix& copy):
00205       myPtr(copy.myPtr)
00206   {
00207     myPtr->myRefCountInc();
00208   }
00209 
00210   inline ConstMatrix::~ConstMatrix()
00211   {
00212     myPtr->myRefCountDec();
00213   }
00214 
00215 
00216   inline const ConstMatrixBase* ConstMatrix::myMatrixPtr() const
00217   {
00218     return myPtr;
00219   }
00220 
00221 
00222   inline const ConstMatrixBase* ConstMatrix::operator->() const
00223   {
00224     return myPtr;
00225   }
00226 
00227 
00228   // Currently ConstMatrix::operator() is out of line -- see matrix.C
00229 
00230 
00231   inline matrix::matrix(MatrixBase* MatPtr):
00232       ConstMatrix(MatPtr)
00233   {}
00234 
00235 
00236   inline matrix::matrix(const matrix& copy):
00237       ConstMatrix(copy)
00238   {}
00239 
00240 
00241   inline MatrixBase* matrix::myMatrixPtr()
00242   {
00243     // dynamic_cast would perform needless checks
00244     // reinterpret_cast might not be portable?
00245     return static_cast<MatrixBase*>(const_cast<ConstMatrixBase*>(myPtr));
00246   }
00247 
00248 
00249   inline MatrixBase* matrix::operator->()
00250   {
00251     // dynamic_cast would perform needless checks
00252     // reinterpret_cast might not be portable?
00253     return static_cast<MatrixBase*>(const_cast<ConstMatrixBase*>(myPtr));
00254   }
00255 
00256 
00257   inline const ring& BaseRing(ConstMatrix M)
00258   {
00259     return M->myBaseRing();
00260   }
00261 
00262 
00263   inline std::size_t NumRows(ConstMatrix M)
00264   {
00265     return M->myNumRows();
00266   }
00267 
00268 
00269   inline std::size_t NumCols(ConstMatrix M)
00270   {
00271     return M->myNumCols();
00272   }
00273 
00274 
00275 } // end of namespace CoCoA
00276 
00277 
00278 
00279 // RCS header/log in the next few lines
00280 // $Header: /Volumes/Home/cocoa/cvs-repository/CoCoALib-0.99/include/CoCoA/matrix.H,v 1.1.1.1 2007/03/09 15:16:11 abbott Exp $
00281 // $Log: matrix.H,v $
00282 // Revision 1.1.1.1  2007/03/09 15:16:11  abbott
00283 // Imported files
00284 //
00285 // Revision 1.5  2006/12/06 17:18:40  cocoa
00286 // -- removed #include "config.H"
00287 //
00288 // Revision 1.4  2006/11/24 17:41:18  cocoa
00289 // -- reorganized includes of header files
00290 //
00291 // Revision 1.3  2006/11/02 13:25:44  cocoa
00292 // Simplification of header files: the OpenMath classes have been renamed.
00293 // Many minor consequential changes.
00294 //
00295 // Revision 1.2  2006/10/06 14:04:15  cocoa
00296 // Corrected position of #ifndef in header files.
00297 // Separated CoCoA_ASSERT into assert.H from config.H;
00298 // many minor consequential changes (have to #include assert.H).
00299 // A little tidying of #include directives (esp. in Max's code).
00300 //
00301 // Revision 1.1.1.1  2006/05/30 11:39:36  cocoa
00302 // Imported files
00303 //
00304 // Revision 1.4  2006/05/12 16:10:58  cocoa
00305 // Added OpenMathFwd.H, and tidied OpenMath.H.
00306 // Many consequential but trivial changes.
00307 //
00308 // Revision 1.3  2006/04/27 13:45:30  cocoa
00309 // Changed name of NewIdentityRingHom to NewIdentityHom.
00310 // Changed name of member functions which print out their own object
00311 // into myOutputSelf (to distinguish from "transitive" myOutput fns).
00312 //
00313 // Revision 1.2  2006/03/27 12:21:26  cocoa
00314 // Minor silly changes to reduce number of complaints from some compiler or other.
00315 //
00316 // Revision 1.1.1.1  2005/10/17 10:46:54  cocoa
00317 // Imported files
00318 //
00319 // Revision 1.1.1.1  2005/05/03 15:47:30  cocoa
00320 // Imported files
00321 //
00322 // Revision 1.11  2005/04/20 15:40:48  cocoa
00323 // Major change: modified the standard way errors are to be signalled
00324 // (now via a macro which records filename and line number).  Updated
00325 // documentation in error.txt accordingly.
00326 //
00327 // Improved the documentation in matrix.txt (still more work to be done).
00328 //
00329 // Revision 1.10  2005/04/19 15:39:55  cocoa
00330 // Matrices now use reference counts.
00331 //
00332 // Revision 1.9  2005/04/19 14:06:04  cocoa
00333 // Added GPL and GFDL licence stuff.
00334 //
00335 // Revision 1.8  2005/03/31 16:59:42  cocoa
00336 // Made special matrix ctors private, so a user has to pass via the
00337 // pseudo-ctors (which do all the arg sanity checking).
00338 //
00339 // Revision 1.7  2005/03/30 17:15:14  cocoa
00340 // Cleaned the SpecialMatrix code; a simple test compiles and
00341 // runs fine.
00342 //
00343 // Revision 1.6  2005/03/29 17:36:47  cocoa
00344 // Just checking in before going home -- test-matrix1 does not yet link!
00345 //
00346 // Revision 1.5  2005/03/29 17:19:30  cocoa
00347 // -- added: rank and myRank
00348 //
00349 // Revision 1.4  2005/03/11 16:44:18  cocoa
00350 // New abstract class structure for matrices.
00351 // New types of special matrix.
00352 //
00353 // Revision 1.3  2005/03/02 18:46:41  cocoa
00354 // Added new types ConstRefMatrix, and RefMatrix following along
00355 // the lines of ConstRefRingElem and RefRingElem.  The semantics
00356 // should be a bit clearer now.
00357 //
00358 // Revision 1.2  2005/02/11 14:15:20  cocoa
00359 // New style ring elements and references to ring elements;
00360 // I hope I have finally got it right!
00361 //
00362 // Revision 1.1.1.1  2005/01/27 15:12:13  cocoa
00363 // Imported files
00364 //
00365 // Revision 1.9  2004/11/29 16:19:02  cocoa
00366 // -- changed syntax for function det
00367 //
00368 // Revision 1.8  2004/11/12 15:49:29  cocoa
00369 // Tidying prior to 0.90 release.
00370 // (a) documentation improved (or marked as poor)
00371 // (b) sundry minor improvements to the code
00372 //
00373 
00374 #endif

Generated on Wed May 23 13:43:35 2007 for CoCoALib by  doxygen 1.4.6