if (dim.is_equal(o.dim))
return true;
- return (dim < o.dim || dim > o.dim || (is_a<numeric>(dim) && is_a<symbol>(o.dim)) || (is_a<symbol>(dim) && is_a<numeric>(o.dim)));
+ return (dim < o.dim || dim > o.dim || (is_exactly_a<numeric>(dim) && is_a<symbol>(o.dim)) || (is_a<symbol>(dim) && is_exactly_a<numeric>(o.dim)));
}
bool varidx::is_dummy_pair_same_type(const basic & other) const
ex minimal_dim(const ex & dim1, const ex & dim2)
{
- if (dim1.is_equal(dim2) || dim1 < dim2 || (is_a<numeric>(dim1) && is_a<symbol>(dim2)))
+ if (dim1.is_equal(dim2) || dim1 < dim2 || (is_exactly_a<numeric>(dim1) && is_a<symbol>(dim2)))
return dim1;
- else if (dim1 > dim2 || (is_a<symbol>(dim1) && is_a<numeric>(dim2)))
+ else if (dim1 > dim2 || (is_a<symbol>(dim1) && is_exactly_a<numeric>(dim2)))
return dim2;
else
throw (std::runtime_error("minimal_dim(): index dimensions cannot be ordered"));
symminfo(const ex & symmterm_, const ex & orig_)
{
- if (is_a<mul>(orig_) && is_a<numeric>(orig_.op(orig_.nops()-1))) {
+ if (is_exactly_a<mul>(orig_) && is_exactly_a<numeric>(orig_.op(orig_.nops()-1))) {
ex tmp = orig_.op(orig_.nops()-1);
orig = orig_ / tmp;
} else
orig = orig_;
- if (is_a<mul>(symmterm_) && is_a<numeric>(symmterm_.op(symmterm_.nops()-1))) {
+ if (is_exactly_a<mul>(symmterm_) && is_exactly_a<numeric>(symmterm_.op(symmterm_.nops()-1))) {
coeff = symmterm_.op(symmterm_.nops()-1);
symmterm = symmterm_ / coeff;
} else {
}
// Symmetrizing over the dummy indices may cancel terms
- int num_terms_orig = (is_a<add>(sum) ? sum.nops() : 1);
+ int num_terms_orig = (is_exactly_a<add>(sum) ? sum.nops() : 1);
if (num_terms_orig > 1 && dummy_indices.size() >= 2) {
// Construct list of all dummy index symbols
std::vector<symminfo> v;
for (int i=0; i<sum.nops(); i++) {
ex sum_symm = sum.op(i).symmetrize(dummy_syms);
- if (is_a<add>(sum_symm))
+ if (is_exactly_a<add>(sum_symm))
for (int j=0; j<sum_symm.nops(); j++)
v.push_back(symminfo(sum_symm.op(j), sum.op(i)));
else
if (is_exactly_a<numeric>(arg))
return csgn(ex_to<numeric>(arg));
- else if (is_a<mul>(arg) &&
- is_a<numeric>(arg.op(arg.nops()-1))) {
+ else if (is_exactly_a<mul>(arg) &&
+ is_exactly_a<numeric>(arg.op(arg.nops()-1))) {
numeric oc = ex_to<numeric>(arg.op(arg.nops()-1));
if (oc.is_real()) {
if (oc > 0)
{
// Just wrap the function into a pseries object
epvector new_seq;
- GINAC_ASSERT(is_exactly_a<symbol>(r.lhs()));
+ GINAC_ASSERT(is_a<symbol>(r.lhs()));
const symbol &s = ex_to<symbol>(r.lhs());
new_seq.push_back(expair(Order(_ex1), numeric(std::min(x.ldegree(s), order))));
return pseries(r, new_seq);
// tgamma series directly.
const ex arg1_pt = arg1.subs(rel);
const ex arg2_pt = arg2.subs(rel);
- GINAC_ASSERT(is_exactly_a<symbol>(rel.lhs()));
+ GINAC_ASSERT(is_a<symbol>(rel.lhs()));
const symbol &s = ex_to<symbol>(rel.lhs());
ex arg1_ser, arg2_ser, arg1arg2_ser;
if ((!arg1_pt.info(info_flags::integer) || arg1_pt.info(info_flags::positive)) &&
int order,
unsigned options)
{
- GINAC_ASSERT(is_exactly_a<symbol>(rel.lhs()));
+ GINAC_ASSERT(is_a<symbol>(rel.lhs()));
ex arg_pt;
bool must_expand_arg = false;
// maybe substitution of rel into arg fails because of a pole
int order,
unsigned options)
{
- GINAC_ASSERT(is_exactly_a<symbol>(rel.lhs()));
+ GINAC_ASSERT(is_a<symbol>(rel.lhs()));
// method:
// Taylor series where there is no pole falls back to tan_deriv.
// On a pole simply expand sin(x)/cos(x).
int order,
unsigned options)
{
- GINAC_ASSERT(is_exactly_a<symbol>(rel.lhs()));
+ GINAC_ASSERT(is_a<symbol>(rel.lhs()));
// method:
// Taylor series where there is no pole or cut falls back to atan_deriv.
// There are two branch cuts, one runnig from I up the imaginary axis and
int order,
unsigned options)
{
- GINAC_ASSERT(is_exactly_a<symbol>(rel.lhs()));
+ GINAC_ASSERT(is_a<symbol>(rel.lhs()));
// method:
// Taylor series where there is no pole falls back to tanh_deriv.
// On a pole simply expand sinh(x)/cosh(x).
int order,
unsigned options)
{
- GINAC_ASSERT(is_exactly_a<symbol>(rel.lhs()));
+ GINAC_ASSERT(is_a<symbol>(rel.lhs()));
// method:
// Taylor series where there is no pole or cut falls back to atanh_deriv.
// There are two branch cuts, one runnig from 1 up the real axis and one
++k;
} else {
// search largest element in column co beginning at row ro
- GINAC_ASSERT(is_a<numeric>(this->m[k*col+co]));
+ GINAC_ASSERT(is_exactly_a<numeric>(this->m[k*col+co]));
unsigned kmax = k+1;
numeric mmax = abs(ex_to<numeric>(m[kmax*col+co]));
while (kmax<row) {
- GINAC_ASSERT(is_a<numeric>(this->m[kmax*col+co]));
+ GINAC_ASSERT(is_exactly_a<numeric>(this->m[kmax*col+co]));
numeric tmp = ex_to<numeric>(this->m[kmax*col+co]);
if (abs(tmp) > mmax) {
mmax = tmp;
// and all others
exvector neg_powers, others;
while (it != itend) {
- GINAC_ASSERT(is_a<numeric>(it->coeff));
+ GINAC_ASSERT(is_exactly_a<numeric>(it->coeff));
if (ex_to<numeric>(it->coeff).is_negative())
neg_powers.push_back(recombine_pair_to_ex(expair(it->rest, -(it->coeff))));
else
* @return "false" if no symbol was found, "true" otherwise */
static bool get_first_symbol(const ex &e, const symbol *&x)
{
- if (is_exactly_a<symbol>(e)) {
+ if (is_a<symbol>(e)) {
x = &ex_to<symbol>(e);
return true;
} else if (is_exactly_a<add>(e) || is_exactly_a<mul>(e)) {
// Collect all symbols of an expression (used internally by get_symbol_stats())
static void collect_symbols(const ex &e, sym_desc_vec &v)
{
- if (is_exactly_a<symbol>(e)) {
+ if (is_a<symbol>(e)) {
add_symbol(&ex_to<symbol>(e), v);
} else if (is_exactly_a<add>(e) || is_exactly_a<mul>(e)) {
for (unsigned i=0; i<e.nops(); i++)
c *= lcmcoeff(e.op(i), _num1);
return lcm(c, l);
} else if (is_exactly_a<power>(e)) {
- if (is_exactly_a<symbol>(e.op(0)))
+ if (is_a<symbol>(e.op(0)))
return l;
else
return pow(lcmcoeff(e.op(0), l), ex_to<numeric>(e.op(1)));
v.push_back(multiply_lcm(e.op(i), lcm));
return (new add(v))->setflag(status_flags::dynallocated);
} else if (is_exactly_a<power>(e)) {
- if (is_exactly_a<symbol>(e.op(0)))
+ if (is_a<symbol>(e.op(0)))
return e * lcm;
else
return pow(multiply_lcm(e.op(0), lcm.power(ex_to<numeric>(e.op(1)).inverse())), e.op(1));
*/
ex sqrfree(const ex &a, const lst &l)
{
- if (is_a<numeric>(a) || // algorithm does not trap a==0
+ if (is_exactly_a<numeric>(a) || // algorithm does not trap a==0
is_a<symbol>(a)) // shortcut
return a;
* to 1, unless you're accumulating factors). */
static ex find_common_factor(const ex & e, ex & factor, lst & repl)
{
- if (is_a<add>(e)) {
+ if (is_exactly_a<add>(e)) {
unsigned num = e.nops();
exvector terms; terms.reserve(num);
for (unsigned i=0; i<num; i++) {
ex x = e.op(i).to_rational(repl);
- if (is_a<add>(x) || is_a<mul>(x)) {
+ if (is_exactly_a<add>(x) || is_exactly_a<mul>(x)) {
ex f = 1;
x = find_common_factor(x, f, repl);
x *= f;
// Try to avoid divide() because it expands the polynomial
ex &t = terms[i];
- if (is_a<mul>(t)) {
+ if (is_exactly_a<mul>(t)) {
for (unsigned j=0; j<t.nops(); j++) {
if (t.op(j).is_equal(gc)) {
exvector v; v.reserve(t.nops());
}
return (new add(terms))->setflag(status_flags::dynallocated);
- } else if (is_a<mul>(e)) {
+ } else if (is_exactly_a<mul>(e)) {
unsigned num = e.nops();
exvector v; v.reserve(num);
return (new mul(v))->setflag(status_flags::dynallocated);
- } else if (is_a<power>(e)) {
+ } else if (is_exactly_a<power>(e)) {
ex x = e.to_rational(repl);
- if (is_a<power>(x) && x.op(1).info(info_flags::negative))
+ if (is_exactly_a<power>(x) && x.op(1).info(info_flags::negative))
return replace_with_symbol(x, repl);
else
return x;
* 'a*(b*x+b*y)' to 'a*b*(x+y)'. */
ex collect_common_factors(const ex & e)
{
- if (is_a<add>(e) || is_a<mul>(e)) {
+ if (is_exactly_a<add>(e) || is_exactly_a<mul>(e)) {
lst repl;
ex factor = 1;
// Integer powers of symbols are printed in a special, optimized way
if (exponent.info(info_flags::integer)
- && (is_exactly_a<symbol>(basis) || is_exactly_a<constant>(basis))) {
+ && (is_a<symbol>(basis) || is_a<constant>(basis))) {
int exp = ex_to<numeric>(exponent).to_int();
if (exp > 0)
c.s << '(';
bool is_tex = is_a<print_latex>(c);
- if (is_tex && is_a<numeric>(exponent) && ex_to<numeric>(exponent).is_negative()) {
+ if (is_tex && is_exactly_a<numeric>(exponent) && ex_to<numeric>(exponent).is_negative()) {
// Powers with negative numeric exponents are printed as fractions in TeX
c.s << "\\frac{1}{";
const ex ebasis = basis.evalm();
const ex eexponent = exponent.evalm();
if (is_a<matrix>(ebasis)) {
- if (is_a<numeric>(eexponent)) {
+ if (is_exactly_a<numeric>(eexponent)) {
return (new matrix(ex_to<matrix>(ebasis).pow(eexponent)))->setflag(status_flags::dynallocated);
}
}
* @return newly constructed pseries */
pseries::pseries(const ex &rel_, const epvector &ops_) : basic(TINFO_pseries), seq(ops_)
{
- GINAC_ASSERT(is_exactly_a<relational>(rel_));
- GINAC_ASSERT(is_exactly_a<symbol>(rel_.lhs()));
+ GINAC_ASSERT(is_a<relational>(rel_));
+ GINAC_ASSERT(is_a<symbol>(rel_.lhs()));
point = rel_.rhs();
var = rel_.lhs();
}
{
epvector seq;
const ex point = r.rhs();
- GINAC_ASSERT(is_exactly_a<symbol>(r.lhs()));
+ GINAC_ASSERT(is_a<symbol>(r.lhs()));
if (this->is_equal_same_type(ex_to<symbol>(r.lhs()))) {
if (order > 0 && !point.is_zero())
ex pseries::series(const relational & r, int order, unsigned options) const
{
const ex p = r.rhs();
- GINAC_ASSERT(is_exactly_a<symbol>(r.lhs()));
+ GINAC_ASSERT(is_a<symbol>(r.lhs()));
const symbol &s = ex_to<symbol>(r.lhs());
if (var.is_equal(s) && point.is_equal(p)) {
ex e;
relational rel_;
- if (is_exactly_a<relational>(r))
+ if (is_a<relational>(r))
rel_ = ex_to<relational>(r);
- else if (is_exactly_a<symbol>(r))
+ else if (is_a<symbol>(r))
rel_ = relational(r,_ex0);
else
throw (std::logic_error("ex::series(): expansion point has unknown type"));