- input parser recognizes "sqrt()", which is also used in the output
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Tue, 18 Dec 2001 18:48:06 +0000 (18:48 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Tue, 18 Dec 2001 18:48:06 +0000 (18:48 +0000)
- divide(a,b,q) only modifies q if the division succeeds; also, divide(a,b,a)
  works now
- fixed small bug in dummy index renaming which could cause it to not
  recognize renamable indices in some cases
- power::degree() and power::ldegree() throw an exception when encountering
  a non-integer exponent

NEWS
ginac/flags.h
ginac/indexed.cpp
ginac/input_parser.yy
ginac/normal.cpp
ginac/power.cpp

diff --git a/NEWS b/NEWS
index b2ad1a4..7ca5aeb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,14 @@
 This file records noteworthy changes.
 
+1.0.2 (<date>)
+* Input parser recognizes "sqrt()", which is also used in the output
+* divide(a,b,q) only modifies q if the division succeeds; also, divide(a,b,a)
+  works now
+* Fixed small bug in dummy index renaming which could cause it to not
+  recognize renamable indices in some cases
+* power::degree() and power::ldegree() throw an exception when encountering
+  a non-integer exponent
+
 1.0.1 (22 November 2001)
 * Function sqrfree() handles a few more cases now.
 * Class relational has real canonical ordering now.
index b7f6222..4c4f772 100644 (file)
@@ -72,7 +72,7 @@ public:
        enum {
                dynallocated    = 0x0001,       ///< Heap-allocated (i.e. created by new if we want to be clever and bypass the stack, @see ex::construct_from_basic() )
                evaluated       = 0x0002,       ///< .eval() has already done its job
-               expanded        = 0x0004,       ///< .expand() has already done its job
+               expanded        = 0x0004,       ///< .expand(0) has already done its job (other expand() options ignore this flag)
                hash_calculated = 0x0008        ///< .calchash() has already done its job
        };
 };
index bc474f3..87f53db 100644 (file)
@@ -539,7 +539,6 @@ static ex rename_dummy_indices(const ex & e, exvector & global_dummy_indices, ex
                        }
                        it++;
                }
-               shaker_sort(global_dummy_indices.begin(), global_dummy_indices.end(), ex_is_less(), ex_swap());
 
                // If this is the first set of local indices, do nothing
                if (old_global_size == 0)
@@ -554,6 +553,7 @@ static ex rename_dummy_indices(const ex & e, exvector & global_dummy_indices, ex
        shaker_sort(local_syms.begin(), local_syms.end(), ex_is_less(), ex_swap());
        for (unsigned i=0; i<global_size; i++)
                global_syms.push_back(global_dummy_indices[i].op(0));
+       shaker_sort(global_syms.begin(), global_syms.end(), ex_is_less(), ex_swap());
 
        // Remove common indices
        exlist local_uniq, global_uniq;
index bbc0764..8ba5bf4 100644 (file)
@@ -94,8 +94,15 @@ exp  : T_NUMBER              {$$ = $1;}
        | T_LITERAL             {$$ = $1;}
        | T_DIGITS              {$$ = $1;}
        | T_SYMBOL '(' exprseq ')' {
-               unsigned i = function::find_function(ex_to<symbol>($1).get_name(), $3.nops());
-               $$ = function(i, ex_to<exprseq>($3)).eval(1);
+               string n = ex_to<symbol>($1).get_name();
+               if (n == "sqrt") {
+                       if ($3.nops() != 1)
+                               throw (std::runtime_error("too many arguments to sqrt()"));
+                       $$ = sqrt($3.op(0));
+               } else {
+                       unsigned i = function::find_function(n, $3.nops());
+                       $$ = function(i, ex_to<exprseq>($3)).eval(1);
+               }
        }
        | exp T_EQUAL exp       {$$ = $1 == $3;}
        | exp T_NOTEQ exp       {$$ = $1 != $3;}
index ee27868..a161f82 100644 (file)
@@ -581,14 +581,15 @@ ex sprem(const ex &a, const ex &b, const symbol &x, bool check_args)
  *  @param check_args  check whether a and b are polynomials with rational
  *         coefficients (defaults to "true")
  *  @return "true" when exact division succeeds (quotient returned in q),
- *          "false" otherwise */
+ *          "false" otherwise (q left untouched) */
 bool divide(const ex &a, const ex &b, ex &q, bool check_args)
 {
-       q = _ex0;
        if (b.is_zero())
                throw(std::overflow_error("divide: division by zero"));
-       if (a.is_zero())
+       if (a.is_zero()) {
+               q = _ex0;
                return true;
+       }
        if (is_ex_exactly_of_type(b, numeric)) {
                q = a / b;
                return true;
@@ -611,8 +612,10 @@ bool divide(const ex &a, const ex &b, ex &q, bool check_args)
 
        // Polynomial long division (recursive)
        ex r = a.expand();
-       if (r.is_zero())
+       if (r.is_zero()) {
+               q = _ex0;
                return true;
+       }
        int bdeg = b.degree(*x);
        int rdeg = r.degree(*x);
        ex blcoeff = b.expand().coeff(*x, bdeg);
index 58913a8..78c9c96 100644 (file)
@@ -238,8 +238,10 @@ int power::degree(const ex & s) const
                        return ex_to<numeric>(exponent).to_int();
                else
                        return basis.degree(s) * ex_to<numeric>(exponent).to_int();
-       }
-       return 0;
+       } else if (basis.has(s))
+               throw(std::runtime_error("power::degree(): undefined degree because of non-integer exponent"));
+       else
+               return 0;
 }
 
 int power::ldegree(const ex & s) const 
@@ -249,8 +251,10 @@ int power::ldegree(const ex & s) const
                        return ex_to<numeric>(exponent).to_int();
                else
                        return basis.ldegree(s) * ex_to<numeric>(exponent).to_int();
-       }
-       return 0;
+       } else if (basis.has(s))
+               throw(std::runtime_error("power::ldegree(): undefined degree because of non-integer exponent"));
+       else
+               return 0;
 }
 
 ex power::coeff(const ex & s, int n) const