X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fmatrix.cpp;h=52b4de36555dfbc10953e1fb8a3c882f7abb80b5;hp=feae32fee687341c7a92a5d8ea4e6693dc61dc88;hb=9df145c8bfa8ce9f2cbe6c05673481b6ca4c4c22;hpb=fe9dbfb9947b24149b3ce7dd9285f27ab286cbd7 diff --git a/ginac/matrix.cpp b/ginac/matrix.cpp index feae32fe..52b4de36 100644 --- a/ginac/matrix.cpp +++ b/ginac/matrix.cpp @@ -152,7 +152,7 @@ void matrix::archive(archive_node &n) const exvector::const_iterator i = m.begin(), iend = m.end(); while (i != iend) { n.add_ex("m", *i); - i++; + ++i; } } @@ -174,15 +174,13 @@ void matrix::print(std::ostream & os, unsigned upper_precedence) const os << "[[ "; for (unsigned r=0; r=0); + GINAC_ASSERT(isetflag(status_flags::dynallocated | status_flags::evaluated ); @@ -291,11 +288,10 @@ ex matrix::evalf(int level) const // evalf() entry by entry exvector m2(row*col); --level; - for (unsigned r=0; rm); exvector::iterator i; exvector::const_iterator ci; - for (i=sum.begin(), ci=other.m.begin(); - i!=sum.end(); - ++i, ++ci) { + for (i=sum.begin(), ci=other.m.begin(); i!=sum.end(); ++i, ++ci) (*i) += (*ci); - } + return matrix(row,col,sum); } @@ -363,11 +357,9 @@ matrix matrix::sub(const matrix & other) const exvector dif(this->m); exvector::iterator i; exvector::const_iterator ci; - for (i=dif.begin(), ci=other.m.begin(); - i!=dif.end(); - ++i, ++ci) { + for (i=dif.begin(), ci=other.m.begin(); i!=dif.end(); ++i, ++ci) (*i) -= (*ci); - } + return matrix(row,col,dif); } @@ -438,7 +430,7 @@ matrix matrix::transpose(void) const /** Determinant of square matrix. This routine doesn't actually calculate the * determinant, it only implements some heuristics about which algorithm to - * call. If all the elements of the matrix are elements of an integral domain + * run. If all the elements of the matrix are elements of an integral domain * the determinant is also in that integral domain and the result is expanded * only. If one or more elements are from a quotient field the determinant is * usually also in that quotient field and the result is normalized before it @@ -446,85 +438,105 @@ matrix matrix::transpose(void) const * [[a/(a-b),1],[b/(a-b),1]] is returned as unity. (In this respect, it * behaves like MapleV and unlike Mathematica.) * + * @param algo allows to chose an algorithm * @return the determinant as a new expression - * @exception logic_error (matrix not square) */ -ex matrix::determinant(void) const + * @exception logic_error (matrix not square) + * @see determinant_algo */ +ex matrix::determinant(unsigned algo) const { if (row!=col) throw (std::logic_error("matrix::determinant(): matrix not square")); GINAC_ASSERT(row*col==m.capacity()); if (this->row==1) // continuation would be pointless return m[0]; - - // Gather some information about the matrix: + + // Gather some statistical information about this matrix: bool numeric_flag = true; bool normal_flag = false; - unsigned sparse_count = 0; // count non-zero elements + unsigned sparse_count = 0; // counts non-zero elements for (exvector::const_iterator r=m.begin(); r!=m.end(); ++r) { - if (!(*r).is_zero()) + lst srl; // symbol replacement list + ex rtest = (*r).to_rational(srl); + if (!rtest.is_zero()) ++sparse_count; - if (!(*r).info(info_flags::numeric)) + if (!rtest.info(info_flags::numeric)) numeric_flag = false; - if ((*r).info(info_flags::rational_function) && - !(*r).info(info_flags::crational_polynomial)) + if (!rtest.info(info_flags::crational_polynomial) && + rtest.info(info_flags::rational_function)) normal_flag = true; } - // Purely numeric matrix handled by Gauss elimination - if (numeric_flag) { - ex det = 1; - matrix tmp(*this); - int sign = tmp.gauss_elimination(); - for (int d=0; d uintpair; // # of zeros, column - std::vector c_zeros; // number of zeros in column - for (unsigned c=0; c can't be used for permutation_sign. - std::vector pre_sort; - for (std::vector::iterator i=c_zeros.begin(); i!=c_zeros.end(); ++i) - pre_sort.push_back(i->second); - int sign = permutation_sign(pre_sort); - exvector result(row*col); // represents sorted matrix - unsigned c = 0; - for (std::vector::iterator i=pre_sort.begin(); - i!=pre_sort.end(); - ++i,++c) { - for (unsigned r=0; r uintpair; + std::vector c_zeros; // number of zeros in column + for (unsigned c=0; c pre_sort; + for (std::vector::iterator i=c_zeros.begin(); i!=c_zeros.end(); ++i) + pre_sort.push_back(i->second); + int sign = permutation_sign(pre_sort); + exvector result(row*col); // represents sorted matrix + unsigned c = 0; + for (std::vector::iterator i=pre_sort.begin(); + i!=pre_sort.end(); + ++i,++c) { + for (unsigned r=0; rn) { // row consists only of zeroes, corresponding rhs must be 0 as well - if (!b(r,0).is_zero()) { + if (!b.m[r*b.cols()].is_zero()) { throw (std::runtime_error("matrix::fraction_free_elim(): singular matrix")); } } else { // assign solutions for vars between first_non_zero+1 and // last_assigned_sol-1: free parameters for (unsigned c=first_non_zero; c