X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fmatrix.cpp;h=375f8a5b122869c1f47460d074f2d074b46ace76;hp=623537febbb965f5ac1324e77f85e07d59a00768;hb=cca88b51436e4b654d16a4d60cd0d1c66fcf5dd6;hpb=d744dbc38e4035c30abf07314c4dab19deb391e6 diff --git a/ginac/matrix.cpp b/ginac/matrix.cpp index 623537fe..375f8a5b 100644 --- a/ginac/matrix.cpp +++ b/ginac/matrix.cpp @@ -3,7 +3,7 @@ * Implementation of symbolic matrices */ /* - * GiNaC Copyright (C) 1999-2005 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2014 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 @@ -20,13 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include -#include -#include -#include - #include "matrix.h" #include "numeric.h" #include "lst.h" @@ -40,6 +33,13 @@ #include "archive.h" #include "utils.h" +#include +#include +#include +#include +#include +#include + namespace GiNaC { GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(matrix, basic, @@ -53,7 +53,7 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(matrix, basic, ////////// /** Default ctor. Initializes to 1 x 1-dimensional zero-matrix. */ -matrix::matrix() : inherited(TINFO_matrix), row(1), col(1), m(1, _ex0) +matrix::matrix() : row(1), col(1), m(1, _ex0) { setflag(status_flags::not_shareable); } @@ -68,8 +68,7 @@ matrix::matrix() : inherited(TINFO_matrix), row(1), col(1), m(1, _ex0) * * @param r number of rows * @param c number of cols */ -matrix::matrix(unsigned r, unsigned c) - : inherited(TINFO_matrix), row(r), col(c), m(r*c, _ex0) +matrix::matrix(unsigned r, unsigned c) : row(r), col(c), m(r*c, _ex0) { setflag(status_flags::not_shareable); } @@ -78,7 +77,7 @@ matrix::matrix(unsigned r, unsigned c) /** Ctor from representation, for internal use only. */ matrix::matrix(unsigned r, unsigned c, const exvector & m2) - : inherited(TINFO_matrix), row(r), col(c), m(m2) + : row(r), col(c), m(m2) { setflag(status_flags::not_shareable); } @@ -88,7 +87,7 @@ matrix::matrix(unsigned r, unsigned c, const exvector & m2) * If the list has more elements than the matrix, the excessive elements are * thrown away. */ matrix::matrix(unsigned r, unsigned c, const lst & l) - : inherited(TINFO_matrix), row(r), col(c), m(r*c, _ex0) + : row(r), col(c), m(r*c, _ex0) { setflag(status_flags::not_shareable); @@ -106,21 +105,25 @@ matrix::matrix(unsigned r, unsigned c, const lst & l) // archiving ////////// -matrix::matrix(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) +void matrix::read_archive(const archive_node &n, lst &sym_lst) { - setflag(status_flags::not_shareable); + inherited::read_archive(n, sym_lst); 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++) { + // XXX: default ctor inserts a zero element, we need to erase it here. + m.pop_back(); + archive_node::archive_node_cit first = n.find_first("m"); + archive_node::archive_node_cit last = n.find_last("m"); + ++last; + for (archive_node::archive_node_cit i=first; i != last; ++i) { ex e; - if (n.find_ex("m", e, sym_lst, i)) - m.push_back(e); - else - break; + n.find_ex_by_loc(i, e, sym_lst); + m.push_back(e); } } +GINAC_BIND_UNARCHIVER(matrix); void matrix::archive(archive_node &n) const { @@ -134,8 +137,6 @@ void matrix::archive(archive_node &n) const } } -DEFAULT_UNARCHIVE(matrix) - ////////// // functions overriding virtual functions from base classes ////////// @@ -221,7 +222,7 @@ ex matrix::eval(int level) const m2[r*col+c] = m[r*col+c].eval(level); return (new matrix(row, col, m2))->setflag(status_flags::dynallocated | - status_flags::evaluated); + status_flags::evaluated); } ex matrix::subs(const exmap & mp, unsigned options) const @@ -262,6 +263,24 @@ ex matrix::conjugate() const return *this; } +ex matrix::real_part() const +{ + exvector v; + v.reserve(m.size()); + for (exvector::const_iterator i=m.begin(); i!=m.end(); ++i) + v.push_back(i->real_part()); + return matrix(row, col, v); +} + +ex matrix::imag_part() const +{ + exvector v; + v.reserve(m.size()); + for (exvector::const_iterator i=m.begin(); i!=m.end(); ++i) + v.push_back(i->imag_part()); + return matrix(row, col, v); +} + // protected int matrix::compare_same_type(const basic & other) const @@ -580,10 +599,11 @@ matrix matrix::mul(const matrix & other) const for (unsigned r1=0; r1rows(); ++r1) { for (unsigned c=0; ccols(); ++c) { + // Quick test: can we shortcut? if (m[r1*col+c].is_zero()) continue; for (unsigned r2=0; r2=0) { - if (indx>0) { + } else { + if (indx>r0) { + // Matrix needs pivoting, swap rows r0 and indx of tmp_n and tmp_d. sign = -sign; - // tmp_n's rows r0 and indx were swapped, do the same in tmp_d: - for (unsigned c=c0; cis_zero())) + return false; + return true; +} + ex lst_to_matrix(const lst & l) { lst::const_iterator itr, itc; @@ -1598,4 +1637,52 @@ ex symbolic_matrix(unsigned r, unsigned c, const std::string & base_name, const return M; } +ex reduced_matrix(const matrix& m, unsigned r, unsigned c) +{ + if (r+1>m.rows() || c+1>m.cols() || m.cols()<2 || m.rows()<2) + throw std::runtime_error("minor_matrix(): index out of bounds"); + + const unsigned rows = m.rows()-1; + const unsigned cols = m.cols()-1; + matrix &M = *new matrix(rows, cols); + M.setflag(status_flags::dynallocated | status_flags::evaluated); + + unsigned ro = 0; + unsigned ro2 = 0; + while (ro2m.rows() || c+nc>m.cols()) + throw std::runtime_error("sub_matrix(): index out of bounds"); + + matrix &M = *new matrix(nr, nc); + M.setflag(status_flags::dynallocated | status_flags::evaluated); + + for (unsigned ro=0; ro