From: Richard Kreckel Date: Sun, 28 Jan 2018 18:23:50 +0000 (+0100) Subject: Add optional algorithm selection to matrix::inverse(). X-Git-Tag: release_1-7-3~8 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=1be7026a705dfefedcd838e6b60795ca6d469bf9 Add optional algorithm selection to matrix::inverse(). Following a proposal by Vitaly Magerya, a signature with a solve_algo is added to class matrix. (Not using a default argument in order to not break the ABI.) --- diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi index d3fe7676..710e06f8 100644 --- a/doc/tutorial/ginac.texi +++ b/doc/tutorial/ginac.texi @@ -1146,7 +1146,7 @@ This creates a symbol that is printed as "@code{x}" in normal output, but as "@code{\Box}" in LaTeX code (@xref{Input/output}, for more information about the different output formats of expressions in GiNaC). GiNaC automatically creates proper LaTeX code for symbols having names of -greek letters (@samp{alpha}, @samp{mu}, etc.). You can retrive the name +greek letters (@samp{alpha}, @samp{mu}, etc.). You can retrieve the name and the LaTeX name of a symbol using the respective methods: @cindex @code{get_name()} @cindex @code{get_TeX_name()} @@ -2175,19 +2175,17 @@ ex matrix::charpoly(const ex & lambda) const; unsigned matrix::rank() const; @end example -The @samp{algo} argument of @code{determinant()} allows to select -between different algorithms for calculating the determinant. The -asymptotic speed (as parametrized by the matrix size) can greatly differ -between those algorithms, depending on the nature of the matrix' -entries. The possible values are defined in the @file{flags.h} header -file. By default, GiNaC uses a heuristic to automatically select an -algorithm that is likely (but not guaranteed) to give the result most -quickly. +The optional @samp{algo} argument of @code{determinant()} allows to +select between different algorithms for calculating the determinant. +The asymptotic speed (as parametrized by the matrix size) can greatly +differ between those algorithms, depending on the nature of the +matrix' entries. The possible values are defined in the +@file{flags.h} header file. By default, GiNaC uses a heuristic to +automatically select an algorithm that is likely (but not guaranteed) +to give the result most quickly. -@cindex @code{inverse()} (matrix) @cindex @code{solve()} -Matrices may also be inverted using the @code{ex matrix::inverse()} -method and linear systems may be solved with: +Linear systems can be solved with: @example matrix matrix::solve(const matrix & vars, const matrix & rhs, @@ -2202,6 +2200,15 @@ times @code{p} and in the case of an underdetermined system will still contain some of the indeterminates from @code{vars}. If the system is overdetermined, an exception is thrown. +@cindex @code{inverse()} (matrix) +To invert a matrix, use the method: + +@example +matrix matrix::inverse(unsigned algo=solve_algo::automatic) const; +@end example + +The @samp{algo} argument is optional. If given, it must be one of +@code{solve_algo} defined in @file{flags.h}. @node Indexed objects, Non-commutative objects, Matrices, Basic concepts @c node-name, next, previous, up @@ -3338,7 +3345,7 @@ something very close to @code{dirac_gamma(mu)}, although @code{dirac_gamma} have more efficient simplification mechanism. @cindex @code{get_metric()} Also, the object created by @code{clifford_unit(mu, minkmetric())} is -not aware about the symmetry of its metric, see the start of the pevious +not aware about the symmetry of its metric, see the start of the previous paragraph. A more accurate analog of 'dirac_gamma(mu)' should be specifies as follows: diff --git a/ginac/matrix.cpp b/ginac/matrix.cpp index 915d4543..80ca3e45 100644 --- a/ginac/matrix.cpp +++ b/ginac/matrix.cpp @@ -939,10 +939,11 @@ ex matrix::charpoly(const ex & lambda) const /** Inverse of this matrix. * + * @param algo selects the algorithm (one of solve_algo) * @return the inverted matrix * @exception logic_error (matrix not square) * @exception runtime_error (singular matrix) */ -matrix matrix::inverse() const +matrix matrix::inverse(unsigned algo) const { if (row != col) throw (std::logic_error("matrix::inverse(): matrix not square")); @@ -965,7 +966,7 @@ matrix matrix::inverse() const matrix sol(row,col); try { - sol = this->solve(vars,identity); + sol = this->solve(vars, identity, algo); } catch (const std::runtime_error & e) { if (e.what()==std::string("matrix::solve(): inconsistent linear system")) throw (std::runtime_error("matrix::inverse(): singular matrix")); diff --git a/ginac/matrix.h b/ginac/matrix.h index 1bb549b0..02748413 100644 --- a/ginac/matrix.h +++ b/ginac/matrix.h @@ -148,7 +148,8 @@ public: ex determinant(unsigned algo = determinant_algo::automatic) const; ex trace() const; ex charpoly(const ex & lambda) const; - matrix inverse() const; + matrix inverse() const { return inverse(solve_algo::automatic); } + matrix inverse(unsigned algo) const; matrix solve(const matrix & vars, const matrix & rhs, unsigned algo = solve_algo::automatic) const; unsigned rank() const; @@ -211,7 +212,9 @@ inline ex charpoly(const matrix & m, const ex & lambda) { return m.charpoly(lambda); } inline matrix inverse(const matrix & m) -{ return m.inverse(); } +{ return m.inverse(solve_algo::automatic); } +inline matrix inverse(const matrix & m, unsigned algo) +{ return m.inverse(algo); } inline unsigned rank(const matrix & m) { return m.rank(); } diff --git a/ginac/version.h b/ginac/version.h index cafd06db..3dd55da2 100644 --- a/ginac/version.h +++ b/ginac/version.h @@ -49,6 +49,8 @@ // increasing. This doesn't matter, though: there is not incurred cost // for numbers that are omitted, except for shrinking the available space // of leftover numbers. Not something we need to worry about yet. ;-) +// TODO, when setting GINAC_LT_REVISION to 0: +// * change matrix inverse to use default argument (twice) #define GINAC_LT_CURRENT 7 #define GINAC_LT_REVISION 3 #define GINAC_LT_AGE 1