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.
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
};
};
}
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)
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;
| 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;}
* @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;
// 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);
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
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