- Banned exZERO(), exONE(), exMINUSHALF() and all this from the interface.
[ginac.git] / ginac / matrix.cpp
index edf2a945fef43153b1460dc78b7290a5e24245db..eddc62052c1a4c7d2c5dc235147d5fcb1f098bf7 100644 (file)
@@ -2,10 +2,34 @@
  *
  *  Implementation of symbolic matrices */
 
+/*
+ *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
 #include <algorithm>
 #include <stdexcept>
 
-#include "ginac.h"
+#include "matrix.h"
+#include "debugmsg.h"
+#include "utils.h"
+
+#ifndef NO_GINAC_NAMESPACE
+namespace GiNaC {
+#endif // ndef NO_GINAC_NAMESPACE
 
 //////////
 // default constructor, destructor, copy constructor, assignment operator
 
 /** Default ctor.  Initializes to 1 x 1-dimensional zero-matrix. */
 matrix::matrix()
-    : basic(TINFO_MATRIX), row(1), col(1)
+    : basic(TINFO_matrix), row(1), col(1)
 {
     debugmsg("matrix default constructor",LOGLEVEL_CONSTRUCT);
-    m.push_back(exZERO());
+    m.push_back(_ex0());
 }
 
 matrix::~matrix()
@@ -69,19 +93,19 @@ void matrix::destroy(bool call_parent)
  *  @param r number of rows
  *  @param c number of cols */
 matrix::matrix(int r, int c)
-    : basic(TINFO_MATRIX), row(r), col(c)
+    : basic(TINFO_matrix), row(r), col(c)
 {
     debugmsg("matrix constructor from int,int",LOGLEVEL_CONSTRUCT);
-    m.resize(r*c, exZERO());
+    m.resize(r*c, _ex0());
 }
 
 // protected
 
 /** Ctor from representation, for internal use only. */
-matrix::matrix(int r, int c, vector<ex> const & m2)
-    : basic(TINFO_MATRIX), row(r), col(c), m(m2)
+matrix::matrix(int r, int c, exvector const & m2)
+    : basic(TINFO_matrix), row(r), col(c), m(m2)
 {
-    debugmsg("matrix constructor from int,int,vector<ex>",LOGLEVEL_CONSTRUCT);
+    debugmsg("matrix constructor from int,int,exvector",LOGLEVEL_CONSTRUCT);
 }
 
 //////////
@@ -96,6 +120,42 @@ basic * matrix::duplicate() const
     return new matrix(*this);
 }
 
+void matrix::print(ostream & os, unsigned upper_precedence) const
+{
+    debugmsg("matrix print",LOGLEVEL_PRINT);
+    os << "[[ ";
+    for (int r=0; r<row-1; ++r) {
+        os << "[[";
+        for (int c=0; c<col-1; ++c) {
+            os << m[r*col+c] << ",";
+        }
+        os << m[col*(r+1)-1] << "]], ";
+    }
+    os << "[[";
+    for (int c=0; c<col-1; ++c) {
+        os << m[(row-1)*col+c] << ",";
+    }
+    os << m[row*col-1] << "]] ]]";
+}
+
+void matrix::printraw(ostream & os) const
+{
+    debugmsg("matrix printraw",LOGLEVEL_PRINT);
+    os << "matrix(" << row << "," << col <<",";
+    for (int r=0; r<row-1; ++r) {
+        os << "(";
+        for (int c=0; c<col-1; ++c) {
+            os << m[r*col+c] << ",";
+        }
+        os << m[col*(r-1)-1] << "),";
+    }
+    os << "(";
+    for (int c=0; c<col-1; ++c) {
+        os << m[(row-1)*col+c] << ",";
+    }
+    os << m[row*col-1] << "))";
+}
+
 /** nops is defined to be rows x columns. */
 int matrix::nops() const
 {
@@ -111,7 +171,7 @@ ex & matrix::let_op(int const i)
 /** expands the elements of a matrix entry by entry. */
 ex matrix::expand(unsigned options) const
 {
-    vector<ex> tmp(row*col);
+    exvector tmp(row*col);
     for (int i=0; i<row*col; ++i) {
         tmp[i]=m[i].expand(options);
     }
@@ -122,13 +182,13 @@ ex matrix::expand(unsigned options) const
  *  itself or one of the elements 'has' it. */
 bool matrix::has(ex const & other) const
 {
-    ASSERT(other.bp!=0);
+    GINAC_ASSERT(other.bp!=0);
     
     // tautology: it is the expression itself
     if (is_equal(*other.bp)) return true;
     
     // search all the elements
-    for (vector<ex>::const_iterator r=m.begin(); r!=m.end(); ++r) {
+    for (exvector::const_iterator r=m.begin(); r!=m.end(); ++r) {
         if ((*r).has(other)) return true;
     }
     return false;
@@ -150,7 +210,7 @@ ex matrix::eval(int level) const
     }
     
     // eval() entry by entry
-    vector<ex> m2(row*col);
+    exvector m2(row*col);
     --level;    
     for (int r=0; r<row; ++r) {
         for (int c=0; c<col; ++c) {
@@ -178,7 +238,7 @@ ex matrix::evalf(int level) const
     }
     
     // evalf() entry by entry
-    vector<ex> m2(row*col);
+    exvector m2(row*col);
     --level;
     for (int r=0; r<row; ++r) {
         for (int c=0; c<col; ++c) {
@@ -192,7 +252,7 @@ ex matrix::evalf(int level) const
 
 int matrix::compare_same_type(basic const & other) const
 {
-    ASSERT(is_exactly_of_type(other, matrix));
+    GINAC_ASSERT(is_exactly_of_type(other, matrix));
     matrix const & o=static_cast<matrix &>(const_cast<basic &>(other));
     
     // compare number of rows
@@ -232,9 +292,9 @@ matrix matrix::add(matrix const & other) const
         throw (std::logic_error("matrix::add(): incompatible matrices"));
     }
     
-    vector<ex> sum(this->m);
-    vector<ex>::iterator i;
-    vector<ex>::const_iterator ci;
+    exvector sum(this->m);
+    exvector::iterator i;
+    exvector::const_iterator ci;
     for (i=sum.begin(), ci=other.m.begin();
          i!=sum.end();
          ++i, ++ci) {
@@ -252,9 +312,9 @@ matrix matrix::sub(matrix const & other) const
         throw (std::logic_error("matrix::sub(): incompatible matrices"));
     }
     
-    vector<ex> dif(this->m);
-    vector<ex>::iterator i;
-    vector<ex>::const_iterator ci;
+    exvector dif(this->m);
+    exvector::iterator i;
+    exvector::const_iterator ci;
     for (i=dif.begin(), ci=other.m.begin();
          i!=dif.end();
          ++i, ++ci) {
@@ -272,7 +332,7 @@ matrix matrix::mul(matrix const & other) const
         throw (std::logic_error("matrix::mul(): incompatible matrices"));
     }
     
-    vector<ex> prod(row*other.col);
+    exvector prod(row*other.col);
     for (int i=0; i<row; ++i) {
         for (int j=0; j<other.col; ++j) {
             for (int l=0; l<col; ++l) {
@@ -315,7 +375,7 @@ matrix & matrix::set(int ro, int co, ex value)
  *  represents the transposed. */
 matrix matrix::transpose(void) const
 {
-    vector<ex> trans(col*row);
+    exvector trans(col*row);
     
     for (int r=0; r<col; ++r) {
         for (int c=0; c<row; ++c) {
@@ -329,18 +389,18 @@ matrix matrix::transpose(void) const
  * called internally by matrix::determinant(). */
 ex determinant_numeric(const matrix & M)
 {
-    ASSERT(M.rows()==M.cols());  // cannot happen, just in case...
+    GINAC_ASSERT(M.rows()==M.cols());  // cannot happen, just in case...
     matrix tmp(M);
-    ex det=exONE();
+    ex det=_ex1();
     ex piv;
     
     for (int r1=0; r1<M.rows(); ++r1) {
         int indx = tmp.pivot(r1);
         if (indx == -1) {
-            return exZERO();
+            return _ex0();
         }
         if (indx != 0) {
-            det *= exMINUSONE();
+            det *= _ex_1();
         }
         det = det * tmp.m[r1*M.cols()+r1];
         for (int r2=r1+1; r2<M.rows(); ++r2) {
@@ -378,7 +438,7 @@ int permutation_sign(vector<T> s)
  *  routine is only called internally by matrix::determinant(). */
 ex determinant_symbolic_perm(const matrix & M)
 {
-    ASSERT(M.rows()==M.cols());  // cannot happen, just in case...
+    GINAC_ASSERT(M.rows()==M.cols());  // cannot happen, just in case...
     
     if (M.rows()==1) {  // speed things up
         return M(0,0);
@@ -403,7 +463,7 @@ ex determinant_symbolic_perm(const matrix & M)
  *  called internally by matrix::determinant(). */
 ex determinant_symbolic_minor(const matrix & M)
 {
-    ASSERT(M.rows()==M.cols());  // cannot happen, just in case...
+    GINAC_ASSERT(M.rows()==M.cols());  // cannot happen, just in case...
     
     if (M.rows()==1) {  // end of recursion
         return M(0,0);
@@ -447,7 +507,7 @@ ex determinant_symbolic_minor(const matrix & M)
  *  that are very hard to canonicalize. */
 /*ex determinant_symbolic_leverrier(const matrix & M)
  *{
- *    ASSERT(M.rows()==M.cols());  // cannot happen, just in case...
+ *    GINAC_ASSERT(M.rows()==M.cols());  // cannot happen, just in case...
  *    
  *    matrix B(M);
  *    matrix I(M.row, M.col);
@@ -485,7 +545,7 @@ ex matrix::determinant(bool normalized) const
     }
 
     // check, if there are non-numeric entries in the matrix:
-    for (vector<ex>::const_iterator r=m.begin(); r!=m.end(); ++r) {
+    for (exvector::const_iterator r=m.begin(); r!=m.end(); ++r) {
         if (!(*r).info(info_flags::numeric)) {
             if (normalized) {
                 return determinant_symbolic_minor(*this).normal();
@@ -550,7 +610,7 @@ matrix matrix::inverse(void) const
     matrix tmp(row,col);
     // set tmp to the unit matrix
     for (int i=0; i<col; ++i) {
-        tmp.m[i*col+i] = exONE();
+        tmp.m[i*col+i] = _ex1();
     }
     // create a copy of this matrix
     matrix cpy(*this);
@@ -630,7 +690,7 @@ matrix matrix::fraction_free_elim(matrix const & vars,
     for (int k=1; (k<=n)&&(r<=m); ++k) {
         // find a nonzero pivot
         int p;
-        for (p=r; (p<=m)&&(a.ffe_get(p,k).is_equal(exZERO())); ++p) {}
+        for (p=r; (p<=m)&&(a.ffe_get(p,k).is_equal(_ex0())); ++p) {}
         // pivot is in row p
         if (p<=m) {
             if (p!=r) {
@@ -669,22 +729,22 @@ matrix matrix::fraction_free_elim(matrix const & vars,
     }
     */
     
-#ifdef DOASSERT
+#ifdef DO_GINAC_ASSERT
     // test if we really have an upper echelon matrix
     int zero_in_last_row=-1;
     for (int r=1; r<=m; ++r) {
         int zero_in_this_row=0;
         for (int c=1; c<=n; ++c) {
-            if (a.ffe_get(r,c).is_equal(exZERO())) {
+            if (a.ffe_get(r,c).is_equal(_ex0())) {
                zero_in_this_row++;
             } else {
                 break;
             }
         }
-        ASSERT((zero_in_this_row>zero_in_last_row)||(zero_in_this_row=n));
+        GINAC_ASSERT((zero_in_this_row>zero_in_last_row)||(zero_in_this_row=n));
         zero_in_last_row=zero_in_this_row;
     }
-#endif // def DOASSERT
+#endif // def DO_GINAC_ASSERT
     
     // assemble solution
     matrix sol(n,1);
@@ -726,7 +786,7 @@ matrix matrix::fraction_free_elim(matrix const & vars,
     }
     */
     
-#ifdef DOASSERT
+#ifdef DO_GINAC_ASSERT
     // test solution with echelon matrix
     for (int r=1; r<=m; ++r) {
         ex e=0;
@@ -738,7 +798,7 @@ matrix matrix::fraction_free_elim(matrix const & vars,
             cout << "b.ffe_get(" << r<<",1)=" << b.ffe_get(r,1) << endl;
             cout << "diff=" << (e-b.ffe_get(r,1)).normal() << endl;
         }
-        ASSERT((e-b.ffe_get(r,1)).normal().is_zero());
+        GINAC_ASSERT((e-b.ffe_get(r,1)).normal().is_zero());
     }
 
     // test solution with original matrix
@@ -761,9 +821,9 @@ matrix matrix::fraction_free_elim(matrix const & vars,
             ex xxx=e-rhs.ffe_get(r,1);
             cerr << "xxx=" << xxx << endl << endl;
         }
-        ASSERT((e-rhs.ffe_get(r,1)).normal().is_zero());
+        GINAC_ASSERT((e-rhs.ffe_get(r,1)).normal().is_zero());
     }
-#endif // def DOASSERT
+#endif // def DO_GINAC_ASSERT
     
     return sol;
 }   
@@ -802,7 +862,7 @@ matrix matrix::solve(matrix const & v) const
     }
     
     // assemble the solution matrix
-    vector<ex> sol(v.row*v.col);
+    exvector sol(v.row*v.col);
     for (int c=0; c<v.col; ++c) {
         for (int r=col-1; r>=0; --r) {
             sol[r*v.col+c] = tmp[r*tmp.col+c];
@@ -850,3 +910,7 @@ int matrix::pivot(int ro)
 
 const matrix some_matrix;
 type_info const & typeid_matrix=typeid(some_matrix);
+
+#ifndef NO_GINAC_NAMESPACE
+} // namespace GiNaC
+#endif // ndef NO_GINAC_NAMESPACE