-/* Leverrier algorithm for large matrices having at least one symbolic entry.
- * This routine is only called internally by matrix::determinant(). The
- * algorithm is very bad for symbolic matrices since it returns expressions
- * that are quite hard to expand. */
-/*ex matrix::determinant_leverrier(const matrix & M)
- *{
- * GINAC_ASSERT(M.rows()==M.cols()); // cannot happen, just in case...
- *
- * matrix B(M);
- * matrix I(M.row, M.col);
- * ex c=B.trace();
- * for (unsigned i=1; i<M.row; ++i) {
- * for (unsigned j=0; j<M.row; ++j)
- * I.m[j*M.col+j] = c;
- * B = M.mul(B.sub(I));
- * c = B.trace()/ex(i+1);
- * }
- * if (M.row%2) {
- * return c;
- * } else {
- * return -c;
- * }
- *}*/
-
-
-ex matrix::determinant_minor_sparse(void) const
-{
- // for small matrices the algorithm does not make any sense:
- if (this->row==1)
- return m[0];
- if (this->row==2)
- return (m[0]*m[3]-m[2]*m[1]).expand();
- if (this->row==3)
- return (m[0]*m[4]*m[8]-m[0]*m[5]*m[7]-
- m[1]*m[3]*m[8]+m[2]*m[3]*m[7]+
- m[1]*m[5]*m[6]-m[2]*m[4]*m[6]).expand();
-
- ex det;
- matrix minorM(this->row-1,this->col-1);
- for (unsigned r1=0; r1<this->row; ++r1) {
- // shortcut if element(r1,0) vanishes
- if (m[r1*col].is_zero())
- continue;
- // assemble the minor matrix
- for (unsigned r=0; r<minorM.rows(); ++r) {
- for (unsigned c=0; c<minorM.cols(); ++c) {
- if (r<r1)
- minorM.set(r,c,m[r*col+c+1]);
- else
- minorM.set(r,c,m[(r+1)*col+c+1]);
- }
- }
- // recurse down and care for sign:
- if (r1%2)
- det -= m[r1*col] * minorM.determinant_minor_sparse();
- else
- det += m[r1*col] * minorM.determinant_minor_sparse();
- }
- return det.expand();
-}
-