/** @file matrix.cpp
*
- * Implementation of symbolic matrices
- *
+ * 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
#include <stdexcept>
#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
: basic(TINFO_matrix), row(1), col(1)
{
debugmsg("matrix default constructor",LOGLEVEL_CONSTRUCT);
- m.push_back(exZERO());
+ m.push_back(_ex0());
}
matrix::~matrix()
: 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)
+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);
}
//////////
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
{
/** 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);
}
* 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;
}
// 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) {
}
// 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) {
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
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) {
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) {
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) {
* 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) {
* 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) {
* 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);
* 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);
* 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);
}
// 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();
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);
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) {
}
*/
-#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);
}
*/
-#ifdef DOASSERT
+#ifdef DO_GINAC_ASSERT
// test solution with echelon matrix
for (int r=1; r<=m; ++r) {
ex e=0;
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
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;
}
}
// 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];
const matrix some_matrix;
type_info const & typeid_matrix=typeid(some_matrix);
+
+#ifndef NO_GINAC_NAMESPACE
+} // namespace GiNaC
+#endif // ndef NO_GINAC_NAMESPACE