- 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 b2ad1a42448794c5a3d80eceaaaecb0b5b38467d..7ca5aeb93c2703655dd941594c694637fe120e5c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,14 @@
 This file records noteworthy changes.
 
 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.
 1.0.1 (22 November 2001)
 * Function sqrfree() handles a few more cases now.
 * Class relational has real canonical ordering now.
index b7f6222d7fcdb668f55237f8551957ac62ffd296..4c4f77290c506626c2822182ed05154237f42d65 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
        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
        };
 };
                hash_calculated = 0x0008        ///< .calchash() has already done its job
        };
 };
index bc474f3d41e5db31c0ed31859fd281911497c9b4..87f53db31ed71c546de02b43a825d02a9cfc39cf 100644 (file)
@@ -539,7 +539,6 @@ static ex rename_dummy_indices(const ex & e, exvector & global_dummy_indices, ex
                        }
                        it++;
                }
                        }
                        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)
 
                // 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(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;
 
        // Remove common indices
        exlist local_uniq, global_uniq;
index bbc07647e80d5459f634c9890a2b336d2799e43a..8ba5bf42f75544e19755349be17fea1b29733a46 100644 (file)
@@ -94,8 +94,15 @@ exp  : T_NUMBER              {$$ = $1;}
        | T_LITERAL             {$$ = $1;}
        | T_DIGITS              {$$ = $1;}
        | T_SYMBOL '(' exprseq ')' {
        | 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;}
        }
        | exp T_EQUAL exp       {$$ = $1 == $3;}
        | exp T_NOTEQ exp       {$$ = $1 != $3;}
index ee27868165e02e148960407369b8d18da282f180..a161f82133a7a448ede06ff831868e9bb31e91d2 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),
  *  @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)
 {
 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 (b.is_zero())
                throw(std::overflow_error("divide: division by zero"));
-       if (a.is_zero())
+       if (a.is_zero()) {
+               q = _ex0;
                return true;
                return true;
+       }
        if (is_ex_exactly_of_type(b, numeric)) {
                q = a / b;
                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();
 
        // Polynomial long division (recursive)
        ex r = a.expand();
-       if (r.is_zero())
+       if (r.is_zero()) {
+               q = _ex0;
                return true;
                return true;
+       }
        int bdeg = b.degree(*x);
        int rdeg = r.degree(*x);
        ex blcoeff = b.expand().coeff(*x, bdeg);
        int bdeg = b.degree(*x);
        int rdeg = r.degree(*x);
        ex blcoeff = b.expand().coeff(*x, bdeg);
index 58913a8bcfd1a786f377c2b667e1cc0be4209292..78c9c9696d14303b468a4f3b1c69b460560a314a 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 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 
 }
 
 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 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
 }
 
 ex power::coeff(const ex & s, int n) const