Add optional algorithm selection to matrix::inverse().
authorRichard Kreckel <kreckel@ginac.de>
Sun, 28 Jan 2018 18:23:50 +0000 (19:23 +0100)
committerRichard Kreckel <kreckel@ginac.de>
Sun, 28 Jan 2018 18:30:10 +0000 (19:30 +0100)
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.)

doc/tutorial/ginac.texi
ginac/matrix.cpp
ginac/matrix.h
ginac/version.h

index d3fe767..710e06f 100644 (file)
@@ -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:
 
index 915d454..80ca3e4 100644 (file)
@@ -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"));
index 1bb549b..0274841 100644 (file)
@@ -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(); }
index cafd06d..3dd55da 100644 (file)
@@ -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