X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fmatrix.cpp;h=9bcab8bd21a66c8dca0b8b6ea5e8de8c24b7c679;hp=34d5f2f93c008a0deeac8aeaf0e4aff64992ed18;hb=b810b012f15981b0937fca5385a8fa2428180a6e;hpb=487e5659efe401683eee0381b0d23f967ffffc3c diff --git a/ginac/matrix.cpp b/ginac/matrix.cpp index 34d5f2f9..9bcab8bd 100644 --- a/ginac/matrix.cpp +++ b/ginac/matrix.cpp @@ -3,7 +3,7 @@ * Implementation of symbolic matrices */ /* - * GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2000 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 @@ -24,6 +24,15 @@ #include #include "matrix.h" +#include "archive.h" +#include "utils.h" +#include "debugmsg.h" + +#ifndef NO_GINAC_NAMESPACE +namespace GiNaC { +#endif // ndef NO_GINAC_NAMESPACE + +GINAC_IMPLEMENT_REGISTERED_CLASS(matrix, basic) ////////// // default constructor, destructor, copy constructor, assignment operator @@ -34,10 +43,10 @@ /** Default ctor. Initializes to 1 x 1-dimensional zero-matrix. */ matrix::matrix() - : basic(TINFO_matrix), row(1), col(1) + : inherited(TINFO_matrix), row(1), col(1) { debugmsg("matrix default constructor",LOGLEVEL_CONSTRUCT); - m.push_back(exZERO()); + m.push_back(_ex0()); } matrix::~matrix() @@ -45,13 +54,13 @@ matrix::~matrix() debugmsg("matrix destructor",LOGLEVEL_DESTRUCT); } -matrix::matrix(matrix const & other) +matrix::matrix(const matrix & other) { debugmsg("matrix copy constructor",LOGLEVEL_CONSTRUCT); copy(other); } -matrix const & matrix::operator=(matrix const & other) +const matrix & matrix::operator=(const matrix & other) { debugmsg("matrix operator=",LOGLEVEL_ASSIGNMENT); if (this != &other) { @@ -63,9 +72,9 @@ matrix const & matrix::operator=(matrix const & other) // protected -void matrix::copy(matrix const & other) +void matrix::copy(const matrix & other) { - basic::copy(other); + inherited::copy(other); row=other.row; col=other.col; m=other.m; // use STL's vector copying @@ -73,7 +82,7 @@ void matrix::copy(matrix const & other) void matrix::destroy(bool call_parent) { - if (call_parent) basic::destroy(call_parent); + if (call_parent) inherited::destroy(call_parent); } ////////// @@ -86,20 +95,59 @@ 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) +matrix::matrix(unsigned r, unsigned c) + : inherited(TINFO_matrix), row(r), col(c) { - debugmsg("matrix constructor from int,int",LOGLEVEL_CONSTRUCT); - m.resize(r*c, exZERO()); + debugmsg("matrix constructor from unsigned,unsigned",LOGLEVEL_CONSTRUCT); + m.resize(r*c, _ex0()); } // protected /** Ctor from representation, for internal use only. */ -matrix::matrix(int r, int c, vector const & m2) - : basic(TINFO_matrix), row(r), col(c), m(m2) +matrix::matrix(unsigned r, unsigned c, const exvector & m2) + : inherited(TINFO_matrix), row(r), col(c), m(m2) { - debugmsg("matrix constructor from int,int,vector",LOGLEVEL_CONSTRUCT); + debugmsg("matrix constructor from unsigned,unsigned,exvector",LOGLEVEL_CONSTRUCT); +} + +////////// +// archiving +////////// + +/** Construct object from archive_node. */ +matrix::matrix(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst) +{ + debugmsg("matrix constructor from archive_node", LOGLEVEL_CONSTRUCT); + if (!(n.find_unsigned("row", row)) || !(n.find_unsigned("col", col))) + throw (std::runtime_error("unknown matrix dimensions in archive")); + m.reserve(row * col); + for (unsigned int i=0; true; i++) { + ex e; + if (n.find_ex("m", e, sym_lst, i)) + m.push_back(e); + else + break; + } +} + +/** Unarchive the object. */ +ex matrix::unarchive(const archive_node &n, const lst &sym_lst) +{ + return (new matrix(n, sym_lst))->setflag(status_flags::dynallocated); +} + +/** Archive the object. */ +void matrix::archive(archive_node &n) const +{ + inherited::archive(n); + n.add_unsigned("row", row); + n.add_unsigned("col", col); + exvector::const_iterator i = m.begin(), iend = m.end(); + while (i != iend) { + n.add_ex("m", *i); + i++; + } } ////////// @@ -114,14 +162,56 @@ basic * matrix::duplicate() const return new matrix(*this); } +void matrix::print(ostream & os, unsigned upper_precedence) const +{ + debugmsg("matrix print",LOGLEVEL_PRINT); + os << "[[ "; + for (unsigned r=0; r tmp(row*col); - for (int i=0; i::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; @@ -168,10 +258,10 @@ ex matrix::eval(int level) const } // eval() entry by entry - vector m2(row*col); + exvector m2(row*col); --level; - for (int r=0; r m2(row*col); + exvector m2(row*col); --level; - for (int r=0; r(const_cast(other)); + GINAC_ASSERT(is_exactly_of_type(other, matrix)); + const matrix & o=static_cast(const_cast(other)); // compare number of rows if (row != o.rows()) { @@ -225,8 +315,8 @@ int matrix::compare_same_type(basic const & other) const // equal number of rows and columns, compare individual elements int cmpval; - for (int r=0; r sum(this->m); - vector::iterator i; - vector::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) { @@ -264,15 +354,15 @@ matrix matrix::add(matrix const & other) const /** Difference of matrices. * * @exception logic_error (incompatible matrices) */ -matrix matrix::sub(matrix const & other) const +matrix matrix::sub(const matrix & other) const { if (col != other.col || row != other.row) { throw (std::logic_error("matrix::sub(): incompatible matrices")); } - vector dif(this->m); - vector::iterator i; - vector::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) { @@ -284,16 +374,16 @@ matrix matrix::sub(matrix const & other) const /** Product of matrices. * * @exception logic_error (incompatible matrices) */ -matrix matrix::mul(matrix const & other) const +matrix matrix::mul(const matrix & other) const { if (col != other.row) { throw (std::logic_error("matrix::mul(): incompatible matrices")); } - vector prod(row*other.col); - for (int i=0; i=row || co<0 || co>=col) { throw (std::range_error("matrix::operator(): index out of range")); @@ -318,7 +408,7 @@ ex const & matrix::operator() (int ro, int co) const /** Set individual elements manually. * * @exception range_error (index out of range) */ -matrix & matrix::set(int ro, int co, ex value) +matrix & matrix::set(unsigned ro, unsigned co, ex value) { if (ro<0 || ro>=row || co<0 || co>=col) { throw (std::range_error("matrix::set(): index out of range")); @@ -333,10 +423,10 @@ matrix & matrix::set(int ro, int co, ex value) * represents the transposed. */ matrix matrix::transpose(void) const { - vector trans(col*row); + exvector trans(col*row); - for (int r=0; r 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); @@ -404,12 +494,12 @@ ex determinant_symbolic_perm(const matrix & M) ex det; ex term; - vector sigma(M.cols()); - for (int i=0; i sigma(M.cols()); + for (unsigned i=0; i::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(); @@ -527,7 +617,7 @@ ex matrix::trace(void) const } ex tr; - for (int r=0; rzero_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); - int last_assigned_sol=n+1; - for (int r=m; r>0; --r) { - int first_non_zero=1; + unsigned last_assigned_sol=n+1; + for (unsigned r=m; r>0; --r) { + unsigned first_non_zero=1; while ((first_non_zero<=n)&&(a.ffe_get(r,first_non_zero).is_zero())) { first_non_zero++; } @@ -720,11 +810,11 @@ matrix matrix::fraction_free_elim(matrix const & vars, } else { // assign solutions for vars between first_non_zero+1 and // last_assigned_sol-1: free parameters - for (int c=first_non_zero+1; c<=last_assigned_sol-1; ++c) { + for (unsigned c=first_non_zero+1; c<=last_assigned_sol-1; ++c) { sol.ffe_set(c,1,vars.ffe_get(c,1)); } ex e=b.ffe_get(r,1); - for (int c=first_non_zero+1; c<=n; ++c) { + for (unsigned c=first_non_zero+1; c<=n; ++c) { e=e-a.ffe_get(r,c)*sol.ffe_get(c,1); } sol.ffe_set(first_non_zero,1, @@ -734,21 +824,21 @@ matrix matrix::fraction_free_elim(matrix const & vars, } // assign solutions for vars between 1 and // last_assigned_sol-1: free parameters - for (int c=1; c<=last_assigned_sol-1; ++c) { + for (unsigned c=1; c<=last_assigned_sol-1; ++c) { sol.ffe_set(c,1,vars.ffe_get(c,1)); } /* - for (int c=1; c<=n; ++c) { + for (unsigned c=1; c<=n; ++c) { cout << vars.ffe_get(c,1) << "->" << sol.ffe_get(c,1) << endl; } */ -#ifdef DOASSERT +#ifdef DO_GINAC_ASSERT // test solution with echelon matrix - for (int r=1; r<=m; ++r) { + for (unsigned r=1; r<=m; ++r) { ex e=0; - for (int c=1; c<=n; ++c) { + for (unsigned c=1; c<=n; ++c) { e=e+a.ffe_get(r,c)*sol.ffe_get(c,1); } if (!(e-b.ffe_get(r,1)).normal().is_zero()) { @@ -756,13 +846,13 @@ 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 - for (int r=1; r<=m; ++r) { + for (unsigned r=1; r<=m; ++r) { ex e=0; - for (int c=1; c<=n; ++c) { + for (unsigned c=1; c<=n; ++c) { e=e+ffe_get(r,c)*sol.ffe_get(c,1); } try { @@ -779,15 +869,15 @@ 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; } /** Solve simultaneous set of equations. */ -matrix matrix::solve(matrix const & v) const +matrix matrix::solve(const matrix & v) const { if (!(row == col && col == v.row)) { throw (std::logic_error("matrix::solve(): incompatible matrices")); @@ -795,24 +885,24 @@ matrix matrix::solve(matrix const & v) const // build the extended matrix of *this with v attached to the right matrix tmp(row,col+v.col); - for (int r=0; r sol(v.row*v.col); - for (int c=0; c=0; --r) { + exvector sol(v.row*v.col); + for (unsigned c=0; c=0; --r) { sol[r*v.col+c] = tmp[r*tmp.col+c]; - for (int i=r+1; i