- ex_to_foobar(baz) -> ex_to<foobar>(baz).
<< radical << endl;
errorflag = true;
}
- numeric ratio = ex_to_numeric(evalf(radical))/floating;
+ numeric ratio = ex_to<numeric>(evalf(radical))/floating;
if (ratio>1.0001 && ratio<0.9999) {
clog << "(" << num << "/" << den << ")^(" << nm
<< ") erroneously evaluated to " << radical;
}
e2 = test_int1 + a;
- if (ex_to_numeric(e2).is_integer()) {
+ if (ex_to<numeric>(e2).is_integer()) {
clog << "expression " << e2
<< " erroneously recognized as integer" << endl;
++result;
static unsigned check_series(const ex &e, const ex &point, const ex &d, int order = 8)
{
ex es = e.series(x==point, order);
- ex ep = ex_to_pseries(es).convert_to_poly();
+ ex ep = ex_to<pseries>(es).convert_to_poly();
if (!(ep - d).is_zero()) {
clog << "series expansion of " << e << " at " << point
<< " erroneously returned " << ep << " (instead of " << d
for (unsigned r=0; r<26; ++r) {
for (unsigned c=0; c<5; ++c) {
m.set(r,
- unsigned(ex_to_numeric(w[r][2*c+1]).to_int()-1),
+ unsigned(ex_to<numeric>(w[r][2*c+1]).to_int()-1),
w[r][2*c+2]);
}
}
for (unsigned r=0; r<101; ++r) {
for (unsigned c=0; c<10; ++c) {
m.set(r,
- unsigned(ex_to_numeric(w[r][2*c+1]).to_int()-1),
+ unsigned(ex_to<numeric>(w[r][2*c+1]).to_int()-1),
w[r][2*c+2]);
}
}
} else if (it->coeff.compare(_num_1()) == 0) {
c.s << "-";
it->rest.bp->print(c, precedence());
- } else if (ex_to_numeric(it->coeff).numer().compare(_num1()) == 0) {
+ } else if (ex_to<numeric>(it->coeff).numer().compare(_num1()) == 0) {
it->rest.bp->print(c, precedence());
c.s << "/";
- ex_to_numeric(it->coeff).denom().print(c, precedence());
- } else if (ex_to_numeric(it->coeff).numer().compare(_num_1()) == 0) {
+ ex_to<numeric>(it->coeff).denom().print(c, precedence());
+ } else if (ex_to<numeric>(it->coeff).numer().compare(_num_1()) == 0) {
c.s << "-";
it->rest.bp->print(c, precedence());
c.s << "/";
- ex_to_numeric(it->coeff).denom().print(c, precedence());
+ ex_to<numeric>(it->coeff).denom().print(c, precedence());
} else {
it->coeff.bp->print(c, precedence());
c.s << "*";
// Then proceed with the remaining factors
epvector::const_iterator it = seq.begin(), itend = seq.end();
while (it != itend) {
- coeff = ex_to_numeric(it->coeff);
+ coeff = ex_to<numeric>(it->coeff);
if (!first) {
if (coeff.csgn() == -1) c.s << '-'; else c.s << '+';
} else {
s->push_back(split_ex_to_pair(m));
if (is_ex_of_type(m, matrix)) {
if (first_term) {
- sum = ex_to_matrix(m);
+ sum = ex_to<matrix>(m);
first_term = false;
} else
- sum = sum.add(ex_to_matrix(m));
+ sum = sum.add(ex_to<matrix>(m));
} else
all_matrices = false;
it++;
expair add::split_ex_to_pair(const ex & e) const
{
if (is_ex_exactly_of_type(e,mul)) {
- const mul &mulref = ex_to_mul(e);
- ex numfactor(mulref.overall_coeff);
+ const mul &mulref(ex_to<mul>(e));
+ ex numfactor = mulref.overall_coeff;
mul *mulcopyp = new mul(mulref);
mulcopyp->overall_coeff = _ex1();
mulcopyp->clearflag(status_flags::evaluated);
{
GINAC_ASSERT(is_ex_exactly_of_type(c, numeric));
if (is_ex_exactly_of_type(e, mul)) {
- const mul &mulref = ex_to_mul(e);
- ex numfactor(mulref.overall_coeff);
+ const mul &mulref(ex_to<mul>(e));
+ ex numfactor = mulref.overall_coeff;
mul *mulcopyp = new mul(mulref);
mulcopyp->overall_coeff = _ex1();
mulcopyp->clearflag(status_flags::evaluated);
else if (are_ex_trivially_equal(numfactor, _ex1()))
return expair(*mulcopyp, c);
else
- return expair(*mulcopyp, ex_to_numeric(numfactor).mul_dyn(ex_to_numeric(c)));
+ return expair(*mulcopyp, ex_to<numeric>(numfactor).mul_dyn(ex_to<numeric>(c)));
} else if (is_ex_exactly_of_type(e, numeric)) {
if (are_ex_trivially_equal(c, _ex1()))
return expair(e, _ex1());
- return expair(ex_to_numeric(e).mul_dyn(ex_to_numeric(c)), _ex1());
+ return expair(ex_to<numeric>(e).mul_dyn(ex_to<numeric>(c)), _ex1());
}
return expair(e, c);
}
GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
if (is_ex_exactly_of_type(p.rest,numeric)) {
- GINAC_ASSERT(ex_to_numeric(p.coeff).is_equal(_num1())); // should be normalized
- return expair(ex_to_numeric(p.rest).mul_dyn(ex_to_numeric(c)),_ex1());
+ GINAC_ASSERT(ex_to<numeric>(p.coeff).is_equal(_num1())); // should be normalized
+ return expair(ex_to<numeric>(p.rest).mul_dyn(ex_to<numeric>(c)),_ex1());
}
- return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c)));
+ return expair(p.rest,ex_to<numeric>(p.coeff).mul_dyn(ex_to<numeric>(c)));
}
ex add::recombine_pair_to_ex(const expair & p) const
{
- if (ex_to_numeric(p.coeff).is_equal(_num1()))
+ if (ex_to<numeric>(p.coeff).is_equal(_num1()))
return p.rest;
else
return p.rest*p.coeff;
// utility functions
-/** Return the add object handled by an ex.
+/** Return the add object handled by an ex. Deprecated: use ex_to<add>().
* This is unsafe: you need to check the type first. */
inline const add &ex_to_add(const ex &e)
{
/** Check if obj is a T, including base classes. */
template <class T>
inline bool is_a(const basic & obj)
-{ return dynamic_cast<const T *>(&obj)!=0; }
+{
+ return dynamic_cast<const T *>(&obj)!=0;
+}
/** Check if obj is a T, not including base classes. This one is just an
* inefficient default. It should in all time-critical cases be overridden
* by template specializations that don't create a temporary. */
template <class T>
inline bool is_exactly_a(const class basic & obj)
-{ const T foo; return foo.tinfo()==obj.tinfo(); }
+{
+ const T foo; return foo.tinfo()==obj.tinfo();
+}
/** Check if ex is a handle to a T, including base classes. */
template <class T>
inline bool is_a(const ex & obj)
-{ return is_a<T>(*obj.bp); }
+{
+ return is_a<T>(*obj.bp);
+}
/** Check if ex is a handle to a T, not including base classes. */
template <class T>
inline bool is_exactly_a(const ex & obj)
-{ return is_exactly_a<T>(*obj.bp); }
+{
+ return is_exactly_a<T>(*obj.bp);
+}
+
+/** Return a reference to the basic-derived class T object embedded in an
+ * expression. This is fast but unsafe: the result is undefined if the
+ * expression does not contain a T object at its top level.
+ *
+ * @param e expression
+ * @return reference to pseries object
+ * @see is_exactly_a<class T>() */
+template <class T>
+inline const T &ex_to(const ex &e)
+{
+ return static_cast<const T &>(*e.bp);
+}
} // namespace GiNaC
GINAC_ASSERT(is_ex_of_type(*self, clifford));
GINAC_ASSERT(is_ex_of_type(*other, indexed));
GINAC_ASSERT(is_ex_of_type(self->op(0), diracgamma));
- unsigned char rl = ex_to_clifford(*self).get_representation_label();
+ unsigned char rl = ex_to<clifford>(*self).get_representation_label();
if (is_ex_of_type(*other, clifford)) {
- ex dim = ex_to_idx(self->op(1)).get_dim();
+ ex dim = ex_to<idx>(self->op(1)).get_dim();
// gamma~mu gamma.mu = dim ONE
if (other - self == 1) {
{
if (is_ex_of_type(e, clifford)) {
- if (ex_to_clifford(e).get_representation_label() == rl
+ if (ex_to<clifford>(e).get_representation_label() == rl
&& is_ex_of_type(e.op(0), diracone))
return trONE;
else
// global functions
-/** Return the clifford object handled by an ex.
+/** Return the clifford object handled by an ex. Deprecated: use ex_to<clifford>().
* This is unsafe: you need to check the type first. */
inline const clifford &ex_to_clifford(const ex &e)
{
// Sort indices
int v[3];
for (unsigned j=0; j<3; j++)
- v[j] = ex_to_numeric(ex_to_idx(i.op(j + 1)).get_value()).to_int();
+ v[j] = ex_to<numeric>(ex_to<idx>(i.op(j + 1)).get_value()).to_int();
if (v[0] > v[1]) std::swap(v[0], v[1]);
if (v[0] > v[2]) std::swap(v[0], v[2]);
if (v[1] > v[2]) std::swap(v[1], v[2]);
// Sort indices, remember permutation sign
int v[3];
for (unsigned j=0; j<3; j++)
- v[j] = ex_to_numeric(ex_to_idx(i.op(j + 1)).get_value()).to_int();
+ v[j] = ex_to<numeric>(ex_to<idx>(i.op(j + 1)).get_value()).to_int();
int sign = 1;
if (v[0] > v[1]) { std::swap(v[0], v[1]); sign = -sign; }
if (v[0] > v[2]) { std::swap(v[0], v[2]); sign = -sign; }
GINAC_ASSERT(is_ex_of_type(*other, indexed));
GINAC_ASSERT(self->nops() == 2);
GINAC_ASSERT(is_ex_of_type(self->op(0), su3t));
- unsigned char rl = ex_to_color(*self).get_representation_label();
+ unsigned char rl = ex_to<color>(*self).get_representation_label();
if (is_ex_exactly_of_type(other->op(0), su3t)) {
if (is_ex_exactly_of_type(other->op(0), su3d)) {
// Find the dummy indices of the contraction
- exvector self_indices = ex_to_indexed(*self).get_indices();
- exvector other_indices = ex_to_indexed(*other).get_indices();
+ exvector self_indices = ex_to<indexed>(*self).get_indices();
+ exvector other_indices = ex_to<indexed>(*other).get_indices();
exvector all_indices = self_indices;
all_indices.insert(all_indices.end(), other_indices.begin(), other_indices.end());
exvector free_indices, dummy_indices;
// d.abc T.b T.c = 5/6 T.a
if (other+1 != v.end()
&& is_ex_exactly_of_type(other[1].op(0), su3t)
- && ex_to_indexed(*self).has_dummy_index_for(other[1].op(1))) {
+ && ex_to<indexed>(*self).has_dummy_index_for(other[1].op(1))) {
- exvector self_indices = ex_to_indexed(*self).get_indices();
+ exvector self_indices = ex_to<indexed>(*self).get_indices();
exvector dummy_indices;
dummy_indices.push_back(other[0].op(1));
dummy_indices.push_back(other[1].op(1));
int sig;
ex a = permute_free_index_to_front(self_indices, dummy_indices, sig);
*self = numeric(5, 6);
- other[0] = color_T(a, ex_to_color(other[0]).get_representation_label());
+ other[0] = color_T(a, ex_to<color>(other[0]).get_representation_label());
other[1] = _ex1();
return true;
}
// Find the dummy indices of the contraction
exvector dummy_indices;
- dummy_indices = ex_to_indexed(*self).get_dummy_indices(ex_to_indexed(*other));
+ dummy_indices = ex_to<indexed>(*self).get_dummy_indices(ex_to<indexed>(*other));
// f.abc f.abc = 24
if (dummy_indices.size() == 3) {
// f.akl f.bkl = 3 delta.ab
} else if (dummy_indices.size() == 2) {
int sign1, sign2;
- ex a = permute_free_index_to_front(ex_to_indexed(*self).get_indices(), dummy_indices, sign1);
- ex b = permute_free_index_to_front(ex_to_indexed(*other).get_indices(), dummy_indices, sign2);
+ ex a = permute_free_index_to_front(ex_to<indexed>(*self).get_indices(), dummy_indices, sign1);
+ ex b = permute_free_index_to_front(ex_to<indexed>(*other).get_indices(), dummy_indices, sign2);
*self = sign1 * sign2 * 3 * delta_tensor(a, b);
*other = _ex1();
return true;
// f.abc T.b T.c = 3/2 I T.a
if (other+1 != v.end()
&& is_ex_exactly_of_type(other[1].op(0), su3t)
- && ex_to_indexed(*self).has_dummy_index_for(other[1].op(1))) {
+ && ex_to<indexed>(*self).has_dummy_index_for(other[1].op(1))) {
- exvector self_indices = ex_to_indexed(*self).get_indices();
+ exvector self_indices = ex_to<indexed>(*self).get_indices();
exvector dummy_indices;
dummy_indices.push_back(other[0].op(1));
dummy_indices.push_back(other[1].op(1));
int sig;
ex a = permute_free_index_to_front(self_indices, dummy_indices, sig);
*self = numeric(3, 2) * sig * I;
- other[0] = color_T(a, ex_to_color(other[0]).get_representation_label());
+ other[0] = color_T(a, ex_to<color>(other[0]).get_representation_label());
other[1] = _ex1();
return true;
}
{
if (!is_ex_of_type(a, idx))
throw(std::invalid_argument("indices of color_T must be of type idx"));
- if (!ex_to_idx(a).get_dim().is_equal(8))
+ if (!ex_to<idx>(a).get_dim().is_equal(8))
throw(std::invalid_argument("index dimension for color_T must be 8"));
return color(su3t(), a, rl);
{
if (!is_ex_of_type(a, idx) || !is_ex_of_type(b, idx) || !is_ex_of_type(c, idx))
throw(std::invalid_argument("indices of color_f must be of type idx"));
- if (!ex_to_idx(a).get_dim().is_equal(8) || !ex_to_idx(b).get_dim().is_equal(8) || !ex_to_idx(c).get_dim().is_equal(8))
+ if (!ex_to<idx>(a).get_dim().is_equal(8) || !ex_to<idx>(b).get_dim().is_equal(8) || !ex_to<idx>(c).get_dim().is_equal(8))
throw(std::invalid_argument("index dimension for color_f must be 8"));
return indexed(su3f(), sy_anti(), a, b, c);
{
if (!is_ex_of_type(a, idx) || !is_ex_of_type(b, idx) || !is_ex_of_type(c, idx))
throw(std::invalid_argument("indices of color_d must be of type idx"));
- if (!ex_to_idx(a).get_dim().is_equal(8) || !ex_to_idx(b).get_dim().is_equal(8) || !ex_to_idx(c).get_dim().is_equal(8))
+ if (!ex_to<idx>(a).get_dim().is_equal(8) || !ex_to<idx>(b).get_dim().is_equal(8) || !ex_to<idx>(c).get_dim().is_equal(8))
throw(std::invalid_argument("index dimension for color_d must be 8"));
return indexed(su3d(), sy_symm(), a, b, c);
{
if (is_ex_of_type(e, color)) {
- if (ex_to_color(e).get_representation_label() == rl
+ if (ex_to<color>(e).get_representation_label() == rl
&& is_ex_of_type(e.op(0), su3one))
return _ex3();
else
// global functions
-/** Return the color object handled by an ex.
+/** Return the color object handled by an ex. Deprecated: use ex_to<color>().
* This is unsafe: you need to check the type first. */
inline const color &ex_to_color(const ex &e)
{
// utility functions
-/** Return the constant object handled by an ex.
+/** Return the constant object handled by an ex. Deprecated: use ex_to<constant>().
* This is unsafe: you need to check the type first. */
inline const constant &ex_to_constant(const ex &e)
{
// utility functions
-/** Return the ${CONTAINER} object handled by an ex.
+/** Return the ${CONTAINER} object handled by an ex. Deprecated: use ex_to<${CONTAINER}>().
* This is unsafe: you need to check the type first. */
inline const ${CONTAINER} &ex_to_${CONTAINER}(const ex &e)
{
GINAC_ASSERT(is_ex_exactly_of_type(p.coeff,numeric));
GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
- return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c)));
+ return expair(p.rest,ex_to<numeric>(p.coeff).mul_dyn(ex_to<numeric>(c)));
}
{
GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
- overall_coeff = ex_to_numeric(overall_coeff).add_dyn(ex_to_numeric(c));
+ overall_coeff = ex_to<numeric>(overall_coeff).add_dyn(ex_to<numeric>(c));
}
void expairseq::combine_overall_coeff(const ex &c1, const ex &c2)
GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
GINAC_ASSERT(is_ex_exactly_of_type(c1,numeric));
GINAC_ASSERT(is_ex_exactly_of_type(c2,numeric));
- overall_coeff = ex_to_numeric(overall_coeff).
- add_dyn(ex_to_numeric(c1).mul(ex_to_numeric(c2)));
+ overall_coeff = ex_to<numeric>(overall_coeff).
+ add_dyn(ex_to<numeric>(c1).mul(ex_to<numeric>(c2)));
}
bool expairseq::can_make_flat(const expair &p) const
if (lh.bp->tinfo()==tinfo()) {
if (rh.bp->tinfo()==tinfo()) {
#if EXPAIRSEQ_USE_HASHTAB
- unsigned totalsize = ex_to_expairseq(lh).seq.size() +
- ex_to_expairseq(rh).seq.size();
+ unsigned totalsize = ex_to<expairseq>(lh).seq.size() +
+ ex_to<expairseq>(rh).seq.size();
if (calc_hashtabsize(totalsize)!=0) {
construct_from_2_ex_via_exvector(lh,rh);
} else {
#endif // EXPAIRSEQ_USE_HASHTAB
- construct_from_2_expairseq(ex_to_expairseq(lh),
- ex_to_expairseq(rh));
+ construct_from_2_expairseq(ex_to<expairseq>(lh),
+ ex_to<expairseq>(rh));
#if EXPAIRSEQ_USE_HASHTAB
}
#endif // EXPAIRSEQ_USE_HASHTAB
return;
} else {
#if EXPAIRSEQ_USE_HASHTAB
- unsigned totalsize = ex_to_expairseq(lh).seq.size()+1;
+ unsigned totalsize = ex_to<expairseq>(lh).seq.size()+1;
if (calc_hashtabsize(totalsize)!=0) {
construct_from_2_ex_via_exvector(lh, rh);
} else {
#endif // EXPAIRSEQ_USE_HASHTAB
- construct_from_expairseq_ex(ex_to_expairseq(lh), rh);
+ construct_from_expairseq_ex(ex_to<expairseq>(lh), rh);
#if EXPAIRSEQ_USE_HASHTAB
}
#endif // EXPAIRSEQ_USE_HASHTAB
}
} else if (rh.bp->tinfo()==tinfo()) {
#if EXPAIRSEQ_USE_HASHTAB
- unsigned totalsize=ex_to_expairseq(rh).seq.size()+1;
+ unsigned totalsize=ex_to<expairseq>(rh).seq.size()+1;
if (calc_hashtabsize(totalsize)!=0) {
construct_from_2_ex_via_exvector(lh,rh);
} else {
#endif // EXPAIRSEQ_USE_HASHTAB
- construct_from_expairseq_ex(ex_to_expairseq(rh),lh);
+ construct_from_expairseq_ex(ex_to<expairseq>(rh),lh);
#if EXPAIRSEQ_USE_HASHTAB
}
#endif // EXPAIRSEQ_USE_HASHTAB
int cmpval = p1.rest.compare(p2.rest);
if (cmpval==0) {
- p1.coeff=ex_to_numeric(p1.coeff).add_dyn(ex_to_numeric(p2.coeff));
- if (!ex_to_numeric(p1.coeff).is_zero()) {
+ p1.coeff=ex_to<numeric>(p1.coeff).add_dyn(ex_to<numeric>(p2.coeff));
+ if (!ex_to<numeric>(p1.coeff).is_zero()) {
// no further processing is necessary, since this
// one element will usually be recombined in eval()
seq.push_back(p1);
int cmpval = (*first1).rest.compare((*first2).rest);
if (cmpval==0) {
// combine terms
- const numeric &newcoeff = ex_to_numeric((*first1).coeff).
- add(ex_to_numeric((*first2).coeff));
+ const numeric &newcoeff = ex_to<numeric>((*first1).coeff).
+ add(ex_to<numeric>((*first2).coeff));
if (!newcoeff.is_zero()) {
seq.push_back(expair((*first1).rest,newcoeff));
if (expair_needs_further_processing(seq.end()-1)) {
int cmpval=(*first).rest.compare(p.rest);
if (cmpval==0) {
// combine terms
- const numeric &newcoeff = ex_to_numeric((*first).coeff).
- add(ex_to_numeric(p.coeff));
+ const numeric &newcoeff = ex_to<numeric>((*first).coeff).
+ add(ex_to<numeric>(p.coeff));
if (!newcoeff.is_zero()) {
seq.push_back(expair((*first).rest,newcoeff));
if (expair_needs_further_processing(seq.end()-1)) {
while (cit!=v.end()) {
if (cit->bp->tinfo()==this->tinfo()) {
++nexpairseqs;
- noperands += ex_to_expairseq(*cit).seq.size();
+ noperands += ex_to<expairseq>(*cit).seq.size();
}
++cit;
}
cit = v.begin();
while (cit!=v.end()) {
if (cit->bp->tinfo()==this->tinfo()) {
- const expairseq &subseqref = ex_to_expairseq(*cit);
+ const expairseq &subseqref = ex_to<expairseq>(*cit);
combine_overall_coeff(subseqref.overall_coeff);
epvector::const_iterator cit_s = subseqref.seq.begin();
while (cit_s!=subseqref.seq.end()) {
while (cit!=v.end()) {
if (cit->rest.bp->tinfo()==this->tinfo()) {
++nexpairseqs;
- noperands += ex_to_expairseq((*cit).rest).seq.size();
+ noperands += ex_to<expairseq>((*cit).rest).seq.size();
}
++cit;
}
while (cit!=v.end()) {
if (cit->rest.bp->tinfo()==this->tinfo() &&
this->can_make_flat(*cit)) {
- const expairseq &subseqref = ex_to_expairseq((*cit).rest);
- combine_overall_coeff(ex_to_numeric(subseqref.overall_coeff),
- ex_to_numeric((*cit).coeff));
+ const expairseq &subseqref = ex_to<expairseq>((*cit).rest);
+ combine_overall_coeff(ex_to<numeric>(subseqref.overall_coeff),
+ ex_to<numeric>((*cit).coeff));
epvector::const_iterator cit_s = subseqref.seq.begin();
while (cit_s!=subseqref.seq.end()) {
seq.push_back(expair((*cit_s).rest,
- ex_to_numeric((*cit_s).coeff).mul_dyn(ex_to_numeric((*cit).coeff))));
+ ex_to<numeric>((*cit_s).coeff).mul_dyn(ex_to<numeric>((*cit).coeff))));
//seq.push_back(combine_pair_with_coeff_to_pair(*cit_s,
// (*cit).coeff));
++cit_s;
bool must_copy = false;
while (itin2!=last) {
if ((*itin1).rest.compare((*itin2).rest)==0) {
- (*itin1).coeff = ex_to_numeric((*itin1).coeff).
- add_dyn(ex_to_numeric((*itin2).coeff));
+ (*itin1).coeff = ex_to<numeric>((*itin1).coeff).
+ add_dyn(ex_to<numeric>((*itin2).coeff));
if (expair_needs_further_processing(itin1))
needs_further_processing = true;
must_copy = true;
} else {
- if (!ex_to_numeric((*itin1).coeff).is_zero()) {
+ if (!ex_to<numeric>((*itin1).coeff).is_zero()) {
if (must_copy)
*itout = *itin1;
++itout;
}
++itin2;
}
- if (!ex_to_numeric((*itin1).coeff).is_zero()) {
+ if (!ex_to<numeric>((*itin1).coeff).is_zero()) {
if (must_copy)
*itout = *itin1;
++itout;
++current;
} else {
// epplit points to a matching expair, combine it with current
- (*(*epplit)).coeff = ex_to_numeric((*(*epplit)).coeff).
- add_dyn(ex_to_numeric((*current).coeff));
+ (*(*epplit)).coeff = ex_to<numeric>((*(*epplit)).coeff).
+ add_dyn(ex_to<numeric>((*current).coeff));
// move obsolete current expair to end by swapping with last_non_zero element
// if this was a numeric, it is swapped with the expair before first_numeric
if (!touched[i]) {
++current;
++i;
- } else if (!ex_to_numeric((*current).coeff).is_zero()) {
+ } else if (!ex_to<numeric>((*current).coeff).is_zero()) {
++current;
++i;
} else {
// utility functions
-/** Return the expairseq object handled by an ex.
+/** Return the expairseq object handled by an ex. Deprecated: use ex_to<expairseq>().
* This is unsafe: you need to check the type first. */
inline const expairseq &ex_to_expairseq(const ex &e)
{
if (seq.size() > 1 && !(opt.symtree.is_zero())) {
exvector v = seq;
GINAC_ASSERT(is_ex_exactly_of_type(opt.symtree, symmetry));
- int sig = canonicalize(v.begin(), ex_to_symmetry(opt.symtree));
+ int sig = canonicalize(v.begin(), ex_to<symmetry>(opt.symtree));
if (sig != INT_MAX) {
// Something has changed while sorting arguments, more evaluations later
if (sig == 0)
bool function::match(const ex & pattern, lst & repl_lst) const
{
// Serial number must match
- if (is_ex_of_type(pattern, function) && serial != ex_to_function(pattern).serial)
+ if (is_ex_of_type(pattern, function) && serial != ex_to<function>(pattern).serial)
return false;
return inherited::match(pattern, repl_lst);
}
for (unsigned i=0; i!=fcn.nops(); i++) {
arg_diff = fcn.op(i).diff(s);
if (!arg_diff.is_zero()) {
- lst new_lst = ex_to_lst(seq[1]);
+ lst new_lst = ex_to<lst>(seq[1]);
new_lst.append(i);
result += arg_diff * Derivative(fcn, new_lst);
}
{
if (!is_ex_of_type(pattern, idx))
return false;
- const idx &o = ex_to_idx(pattern);
+ const idx &o = ex_to<idx>(pattern);
if (!dim.is_equal(o.dim))
return false;
return value.match(o.value, repl_lst);
{
if (!is_ex_of_type(pattern, varidx))
return false;
- const varidx &o = ex_to_varidx(pattern);
+ const varidx &o = ex_to<varidx>(pattern);
if (covariant != o.covariant)
return false;
return inherited::match(pattern, repl_lst);
{
if (!is_ex_of_type(pattern, spinidx))
return false;
- const spinidx &o = ex_to_spinidx(pattern);
+ const spinidx &o = ex_to<spinidx>(pattern);
if (dotted != o.dotted)
return false;
return inherited::match(pattern, repl_lst);
if (!is_ex_of_type(e1, idx) || !is_ex_of_type(e2, idx))
return false;
- return is_dummy_pair(ex_to_idx(e1), ex_to_idx(e2));
+ return is_dummy_pair(ex_to<idx>(e1), ex_to<idx>(e2));
}
void find_free_and_dummy(exvector::const_iterator it, exvector::const_iterator itend, exvector & out_free, exvector & out_dummy)
// Only one index? Then it is a free one if it's not numeric
if (itend - it == 1) {
- if (ex_to_idx(*it).is_symbolic())
+ if (ex_to<idx>(*it).is_symbolic())
out_free.push_back(*it);
return;
}
if (it == itend)
return;
} else {
- if (!it->is_equal(*last) && ex_to_idx(*last).is_symbolic())
+ if (!it->is_equal(*last) && ex_to<idx>(*last).is_symbolic())
out_free.push_back(*last);
}
last = it++;
}
- if (ex_to_idx(*last).is_symbolic())
+ if (ex_to<idx>(*last).is_symbolic())
out_free.push_back(*last);
}
// utility functions
-/** Return the idx object handled by an ex.
+/** Return the idx object handled by an ex. Deprecated: use ex_to<idx>().
* This is unsafe: you need to check the type first. */
inline const idx &ex_to_idx(const ex & e)
{
return static_cast<const idx &>(*e.bp);
}
-/** Return the varidx object handled by an ex.
+/** Return the varidx object handled by an ex. Deprecated: use ex_to<varidx>().
* This is unsafe: you need to check the type first. */
inline const varidx &ex_to_varidx(const ex & e)
{
return static_cast<const varidx &>(*e.bp);
}
-/** Return the spinidx object handled by an ex.
+/** Return the spinidx object handled by an ex. Deprecated: use ex_to<spinidx>().
* This is unsafe: you need to check the type first. */
inline const spinidx &ex_to_spinidx(const ex & e)
{
struct idx_is_not : public std::binary_function<ex, unsigned, bool> {
bool operator() (const ex & e, unsigned inf) const {
- return !(ex_to_idx(e).get_value().info(inf));
+ return !(ex_to<idx>(e).get_value().info(inf));
}
};
{
// First evaluate children, then we will end up here again
if (level > 1)
- return indexed(ex_to_symmetry(symtree), evalchildren(level));
+ return indexed(ex_to<symmetry>(symtree), evalchildren(level));
const ex &base = seq[0];
// If the base object is a product, pull out the numeric factor
if (is_ex_exactly_of_type(base, mul) && is_ex_exactly_of_type(base.op(base.nops() - 1), numeric)) {
exvector v(seq);
- ex f = ex_to_numeric(base.op(base.nops() - 1));
+ ex f = ex_to<numeric>(base.op(base.nops() - 1));
v[0] = seq[0] / f;
return f * thisexprseq(v);
}
if (seq.size() > 2) {
exvector v = seq;
GINAC_ASSERT(is_ex_exactly_of_type(symtree, symmetry));
- int sig = canonicalize(v.begin() + 1, ex_to_symmetry(symtree));
+ int sig = canonicalize(v.begin() + 1, ex_to<symmetry>(symtree));
if (sig != INT_MAX) {
// Something has changed while sorting indices, more evaluations later
if (sig == 0)
ex indexed::thisexprseq(const exvector & v) const
{
- return indexed(ex_to_symmetry(symtree), v);
+ return indexed(ex_to<symmetry>(symtree), v);
}
ex indexed::thisexprseq(exvector * vp) const
{
- return indexed(ex_to_symmetry(symtree), vp);
+ return indexed(ex_to<symmetry>(symtree), vp);
}
ex indexed::expand(unsigned options) const
bool covariant = true;
while (it != itend) {
- bool cur_covariant = (is_ex_of_type(*it, varidx) ? ex_to_varidx(*it).is_covariant() : true);
+ bool cur_covariant = (is_ex_of_type(*it, varidx) ? ex_to<varidx>(*it).is_covariant() : true);
if (first || cur_covariant != covariant) {
if (!first)
c.s << "}";
// Indexed factor found, get free indices and look for contraction
// candidates
exvector free1, dummy1;
- find_free_and_dummy(ex_to_indexed(*it1).seq.begin() + 1, ex_to_indexed(*it1).seq.end(), free1, dummy1);
+ find_free_and_dummy(ex_to<indexed>(*it1).seq.begin() + 1, ex_to<indexed>(*it1).seq.end(), free1, dummy1);
exvector::iterator it2;
for (it2 = it1 + 1; it2 != itend; it2++) {
// Find free indices of second factor and merge them with free
// indices of first factor
exvector un;
- find_free_and_dummy(ex_to_indexed(*it2).seq.begin() + 1, ex_to_indexed(*it2).seq.end(), un, dummy1);
+ find_free_and_dummy(ex_to<indexed>(*it2).seq.begin() + 1, ex_to<indexed>(*it2).seq.end(), un, dummy1);
un.insert(un.end(), free1.begin(), free1.end());
// Check whether the two factors share dummy indices
// Contraction of symmetric with antisymmetric object is zero
if (dummy.size() > 1
- && ex_to_symmetry(ex_to_indexed(*it1).symtree).has_symmetry()
- && ex_to_symmetry(ex_to_indexed(*it2).symtree).has_symmetry()) {
+ && ex_to<symmetry>(ex_to<indexed>(*it1).symtree).has_symmetry()
+ && ex_to<symmetry>(ex_to<indexed>(*it2).symtree).has_symmetry()) {
// Check all pairs of dummy indices
for (unsigned idx1=0; idx1<dummy.size()-1; idx1++) {
exvector free_indices_of_factor;
if (is_ex_of_type(*it1, indexed)) {
exvector dummy_indices_of_factor;
- find_free_and_dummy(ex_to_indexed(*it1).seq.begin() + 1, ex_to_indexed(*it1).seq.end(), free_indices_of_factor, dummy_indices_of_factor);
+ find_free_and_dummy(ex_to<indexed>(*it1).seq.begin() + 1, ex_to<indexed>(*it1).seq.end(), free_indices_of_factor, dummy_indices_of_factor);
individual_dummy_indices.insert(individual_dummy_indices.end(), dummy_indices_of_factor.begin(), dummy_indices_of_factor.end());
} else
free_indices_of_factor = it1->get_free_indices();
// Product of indexed object with a scalar?
if (is_ex_exactly_of_type(r, mul) && r.nops() == 2
&& is_ex_exactly_of_type(r.op(1), numeric) && is_ex_of_type(r.op(0), indexed))
- return r.op(0).op(0).bp->scalar_mul_indexed(r.op(0), ex_to_numeric(r.op(1)));
+ return r.op(0).op(0).bp->scalar_mul_indexed(r.op(0), ex_to<numeric>(r.op(1)));
else
return r;
}
// Simplification of single indexed object: just find the free indices
// and perform dummy index renaming
if (is_ex_of_type(e_expanded, indexed)) {
- const indexed &i = ex_to_indexed(e_expanded);
+ const indexed &i = ex_to<indexed>(e_expanded);
exvector local_dummy_indices;
find_free_and_dummy(i.seq.begin() + 1, i.seq.end(), free_indices, local_dummy_indices);
return rename_dummy_indices(e_expanded, dummy_indices, local_dummy_indices);
// utility functions
-/** Return the indexed object handled by an ex.
+/** Return the indexed object handled by an ex. Deprecated: use ex_to<indexed>().
* This is unsafe: you need to check the type first. */
inline const indexed &ex_to_indexed(const ex &e)
{
TYPECHECK(arg,numeric)
END_TYPECHECK(abs(arg))
- return abs(ex_to_numeric(arg));
+ return abs(ex_to<numeric>(arg));
}
static ex abs_eval(const ex & arg)
{
if (is_ex_exactly_of_type(arg, numeric))
- return abs(ex_to_numeric(arg));
+ return abs(ex_to<numeric>(arg));
else
return abs(arg).hold();
}
TYPECHECK(arg,numeric)
END_TYPECHECK(csgn(arg))
- return csgn(ex_to_numeric(arg));
+ return csgn(ex_to<numeric>(arg));
}
static ex csgn_eval(const ex & arg)
{
if (is_ex_exactly_of_type(arg, numeric))
- return csgn(ex_to_numeric(arg));
+ return csgn(ex_to<numeric>(arg));
else if (is_ex_of_type(arg, mul) &&
is_ex_of_type(arg.op(arg.nops()-1),numeric)) {
- numeric oc = ex_to_numeric(arg.op(arg.nops()-1));
+ numeric oc = ex_to<numeric>(arg.op(arg.nops()-1));
if (oc.is_real()) {
if (oc > 0)
// csgn(42*x) -> csgn(x)
{
const ex arg_pt = arg.subs(rel);
if (arg_pt.info(info_flags::numeric)
- && ex_to_numeric(arg_pt).real().is_zero()
+ && ex_to<numeric>(arg_pt).real().is_zero()
&& !(options & series_options::suppress_branchcut))
throw (std::domain_error("csgn_series(): on imaginary axis"));
TYPECHECK(y,numeric)
END_TYPECHECK(eta(x,y))
- numeric xim = imag(ex_to_numeric(x));
- numeric yim = imag(ex_to_numeric(y));
- numeric xyim = imag(ex_to_numeric(x*y));
+ numeric xim = imag(ex_to<numeric>(x));
+ numeric yim = imag(ex_to<numeric>(y));
+ numeric xyim = imag(ex_to<numeric>(x*y));
return evalf(I/4*Pi)*((csgn(-xim)+1)*(csgn(-yim)+1)*(csgn(xyim)+1)-(csgn(xim)+1)*(csgn(yim)+1)*(csgn(-xyim)+1));
}
if (is_ex_exactly_of_type(x, numeric) &&
is_ex_exactly_of_type(y, numeric)) {
// don't call eta_evalf here because it would call Pi.evalf()!
- numeric xim = imag(ex_to_numeric(x));
- numeric yim = imag(ex_to_numeric(y));
- numeric xyim = imag(ex_to_numeric(x*y));
+ numeric xim = imag(ex_to<numeric>(x));
+ numeric yim = imag(ex_to<numeric>(y));
+ numeric xyim = imag(ex_to<numeric>(x*y));
return (I/4)*Pi*((csgn(-xim)+1)*(csgn(-yim)+1)*(csgn(xyim)+1)-(csgn(xim)+1)*(csgn(yim)+1)*(csgn(-xyim)+1));
}
{
const ex arg1_pt = arg1.subs(rel);
const ex arg2_pt = arg2.subs(rel);
- if (ex_to_numeric(arg1_pt).imag().is_zero() ||
- ex_to_numeric(arg2_pt).imag().is_zero() ||
- ex_to_numeric(arg1_pt*arg2_pt).imag().is_zero()) {
+ if (ex_to<numeric>(arg1_pt).imag().is_zero() ||
+ ex_to<numeric>(arg2_pt).imag().is_zero() ||
+ ex_to<numeric>(arg1_pt*arg2_pt).imag().is_zero()) {
throw (std::domain_error("eta_series(): on discontinuity"));
}
epvector seq;
TYPECHECK(x,numeric)
END_TYPECHECK(Li2(x))
- return Li2(ex_to_numeric(x)); // -> numeric Li2(numeric)
+ return Li2(ex_to<numeric>(x)); // -> numeric Li2(numeric)
}
static ex Li2_eval(const ex & x)
}
// third special case: x real, >=1 (branch cut)
if (!(options & series_options::suppress_branchcut) &&
- ex_to_numeric(x_pt).is_real() && ex_to_numeric(x_pt)>1) {
+ ex_to<numeric>(x_pt).is_real() && ex_to<numeric>(x_pt)>1) {
// method:
// This is the branch cut: assemble the primitive series manually
// and then add the corresponding complex step function.
static ex factorial_eval(const ex & x)
{
if (is_ex_exactly_of_type(x, numeric))
- return factorial(ex_to_numeric(x));
+ return factorial(ex_to<numeric>(x));
else
return factorial(x).hold();
}
static ex binomial_eval(const ex & x, const ex &y)
{
if (is_ex_exactly_of_type(x, numeric) && is_ex_exactly_of_type(y, numeric))
- return binomial(ex_to_numeric(x), ex_to_numeric(y));
+ return binomial(ex_to<numeric>(x), ex_to<numeric>(y));
else
return binomial(x, y).hold();
}
ex eq = eqns.op(r).op(0)-eqns.op(r).op(1); // lhs-rhs==0
ex linpart = eq;
for (unsigned c=0; c<symbols.nops(); c++) {
- ex co = eq.coeff(ex_to_symbol(symbols.op(c)),1);
+ ex co = eq.coeff(ex_to<symbol>(symbols.op(c)),1);
linpart -= co*symbols.op(c);
sys(r,c) = co;
}
TYPECHECK(x,numeric)
END_TYPECHECK(lgamma(x))
- return lgamma(ex_to_numeric(x));
+ return lgamma(ex_to<numeric>(x));
}
if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
throw do_taylor(); // caught by function::series()
// if we got here we have to care for a simple pole of tgamma(-m):
- numeric m = -ex_to_numeric(arg_pt);
+ numeric m = -ex_to<numeric>(arg_pt);
ex recur;
for (numeric p; p<=m; ++p)
recur += log(arg+p);
TYPECHECK(x,numeric)
END_TYPECHECK(tgamma(x))
- return tgamma(ex_to_numeric(x));
+ return tgamma(ex_to<numeric>(x));
}
if (x.info(info_flags::integer)) {
// tgamma(n) -> (n-1)! for postitive n
if (x.info(info_flags::posint)) {
- return factorial(ex_to_numeric(x).sub(_num1()));
+ return factorial(ex_to<numeric>(x).sub(_num1()));
} else {
throw (pole_error("tgamma_eval(): simple pole",1));
}
// trap positive x==(n+1/2)
// tgamma(n+1/2) -> Pi^(1/2)*(1*3*..*(2*n-1))/(2^n)
if ((x*_ex2()).info(info_flags::posint)) {
- numeric n = ex_to_numeric(x).sub(_num1_2());
+ numeric n = ex_to<numeric>(x).sub(_num1_2());
numeric coefficient = doublefactorial(n.mul(_num2()).sub(_num1()));
coefficient = coefficient.div(pow(_num2(),n));
return coefficient * pow(Pi,_ex1_2());
} else {
// trap negative x==(-n+1/2)
// tgamma(-n+1/2) -> Pi^(1/2)*(-2)^n/(1*3*..*(2*n-1))
- numeric n = abs(ex_to_numeric(x).sub(_num1_2()));
+ numeric n = abs(ex_to<numeric>(x).sub(_num1_2()));
numeric coefficient = pow(_num_2(), n);
coefficient = coefficient.div(doublefactorial(n.mul(_num2()).sub(_num1())));;
return coefficient*power(Pi,_ex1_2());
if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
throw do_taylor(); // caught by function::series()
// if we got here we have to care for a simple pole at -m:
- numeric m = -ex_to_numeric(arg_pt);
+ numeric m = -ex_to<numeric>(arg_pt);
ex ser_denom = _ex1();
for (numeric p; p<=m; ++p)
ser_denom *= arg+p;
TYPECHECK(y,numeric)
END_TYPECHECK(beta(x,y))
- return tgamma(ex_to_numeric(x))*tgamma(ex_to_numeric(y))/tgamma(ex_to_numeric(x+y));
+ return tgamma(ex_to<numeric>(x))*tgamma(ex_to<numeric>(y))/tgamma(ex_to<numeric>(x+y));
}
// treat all problematic x and y that may not be passed into tgamma,
// because they would throw there although beta(x,y) is well-defined
// using the formula beta(x,y) == (-1)^y * beta(1-x-y, y)
- numeric nx(ex_to_numeric(x));
- numeric ny(ex_to_numeric(y));
+ numeric nx(ex_to<numeric>(x));
+ numeric ny(ex_to<numeric>(y));
if (nx.is_real() && nx.is_integer() &&
ny.is_real() && ny.is_integer()) {
if (nx.is_negative()) {
TYPECHECK(x,numeric)
END_TYPECHECK(psi(x))
- return psi(ex_to_numeric(x));
+ return psi(ex_to<numeric>(x));
}
/** Evaluation of digamma-function psi(x).
static ex psi1_eval(const ex & x)
{
if (x.info(info_flags::numeric)) {
- numeric nx = ex_to_numeric(x);
+ numeric nx = ex_to<numeric>(x);
if (nx.is_integer()) {
// integer case
if (nx.is_positive()) {
if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
throw do_taylor(); // caught by function::series()
// if we got here we have to care for a simple pole at -m:
- numeric m = -ex_to_numeric(arg_pt);
+ numeric m = -ex_to<numeric>(arg_pt);
ex recur;
for (numeric p; p<=m; ++p)
recur += power(arg+p,_ex_1());
TYPECHECK(x,numeric)
END_TYPECHECK(psi(n,x))
- return psi(ex_to_numeric(n), ex_to_numeric(x));
+ return psi(ex_to<numeric>(n), ex_to<numeric>(x));
}
/** Evaluation of polygamma-function psi(n,x).
return log(tgamma(x));
if (n.info(info_flags::numeric) && n.info(info_flags::posint) &&
x.info(info_flags::numeric)) {
- numeric nn = ex_to_numeric(n);
- numeric nx = ex_to_numeric(x);
+ numeric nn = ex_to<numeric>(n);
+ numeric nx = ex_to<numeric>(x);
if (nx.is_integer()) {
// integer case
if (nx.is_equal(_num1()))
if (!arg_pt.info(info_flags::integer) || arg_pt.info(info_flags::positive))
throw do_taylor(); // caught by function::series()
// if we got here we have to care for a pole of order n+1 at -m:
- numeric m = -ex_to_numeric(arg_pt);
+ numeric m = -ex_to<numeric>(arg_pt);
ex recur;
for (numeric p; p<=m; ++p)
recur += power(arg+p,-n+_ex_1());
TYPECHECK(x,numeric)
END_TYPECHECK(exp(x))
- return exp(ex_to_numeric(x)); // -> numeric exp(numeric)
+ return exp(ex_to<numeric>(x)); // -> numeric exp(numeric)
}
static ex exp_eval(const ex & x)
// exp(n*Pi*I/2) -> {+1|+I|-1|-I}
ex TwoExOverPiI=(_ex2()*x)/(Pi*I);
if (TwoExOverPiI.info(info_flags::integer)) {
- numeric z=mod(ex_to_numeric(TwoExOverPiI),_num4());
+ numeric z=mod(ex_to<numeric>(TwoExOverPiI),_num4());
if (z.is_equal(_num0()))
return _ex1();
if (z.is_equal(_num1()))
TYPECHECK(x,numeric)
END_TYPECHECK(log(x))
- return log(ex_to_numeric(x)); // -> numeric log(numeric)
+ return log(ex_to<numeric>(x)); // -> numeric log(numeric)
}
static ex log_eval(const ex & x)
if (is_ex_the_function(x, exp)) {
ex t = x.op(0);
if (t.info(info_flags::numeric)) {
- numeric nt = ex_to_numeric(t);
+ numeric nt = ex_to<numeric>(t);
if (nt.is_real())
return t;
}
// Return a plain n*log(x) for the x^n part and series expand the
// other part. Add them together and reexpand again in order to have
// one unnested pseries object. All this also works for negative n.
- const pseries argser = ex_to_pseries(arg.series(rel, order, options));
+ const pseries argser = ex_to<pseries>(arg.series(rel, order, options));
const symbol *s = static_cast<symbol *>(rel.lhs().bp);
const ex point = rel.rhs();
const int n = argser.ldegree(*s);
if (!argser.is_terminating() || argser.nops()!=1) {
// in this case n more terms are needed
// (sadly, to generate them, we have to start from the beginning)
- ex newarg = ex_to_pseries((arg/coeff).series(rel, order+n, options)).shift_exponents(-n).convert_to_poly(true);
- return pseries(rel, seq).add_series(ex_to_pseries(log(newarg).series(rel, order, options)));
+ ex newarg = ex_to<pseries>((arg/coeff).series(rel, order+n, options)).shift_exponents(-n).convert_to_poly(true);
+ return pseries(rel, seq).add_series(ex_to<pseries>(log(newarg).series(rel, order, options)));
} else // it was a monomial
return pseries(rel, seq);
}
TYPECHECK(x,numeric)
END_TYPECHECK(sin(x))
- return sin(ex_to_numeric(x)); // -> numeric sin(numeric)
+ return sin(ex_to<numeric>(x)); // -> numeric sin(numeric)
}
static ex sin_eval(const ex & x)
ex SixtyExOverPi = _ex60()*x/Pi;
ex sign = _ex1();
if (SixtyExOverPi.info(info_flags::integer)) {
- numeric z = mod(ex_to_numeric(SixtyExOverPi),_num120());
+ numeric z = mod(ex_to<numeric>(SixtyExOverPi),_num120());
if (z>=_num60()) {
// wrap to interval [0, Pi)
z -= _num60();
TYPECHECK(x,numeric)
END_TYPECHECK(cos(x))
- return cos(ex_to_numeric(x)); // -> numeric cos(numeric)
+ return cos(ex_to<numeric>(x)); // -> numeric cos(numeric)
}
static ex cos_eval(const ex & x)
ex SixtyExOverPi = _ex60()*x/Pi;
ex sign = _ex1();
if (SixtyExOverPi.info(info_flags::integer)) {
- numeric z = mod(ex_to_numeric(SixtyExOverPi),_num120());
+ numeric z = mod(ex_to<numeric>(SixtyExOverPi),_num120());
if (z>=_num60()) {
// wrap to interval [0, Pi)
z = _num120()-z;
TYPECHECK(x,numeric)
END_TYPECHECK(tan(x)) // -> numeric tan(numeric)
- return tan(ex_to_numeric(x));
+ return tan(ex_to<numeric>(x));
}
static ex tan_eval(const ex & x)
ex SixtyExOverPi = _ex60()*x/Pi;
ex sign = _ex1();
if (SixtyExOverPi.info(info_flags::integer)) {
- numeric z = mod(ex_to_numeric(SixtyExOverPi),_num60());
+ numeric z = mod(ex_to<numeric>(SixtyExOverPi),_num60());
if (z>=_num60()) {
// wrap to interval [0, Pi)
z -= _num60();
TYPECHECK(x,numeric)
END_TYPECHECK(asin(x))
- return asin(ex_to_numeric(x)); // -> numeric asin(numeric)
+ return asin(ex_to<numeric>(x)); // -> numeric asin(numeric)
}
static ex asin_eval(const ex & x)
TYPECHECK(x,numeric)
END_TYPECHECK(acos(x))
- return acos(ex_to_numeric(x)); // -> numeric acos(numeric)
+ return acos(ex_to<numeric>(x)); // -> numeric acos(numeric)
}
static ex acos_eval(const ex & x)
TYPECHECK(x,numeric)
END_TYPECHECK(atan(x))
- return atan(ex_to_numeric(x)); // -> numeric atan(numeric)
+ return atan(ex_to<numeric>(x)); // -> numeric atan(numeric)
}
static ex atan_eval(const ex & x)
TYPECHECK(x,numeric)
END_TYPECHECK(atan2(y,x))
- return atan(ex_to_numeric(y),ex_to_numeric(x)); // -> numeric atan(numeric)
+ return atan(ex_to<numeric>(y),ex_to<numeric>(x)); // -> numeric atan(numeric)
}
static ex atan2_eval(const ex & y, const ex & x)
TYPECHECK(x,numeric)
END_TYPECHECK(sinh(x))
- return sinh(ex_to_numeric(x)); // -> numeric sinh(numeric)
+ return sinh(ex_to<numeric>(x)); // -> numeric sinh(numeric)
}
static ex sinh_eval(const ex & x)
}
if ((x/Pi).info(info_flags::numeric) &&
- ex_to_numeric(x/Pi).real().is_zero()) // sinh(I*x) -> I*sin(x)
+ ex_to<numeric>(x/Pi).real().is_zero()) // sinh(I*x) -> I*sin(x)
return I*sin(x/I);
if (is_ex_exactly_of_type(x, function)) {
TYPECHECK(x,numeric)
END_TYPECHECK(cosh(x))
- return cosh(ex_to_numeric(x)); // -> numeric cosh(numeric)
+ return cosh(ex_to<numeric>(x)); // -> numeric cosh(numeric)
}
static ex cosh_eval(const ex & x)
}
if ((x/Pi).info(info_flags::numeric) &&
- ex_to_numeric(x/Pi).real().is_zero()) // cosh(I*x) -> cos(x)
+ ex_to<numeric>(x/Pi).real().is_zero()) // cosh(I*x) -> cos(x)
return cos(x/I);
if (is_ex_exactly_of_type(x, function)) {
TYPECHECK(x,numeric)
END_TYPECHECK(tanh(x))
- return tanh(ex_to_numeric(x)); // -> numeric tanh(numeric)
+ return tanh(ex_to<numeric>(x)); // -> numeric tanh(numeric)
}
static ex tanh_eval(const ex & x)
}
if ((x/Pi).info(info_flags::numeric) &&
- ex_to_numeric(x/Pi).real().is_zero()) // tanh(I*x) -> I*tan(x);
+ ex_to<numeric>(x/Pi).real().is_zero()) // tanh(I*x) -> I*tan(x);
return I*tan(x/I);
if (is_ex_exactly_of_type(x, function)) {
TYPECHECK(x,numeric)
END_TYPECHECK(asinh(x))
- return asinh(ex_to_numeric(x)); // -> numeric asinh(numeric)
+ return asinh(ex_to<numeric>(x)); // -> numeric asinh(numeric)
}
static ex asinh_eval(const ex & x)
TYPECHECK(x,numeric)
END_TYPECHECK(acosh(x))
- return acosh(ex_to_numeric(x)); // -> numeric acosh(numeric)
+ return acosh(ex_to<numeric>(x)); // -> numeric acosh(numeric)
}
static ex acosh_eval(const ex & x)
TYPECHECK(x,numeric)
END_TYPECHECK(atanh(x))
- return atanh(ex_to_numeric(x)); // -> numeric atanh(numeric)
+ return atanh(ex_to<numeric>(x)); // -> numeric atanh(numeric)
}
static ex atanh_eval(const ex & x)
TYPECHECK(x,numeric)
END_TYPECHECK(zeta(x))
- return zeta(ex_to_numeric(x));
+ return zeta(ex_to<numeric>(x));
}
static ex zeta1_eval(const ex & x)
{
if (x.info(info_flags::numeric)) {
- numeric y = ex_to_numeric(x);
+ numeric y = ex_to<numeric>(x);
// trap integer arguments:
if (y.is_integer()) {
if (y.is_zero())
if (row != 1 && col != 1)
throw (std::runtime_error("matrix::eval_indexed(): vector must have exactly 1 index"));
- const idx & i1 = ex_to_idx(i.op(1));
+ const idx & i1 = ex_to<idx>(i.op(1));
if (col == 1) {
// Index numeric -> return vector element
if (all_indices_unsigned) {
- unsigned n1 = ex_to_numeric(i1.get_value()).to_int();
+ unsigned n1 = ex_to<numeric>(i1.get_value()).to_int();
if (n1 >= row)
throw (std::runtime_error("matrix::eval_indexed(): value of index exceeds number of vector elements"));
return (*this)(n1, 0);
// Index numeric -> return vector element
if (all_indices_unsigned) {
- unsigned n1 = ex_to_numeric(i1.get_value()).to_int();
+ unsigned n1 = ex_to<numeric>(i1.get_value()).to_int();
if (n1 >= col)
throw (std::runtime_error("matrix::eval_indexed(): value of index exceeds number of vector elements"));
return (*this)(0, n1);
} else if (i.nops() == 3) {
// Two indices
- const idx & i1 = ex_to_idx(i.op(1));
- const idx & i2 = ex_to_idx(i.op(2));
+ const idx & i1 = ex_to<idx>(i.op(1));
+ const idx & i2 = ex_to<idx>(i.op(2));
if (!i1.get_dim().is_equal(row))
throw (std::runtime_error("matrix::eval_indexed(): dimension of first index must match number of rows"));
// Both indices numeric -> return matrix element
if (all_indices_unsigned) {
- unsigned n1 = ex_to_numeric(i1.get_value()).to_int(), n2 = ex_to_numeric(i2.get_value()).to_int();
+ unsigned n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
if (n1 >= row)
throw (std::runtime_error("matrix::eval_indexed(): value of first index exceeds number of rows"));
if (n2 >= col)
if (is_ex_of_type(other.op(0), matrix)) {
GINAC_ASSERT(other.nops() == 2 || other.nops() == 3);
- const matrix &self_matrix = ex_to_matrix(self.op(0));
- const matrix &other_matrix = ex_to_matrix(other.op(0));
+ const matrix &self_matrix = ex_to<matrix>(self.op(0));
+ const matrix &other_matrix = ex_to<matrix>(other.op(0));
if (self.nops() == 2 && other.nops() == 2) { // vector + vector
GINAC_ASSERT(is_ex_of_type(self.op(0), matrix));
GINAC_ASSERT(self.nops() == 2 || self.nops() == 3);
- const matrix &self_matrix = ex_to_matrix(self.op(0));
+ const matrix &self_matrix = ex_to<matrix>(self.op(0));
if (self.nops() == 2)
return indexed(self_matrix.mul(other), self.op(1));
GINAC_ASSERT(other->nops() == 2 || other->nops() == 3);
- const matrix &self_matrix = ex_to_matrix(self->op(0));
- const matrix &other_matrix = ex_to_matrix(other->op(0));
+ const matrix &self_matrix = ex_to<matrix>(self->op(0));
+ const matrix &other_matrix = ex_to<matrix>(other->op(0));
if (self->nops() == 2) {
unsigned self_dim = (self_matrix.col == 1) ? self_matrix.row : self_matrix.col;
numeric k;
matrix prod(row,col);
if (expn.info(info_flags::negative)) {
- k = -ex_to_numeric(expn);
+ k = -ex_to<numeric>(expn);
prod = this->inverse();
} else {
- k = ex_to_numeric(expn);
+ k = ex_to<numeric>(expn);
prod = *this;
}
matrix result(row,col);
// search largest element in column co beginning at row ro
GINAC_ASSERT(is_ex_of_type(this->m[k*col+co],numeric));
unsigned kmax = k+1;
- numeric mmax = abs(ex_to_numeric(m[kmax*col+co]));
+ numeric mmax = abs(ex_to<numeric>(m[kmax*col+co]));
while (kmax<row) {
GINAC_ASSERT(is_ex_of_type(this->m[kmax*col+co],numeric));
- numeric tmp = ex_to_numeric(this->m[kmax*col+co]);
+ numeric tmp = ex_to<numeric>(this->m[kmax*col+co]);
if (abs(tmp) > mmax) {
mmax = tmp;
k = kmax;
// utility functions
-/** Return the matrix object handled by an ex.
+/** Return the matrix object handled by an ex. Deprecated: use ex_to<matrix>().
* This is unsafe: you need to check the type first. */
inline const matrix &ex_to_matrix(const ex &e)
{
while (it != itend) {
// If the first argument is a negative integer power, it gets printed as "1.0/<expr>"
- if (it == seq.begin() && ex_to_numeric(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0) {
+ if (it == seq.begin() && ex_to<numeric>(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0) {
if (is_a<print_csrc_cl_N>(c))
c.s << "recip(";
else
it->rest.print(c, precedence());
else {
// Outer parens around ex needed for broken gcc-2.95 parser:
- (ex(power(it->rest, abs(ex_to_numeric(it->coeff))))).print(c, level);
+ (ex(power(it->rest, abs(ex_to<numeric>(it->coeff))))).print(c, level);
}
// Separator is "/" for negative integer powers, "*" otherwise
++it;
if (it != itend) {
- if (ex_to_numeric(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0)
+ if (ex_to<numeric>(it->coeff).is_integer() && it->coeff.compare(_num0()) < 0)
c.s << "/";
else
c.s << "*";
bool first = true;
// First print the overall numeric coefficient
- numeric coeff = ex_to_numeric(overall_coeff);
+ numeric coeff = ex_to<numeric>(overall_coeff);
if (coeff.csgn() == -1)
c.s << '-';
if (!coeff.is_equal(_num1()) &&
{
int deg_sum = 0;
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
- if (ex_to_numeric(cit->coeff).is_integer())
- deg_sum+=cit->rest.degree(s) * ex_to_numeric(cit->coeff).to_int();
+ if (ex_to<numeric>(cit->coeff).is_integer())
+ deg_sum+=cit->rest.degree(s) * ex_to<numeric>(cit->coeff).to_int();
}
return deg_sum;
}
{
int deg_sum = 0;
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
- if (ex_to_numeric(cit->coeff).is_integer())
- deg_sum+=cit->rest.ldegree(s) * ex_to_numeric(cit->coeff).to_int();
+ if (ex_to<numeric>(cit->coeff).is_integer())
+ deg_sum+=cit->rest.ldegree(s) * ex_to<numeric>(cit->coeff).to_int();
}
return deg_sum;
}
#ifdef DO_GINAC_ASSERT
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
GINAC_ASSERT((!is_ex_exactly_of_type((*cit).rest,mul)) ||
- (!(ex_to_numeric((*cit).coeff).is_integer())));
+ (!(ex_to<numeric>((*cit).coeff).is_integer())));
GINAC_ASSERT(!(cit->is_canonical_numeric()));
if (is_ex_exactly_of_type(recombine_pair_to_ex(*cit),numeric))
print(print_tree(std::cerr));
return recombine_pair_to_ex(*(seq.begin()));
} else if ((seq_size==1) &&
is_ex_exactly_of_type((*seq.begin()).rest,add) &&
- ex_to_numeric((*seq.begin()).coeff).is_equal(_num1())) {
+ ex_to<numeric>((*seq.begin()).coeff).is_equal(_num1())) {
// *(+(x,y,...);c) -> +(*(x,c),*(y,c),...) (c numeric(), no powers of +())
- const add & addref = ex_to_add((*seq.begin()).rest);
+ const add & addref = ex_to<add>((*seq.begin()).rest);
epvector distrseq;
distrseq.reserve(addref.seq.size());
for (epvector::const_iterator cit=addref.seq.begin(); cit!=addref.seq.end(); ++cit) {
distrseq.push_back(addref.combine_pair_with_coeff_to_pair(*cit, overall_coeff));
}
return (new add(distrseq,
- ex_to_numeric(addref.overall_coeff).
- mul_dyn(ex_to_numeric(overall_coeff))))
+ ex_to<numeric>(addref.overall_coeff).
+ mul_dyn(ex_to<numeric>(overall_coeff))))
->setflag(status_flags::dynallocated | status_flags::evaluated);
}
return this->hold();
// numeric*matrix
if (seq.size() == 1 && seq[0].coeff.is_equal(_ex1())
&& is_ex_of_type(seq[0].rest, matrix))
- return ex_to_matrix(seq[0].rest).mul(ex_to_numeric(overall_coeff));
+ return ex_to<matrix>(seq[0].rest).mul(ex_to<numeric>(overall_coeff));
// Evaluate children first, look whether there are any matrices at all
// (there can be either no matrices or one matrix; if there were more
// The product contained a matrix. We will multiply all other factors
// into that matrix.
- matrix m = ex_to_matrix(the_matrix->rest);
+ matrix m = ex_to<matrix>(the_matrix->rest);
s->erase(the_matrix);
ex scalar = (new mul(s, overall_coeff))->setflag(status_flags::dynallocated);
return m.mul_scalar(scalar);
expair mul::split_ex_to_pair(const ex & e) const
{
if (is_ex_exactly_of_type(e,power)) {
- const power & powerref = ex_to_power(e);
+ const power & powerref = ex_to<power>(e);
if (is_ex_exactly_of_type(powerref.exponent,numeric))
return expair(powerref.basis,powerref.exponent);
}
ex mul::recombine_pair_to_ex(const expair & p) const
{
- if (ex_to_numeric(p.coeff).is_equal(_num1()))
+ if (ex_to<numeric>(p.coeff).is_equal(_num1()))
return p.rest;
else
return power(p.rest,p.coeff);
bool mul::expair_needs_further_processing(epp it)
{
if (is_ex_exactly_of_type((*it).rest,mul) &&
- ex_to_numeric((*it).coeff).is_integer()) {
+ ex_to<numeric>((*it).coeff).is_integer()) {
// combined pair is product with integer power -> expand it
*it = split_ex_to_pair(recombine_pair_to_ex(*it));
return true;
*it = ep;
return true;
}
- if (ex_to_numeric((*it).coeff).is_equal(_num1())) {
+ if (ex_to<numeric>((*it).coeff).is_equal(_num1())) {
// combined pair has coeff 1 and must be moved to the end
return true;
}
{
GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
- overall_coeff = ex_to_numeric(overall_coeff).mul_dyn(ex_to_numeric(c));
+ overall_coeff = ex_to<numeric>(overall_coeff).mul_dyn(ex_to<numeric>(c));
}
void mul::combine_overall_coeff(const ex & c1, const ex & c2)
GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
GINAC_ASSERT(is_ex_exactly_of_type(c1,numeric));
GINAC_ASSERT(is_ex_exactly_of_type(c2,numeric));
- overall_coeff = ex_to_numeric(overall_coeff).mul_dyn(ex_to_numeric(c1).power(ex_to_numeric(c2)));
+ overall_coeff = ex_to<numeric>(overall_coeff).mul_dyn(ex_to<numeric>(c1).power(ex_to<numeric>(c2)));
}
bool mul::can_make_flat(const expair & p) const
// this assertion will probably fail somewhere
// it would require a more careful make_flat, obeying the power laws
// probably should return true only if p.coeff is integer
- return ex_to_numeric(p.coeff).is_equal(_num1());
+ return ex_to<numeric>(p.coeff).is_equal(_num1());
}
ex mul::expand(unsigned options) const
non_adds.reserve(expanded_seq.size());
epvector::const_iterator cit = expanded_seq.begin();
epvector::const_iterator last = expanded_seq.end();
- ex last_expanded(_ex1());
+ ex last_expanded = _ex1();
while (cit!=last) {
if (is_ex_exactly_of_type((*cit).rest,add) &&
((*cit).coeff.is_equal(_ex1()))) {
++number_of_adds;
if (is_ex_exactly_of_type(last_expanded,add)) {
// expand adds
- const add & add1 = ex_to_add(last_expanded);
- const add & add2 = ex_to_add((*cit).rest);
+ const add & add1 = ex_to<add>(last_expanded);
+ const add & add2 = ex_to<add>((*cit).rest);
int n1 = add1.nops();
int n2 = add2.nops();
exvector distrseq;
delete expanded_seqp;
if (is_ex_exactly_of_type(last_expanded,add)) {
- add const & finaladd = ex_to_add(last_expanded);
+ add const & finaladd = ex_to<add>(last_expanded);
exvector distrseq;
int n = finaladd.nops();
distrseq.reserve(n);
// utility functions
-/** Return the mul object handled by an ex.
+/** Return the mul object handled by an ex. Deprecated: use ex_to<mul>().
* This is unsafe: you need to check the type first. */
inline const mul &ex_to_mul(const ex &e)
{
for (exvector::const_iterator cit=expanded_seq.begin(); cit!=last; ++cit) {
if (is_ex_exactly_of_type((*cit),add)) {
positions_of_adds[number_of_adds]=current_position;
- const add & expanded_addref=ex_to_add(*cit);
+ const add & expanded_addref=ex_to<add>(*cit);
number_of_add_operands[number_of_adds]=expanded_addref.seq.size();
number_of_expanded_terms *= expanded_addref.seq.size();
number_of_adds++;
term=expanded_seq;
for (l=0; l<number_of_adds; l++) {
GINAC_ASSERT(is_ex_exactly_of_type(expanded_seq[positions_of_adds[l]],add));
- const add & addref=ex_to_add(expanded_seq[positions_of_adds[l]]);
+ const add & addref=ex_to<add>(expanded_seq[positions_of_adds[l]]);
term[positions_of_adds[l]]=addref.recombine_pair_to_ex(addref.seq[k[l]]);
}
distrseq.push_back((new ncmul(term,1))->setflag(status_flags::dynallocated |
// If there are only matrices, simply multiply them
it = s->begin(); itend = s->end();
if (is_ex_of_type(*it, matrix)) {
- matrix prod(ex_to_matrix(*it));
+ matrix prod(ex_to<matrix>(*it));
it++;
while (it != itend) {
if (!is_ex_of_type(*it, matrix))
goto no_matrix;
- prod = prod.mul(ex_to_matrix(*it));
+ prod = prod.mul(ex_to<matrix>(*it));
it++;
}
delete s;
// utility functions
-/** Return the ncmul object handled by an ex.
+/** Return the ncmul object handled by an ex. Deprecated: use ex_to<ncmul>().
* This is unsafe: you need to check the type first. */
inline const ncmul &ex_to_ncmul(const ex &e)
{
static numeric lcmcoeff(const ex &e, const numeric &l)
{
if (e.info(info_flags::rational))
- return lcm(ex_to_numeric(e).denom(), l);
+ return lcm(ex_to<numeric>(e).denom(), l);
else if (is_ex_exactly_of_type(e, add)) {
numeric c = _num1();
for (unsigned i=0; i<e.nops(); i++)
if (is_ex_exactly_of_type(e.op(0), symbol))
return l;
else
- return pow(lcmcoeff(e.op(0), l), ex_to_numeric(e.op(1)));
+ return pow(lcmcoeff(e.op(0), l), ex_to<numeric>(e.op(1)));
}
return l;
}
if (is_ex_exactly_of_type(e.op(0), symbol))
return e * lcm;
else
- return pow(multiply_lcm(e.op(0), lcm.power(ex_to_numeric(e.op(1)).inverse())), e.op(1));
+ return pow(multiply_lcm(e.op(0), lcm.power(ex_to<numeric>(e.op(1)).inverse())), e.op(1));
} else
return e * lcm;
}
while (it != itend) {
GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
GINAC_ASSERT(is_ex_exactly_of_type(it->coeff,numeric));
- c = gcd(ex_to_numeric(it->coeff), c);
+ c = gcd(ex_to<numeric>(it->coeff), c);
it++;
}
GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
- c = gcd(ex_to_numeric(overall_coeff),c);
+ c = gcd(ex_to<numeric>(overall_coeff),c);
return c;
}
}
#endif // def DO_GINAC_ASSERT
GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
- return abs(ex_to_numeric(overall_coeff));
+ return abs(ex_to<numeric>(overall_coeff));
}
epvector::const_iterator it = seq.begin();
epvector::const_iterator itend = seq.end();
GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
- numeric cur_max = abs(ex_to_numeric(overall_coeff));
+ numeric cur_max = abs(ex_to<numeric>(overall_coeff));
while (it != itend) {
numeric a;
GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
- a = abs(ex_to_numeric(it->coeff));
+ a = abs(ex_to<numeric>(it->coeff));
if (a > cur_max)
cur_max = a;
it++;
}
#endif // def DO_GINAC_ASSERT
GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
- return abs(ex_to_numeric(overall_coeff));
+ return abs(ex_to<numeric>(overall_coeff));
}
epvector::const_iterator itend = seq.end();
while (it != itend) {
GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
- numeric coeff = GiNaC::smod(ex_to_numeric(it->coeff), xi);
+ numeric coeff = GiNaC::smod(ex_to<numeric>(it->coeff), xi);
if (!coeff.is_zero())
newseq.push_back(expair(it->rest, coeff));
it++;
}
GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
- numeric coeff = GiNaC::smod(ex_to_numeric(overall_coeff), xi);
+ numeric coeff = GiNaC::smod(ex_to<numeric>(overall_coeff), xi);
return (new add(newseq,coeff))->setflag(status_flags::dynallocated);
}
#endif // def DO_GINAC_ASSERT
mul * mulcopyp = new mul(*this);
GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
- mulcopyp->overall_coeff = GiNaC::smod(ex_to_numeric(overall_coeff),xi);
+ mulcopyp->overall_coeff = GiNaC::smod(ex_to<numeric>(overall_coeff),xi);
mulcopyp->clearflag(status_flags::evaluated);
mulcopyp->clearflag(status_flags::hash_calculated);
return mulcopyp->setflag(status_flags::dynallocated);
// GCD of two numeric values -> CLN
if (is_ex_exactly_of_type(a, numeric) && is_ex_exactly_of_type(b, numeric)) {
- numeric g = gcd(ex_to_numeric(a), ex_to_numeric(b));
+ numeric g = gcd(ex_to<numeric>(a), ex_to<numeric>(b));
if (ca)
- *ca = ex_to_numeric(a) / g;
+ *ca = ex_to<numeric>(a) / g;
if (cb)
- *cb = ex_to_numeric(b) / g;
+ *cb = ex_to<numeric>(b) / g;
return g;
}
if (divide_in_z(p, g, ca ? *ca : dummy, var) && divide_in_z(q, g, cb ? *cb : dummy, var)) {
g *= gc;
ex lc = g.lcoeff(x);
- if (is_ex_exactly_of_type(lc, numeric) && ex_to_numeric(lc).is_negative())
+ if (is_ex_exactly_of_type(lc, numeric) && ex_to<numeric>(lc).is_negative())
return -g;
else
return g;
if (ca)
*ca = cp;
ex lc = g.lcoeff(x);
- if (is_ex_exactly_of_type(lc, numeric) && ex_to_numeric(lc).is_negative())
+ if (is_ex_exactly_of_type(lc, numeric) && ex_to<numeric>(lc).is_negative())
return -g;
else
return g;
if (cb)
*cb = cq;
ex lc = g.lcoeff(x);
- if (is_ex_exactly_of_type(lc, numeric) && ex_to_numeric(lc).is_negative())
+ if (is_ex_exactly_of_type(lc, numeric) && ex_to<numeric>(lc).is_negative())
return -g;
else
return g;
// GCD of numerics -> CLN
if (is_ex_exactly_of_type(a, numeric) && is_ex_exactly_of_type(b, numeric)) {
- numeric g = gcd(ex_to_numeric(a), ex_to_numeric(b));
+ numeric g = gcd(ex_to<numeric>(a), ex_to<numeric>(b));
if (ca || cb) {
if (g.is_zero()) {
if (ca)
*cb = _ex0();
} else {
if (ca)
- *ca = ex_to_numeric(a) / g;
+ *ca = ex_to<numeric>(a) / g;
if (cb)
- *cb = ex_to_numeric(b) / g;
+ *cb = ex_to<numeric>(b) / g;
}
}
return g;
ex lcm(const ex &a, const ex &b, bool check_args)
{
if (is_ex_exactly_of_type(a, numeric) && is_ex_exactly_of_type(b, numeric))
- return lcm(ex_to_numeric(a), ex_to_numeric(b));
+ return lcm(ex_to<numeric>(a), ex_to<numeric>(b));
if (check_args && (!a.info(info_flags::rational_polynomial) || !b.info(info_flags::rational_polynomial)))
throw(std::invalid_argument("lcm: arguments must be polynomials over the rationals"));
// Find the symbol to factor in at this stage
if (!is_ex_of_type(args.op(0), symbol))
throw (std::runtime_error("sqrfree(): invalid factorization variable"));
- const symbol x = ex_to_symbol(args.op(0));
+ const symbol x = ex_to<symbol>(args.op(0));
// convert the argument from something in Q[X] to something in Z[X]
numeric lcm = lcm_of_coefficients_denominators(a);
ex tmp = multiply_lcm(a,lcm);
const symbol *x;
if (get_first_symbol(den, x)) {
GINAC_ASSERT(is_ex_exactly_of_type(den.unit(*x),numeric));
- if (ex_to_numeric(den.unit(*x)).is_negative()) {
+ if (ex_to<numeric>(den.unit(*x)).is_negative()) {
num *= _ex_1();
den *= _ex_1();
}
// utility functions
-/** Return the numeric object handled by an ex.
+/** Return the numeric object handled by an ex. Deprecated: use ex_to<numeric>().
* This is unsafe: you need to check the type first. */
inline const numeric &ex_to_numeric(const ex &e)
{
// 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))) {
- int exp = ex_to_numeric(exponent).to_int();
+ int exp = ex_to<numeric>(exponent).to_int();
if (exp > 0)
c.s << '(';
else {
else
c.s << "1.0/(";
}
- print_sym_pow(c, ex_to_symbol(basis), exp);
+ print_sym_pow(c, ex_to<symbol>(basis), exp);
c.s << ')';
// <expr>^-1 is printed as "1.0/<expr>" or with the recip() function of CLN
{
if (is_exactly_of_type(*exponent.bp,numeric)) {
if (basis.is_equal(s)) {
- if (ex_to_numeric(exponent).is_integer())
- return ex_to_numeric(exponent).to_int();
+ if (ex_to<numeric>(exponent).is_integer())
+ return ex_to<numeric>(exponent).to_int();
else
return 0;
} else
- return basis.degree(s) * ex_to_numeric(exponent).to_int();
+ return basis.degree(s) * ex_to<numeric>(exponent).to_int();
}
return 0;
}
{
if (is_exactly_of_type(*exponent.bp,numeric)) {
if (basis.is_equal(s)) {
- if (ex_to_numeric(exponent).is_integer())
- return ex_to_numeric(exponent).to_int();
+ if (ex_to<numeric>(exponent).is_integer())
+ return ex_to<numeric>(exponent).to_int();
else
return 0;
} else
- return basis.ldegree(s) * ex_to_numeric(exponent).to_int();
+ return basis.ldegree(s) * ex_to<numeric>(exponent).to_int();
}
return 0;
}
return _ex0();
} else {
// basis equal to s
- if (is_exactly_of_type(*exponent.bp, numeric) && ex_to_numeric(exponent).is_integer()) {
+ if (is_exactly_of_type(*exponent.bp, numeric) && ex_to<numeric>(exponent).is_integer()) {
// integer exponent
- int int_exp = ex_to_numeric(exponent).to_int();
+ int int_exp = ex_to<numeric>(exponent).to_int();
if (n == int_exp)
return _ex1();
else
// (c1, c2 numeric(), c2 integer or -1 < c1 <= 1,
// case c1==1 should not happen, see below!)
if (is_ex_exactly_of_type(ebasis,power)) {
- const power & sub_power = ex_to_power(ebasis);
+ const power & sub_power = ex_to<power>(ebasis);
const ex & sub_basis = sub_power.basis;
const ex & sub_exponent = sub_power.exponent;
if (is_ex_exactly_of_type(sub_exponent,numeric)) {
- const numeric & num_sub_exponent = ex_to_numeric(sub_exponent);
+ const numeric & num_sub_exponent = ex_to<numeric>(sub_exponent);
GINAC_ASSERT(num_sub_exponent!=numeric(1));
if (num_exponent->is_integer() || (abs(num_sub_exponent) - _num1()).is_negative())
return power(sub_basis,num_sub_exponent.mul(*num_exponent));
// ^(*(x,y,z),c1) -> *(x^c1,y^c1,z^c1) (c1 integer)
if (num_exponent->is_integer() && is_ex_exactly_of_type(ebasis,mul)) {
- return expand_mul(ex_to_mul(ebasis), *num_exponent);
+ return expand_mul(ex_to<mul>(ebasis), *num_exponent);
}
// ^(*(...,x;c1),c2) -> ^(*(...,x;1),c2)*c1^c2 (c1, c2 numeric(), c1>0)
// ^(*(...,x,c1),c2) -> ^(*(...,x;-1),c2)*(-c1)^c2 (c1, c2 numeric(), c1<0)
if (is_ex_exactly_of_type(ebasis,mul)) {
GINAC_ASSERT(!num_exponent->is_integer()); // should have been handled above
- const mul & mulref = ex_to_mul(ebasis);
+ const mul & mulref = ex_to<mul>(ebasis);
if (!mulref.overall_coeff.is_equal(_ex1())) {
- const numeric & num_coeff = ex_to_numeric(mulref.overall_coeff);
+ const numeric & num_coeff = ex_to<numeric>(mulref.overall_coeff);
if (num_coeff.is_real()) {
if (num_coeff.is_positive()) {
mul * mulp = new mul(mulref);
ex eexponent = exponent.evalm();
if (is_ex_of_type(ebasis,matrix)) {
if (is_ex_of_type(eexponent,numeric)) {
- return (new matrix(ex_to_matrix(ebasis).pow(eexponent)))->setflag(status_flags::dynallocated);
+ return (new matrix(ex_to<matrix>(ebasis).pow(eexponent)))->setflag(status_flags::dynallocated);
}
}
return (new power(ebasis, eexponent))->setflag(status_flags::dynallocated);
// x^(a+b) -> x^a * x^b
if (is_ex_exactly_of_type(expanded_exponent, add)) {
- const add &a = ex_to_add(expanded_exponent);
+ const add &a = ex_to<add>(expanded_exponent);
exvector distrseq;
distrseq.reserve(a.seq.size() + 1);
epvector::const_iterator last = a.seq.end();
}
// Make sure that e.g. (x+y)^(2+a) expands the (x+y)^2 factor
- if (ex_to_numeric(a.overall_coeff).is_integer()) {
- const numeric &num_exponent = ex_to_numeric(a.overall_coeff);
+ if (ex_to<numeric>(a.overall_coeff).is_integer()) {
+ const numeric &num_exponent = ex_to<numeric>(a.overall_coeff);
int int_exponent = num_exponent.to_int();
if (int_exponent > 0 && is_ex_exactly_of_type(expanded_basis, add))
- distrseq.push_back(expand_add(ex_to_add(expanded_basis), int_exponent));
+ distrseq.push_back(expand_add(ex_to<add>(expanded_basis), int_exponent));
else
distrseq.push_back(power(expanded_basis, a.overall_coeff));
} else
}
if (!is_ex_exactly_of_type(expanded_exponent, numeric) ||
- !ex_to_numeric(expanded_exponent).is_integer()) {
+ !ex_to<numeric>(expanded_exponent).is_integer()) {
if (are_ex_trivially_equal(basis,expanded_basis) && are_ex_trivially_equal(exponent,expanded_exponent)) {
return this->hold();
} else {
}
// integer numeric exponent
- const numeric & num_exponent = ex_to_numeric(expanded_exponent);
+ const numeric & num_exponent = ex_to<numeric>(expanded_exponent);
int int_exponent = num_exponent.to_int();
// (x+y)^n, n>0
if (int_exponent > 0 && is_ex_exactly_of_type(expanded_basis,add))
- return expand_add(ex_to_add(expanded_basis), int_exponent);
+ return expand_add(ex_to<add>(expanded_basis), int_exponent);
// (x*y)^n -> x^n * y^n
if (is_ex_exactly_of_type(expanded_basis,mul))
- return expand_mul(ex_to_mul(expanded_basis), num_exponent);
+ return expand_mul(ex_to<mul>(expanded_basis), num_exponent);
// cannot expand further
if (are_ex_trivially_equal(basis,expanded_basis) && are_ex_trivially_equal(exponent,expanded_exponent))
const ex & b = a.op(l);
GINAC_ASSERT(!is_ex_exactly_of_type(b,add));
GINAC_ASSERT(!is_ex_exactly_of_type(b,power) ||
- !is_ex_exactly_of_type(ex_to_power(b).exponent,numeric) ||
- !ex_to_numeric(ex_to_power(b).exponent).is_pos_integer() ||
- !is_ex_exactly_of_type(ex_to_power(b).basis,add) ||
- !is_ex_exactly_of_type(ex_to_power(b).basis,mul) ||
- !is_ex_exactly_of_type(ex_to_power(b).basis,power));
+ !is_ex_exactly_of_type(ex_to<power>(b).exponent,numeric) ||
+ !ex_to<numeric>(ex_to<power>(b).exponent).is_pos_integer() ||
+ !is_ex_exactly_of_type(ex_to<power>(b).basis,add) ||
+ !is_ex_exactly_of_type(ex_to<power>(b).basis,mul) ||
+ !is_ex_exactly_of_type(ex_to<power>(b).basis,power));
if (is_ex_exactly_of_type(b,mul))
- term.push_back(expand_mul(ex_to_mul(b),numeric(k[l])));
+ term.push_back(expand_mul(ex_to<mul>(b),numeric(k[l])));
else
term.push_back(power(b,k[l]));
}
const ex & b = a.op(l);
GINAC_ASSERT(!is_ex_exactly_of_type(b,add));
GINAC_ASSERT(!is_ex_exactly_of_type(b,power) ||
- !is_ex_exactly_of_type(ex_to_power(b).exponent,numeric) ||
- !ex_to_numeric(ex_to_power(b).exponent).is_pos_integer() ||
- !is_ex_exactly_of_type(ex_to_power(b).basis,add) ||
- !is_ex_exactly_of_type(ex_to_power(b).basis,mul) ||
- !is_ex_exactly_of_type(ex_to_power(b).basis,power));
+ !is_ex_exactly_of_type(ex_to<power>(b).exponent,numeric) ||
+ !ex_to<numeric>(ex_to<power>(b).exponent).is_pos_integer() ||
+ !is_ex_exactly_of_type(ex_to<power>(b).basis,add) ||
+ !is_ex_exactly_of_type(ex_to<power>(b).basis,mul) ||
+ !is_ex_exactly_of_type(ex_to<power>(b).basis,power));
if (is_ex_exactly_of_type(b,mul))
- term.push_back(expand_mul(ex_to_mul(b),numeric(n-k_cum[m-2])));
+ term.push_back(expand_mul(ex_to<mul>(b),numeric(n-k_cum[m-2])));
else
term.push_back(power(b,n-k_cum[m-2]));
GINAC_ASSERT(!is_ex_exactly_of_type(r,add));
GINAC_ASSERT(!is_ex_exactly_of_type(r,power) ||
- !is_ex_exactly_of_type(ex_to_power(r).exponent,numeric) ||
- !ex_to_numeric(ex_to_power(r).exponent).is_pos_integer() ||
- !is_ex_exactly_of_type(ex_to_power(r).basis,add) ||
- !is_ex_exactly_of_type(ex_to_power(r).basis,mul) ||
- !is_ex_exactly_of_type(ex_to_power(r).basis,power));
+ !is_ex_exactly_of_type(ex_to<power>(r).exponent,numeric) ||
+ !ex_to<numeric>(ex_to<power>(r).exponent).is_pos_integer() ||
+ !is_ex_exactly_of_type(ex_to<power>(r).basis,add) ||
+ !is_ex_exactly_of_type(ex_to<power>(r).basis,mul) ||
+ !is_ex_exactly_of_type(ex_to<power>(r).basis,power));
if (are_ex_trivially_equal(c,_ex1())) {
if (is_ex_exactly_of_type(r,mul)) {
- sum.push_back(expair(expand_mul(ex_to_mul(r),_num2()),
+ sum.push_back(expair(expand_mul(ex_to<mul>(r),_num2()),
_ex1()));
} else {
sum.push_back(expair((new power(r,_ex2()))->setflag(status_flags::dynallocated),
}
} else {
if (is_ex_exactly_of_type(r,mul)) {
- sum.push_back(expair(expand_mul(ex_to_mul(r),_num2()),
- ex_to_numeric(c).power_dyn(_num2())));
+ sum.push_back(expair(expand_mul(ex_to<mul>(r),_num2()),
+ ex_to<numeric>(c).power_dyn(_num2())));
} else {
sum.push_back(expair((new power(r,_ex2()))->setflag(status_flags::dynallocated),
- ex_to_numeric(c).power_dyn(_num2())));
+ ex_to<numeric>(c).power_dyn(_num2())));
}
}
const ex & r1 = (*cit1).rest;
const ex & c1 = (*cit1).coeff;
sum.push_back(a.combine_ex_with_coeff_to_pair((new mul(r,r1))->setflag(status_flags::dynallocated),
- _num2().mul(ex_to_numeric(c)).mul_dyn(ex_to_numeric(c1))));
+ _num2().mul(ex_to<numeric>(c)).mul_dyn(ex_to<numeric>(c1))));
}
}
// second part: add terms coming from overall_factor (if != 0)
if (!a.overall_coeff.is_zero()) {
for (epvector::const_iterator cit=a.seq.begin(); cit!=a.seq.end(); ++cit) {
- sum.push_back(a.combine_pair_with_coeff_to_pair(*cit,ex_to_numeric(a.overall_coeff).mul_dyn(_num2())));
+ sum.push_back(a.combine_pair_with_coeff_to_pair(*cit,ex_to<numeric>(a.overall_coeff).mul_dyn(_num2())));
}
- sum.push_back(expair(ex_to_numeric(a.overall_coeff).power_dyn(_num2()),_ex1()));
+ sum.push_back(expair(ex_to<numeric>(a.overall_coeff).power_dyn(_num2()),_ex1()));
}
GINAC_ASSERT(sum.size()==(a_nops*(a_nops+1))/2);
} else {
// it is safe not to call mul::combine_pair_with_coeff_to_pair()
// since n is an integer
- distrseq.push_back(expair((*cit).rest, ex_to_numeric((*cit).coeff).mul(n)));
+ distrseq.push_back(expair((*cit).rest, ex_to<numeric>((*cit).coeff).mul(n)));
}
++cit;
}
- return (new mul(distrseq,ex_to_numeric(m.overall_coeff).power_dyn(n)))->setflag(status_flags::dynallocated);
+ return (new mul(distrseq,ex_to<numeric>(m.overall_coeff).power_dyn(n)))->setflag(status_flags::dynallocated);
}
/*
// utility functions
-/** Return the power object handled by an ex.
+/** Return the power object handled by an ex. Deprecated: use ex_to<power>().
* This is unsafe: you need to check the type first. */
inline const power &ex_to_power(const ex &e)
{
if (var.is_equal(s)) {
// Return last exponent
if (seq.size())
- return ex_to_numeric((*(seq.end() - 1)).coeff).to_int();
+ return ex_to<numeric>((*(seq.end() - 1)).coeff).to_int();
else
return 0;
} else {
if (var.is_equal(s)) {
// Return first exponent
if (seq.size())
- return ex_to_numeric((*(seq.begin())).coeff).to_int();
+ return ex_to<numeric>((*(seq.begin())).coeff).to_int();
else
return 0;
} else {
while (lo <= hi) {
int mid = (lo + hi) / 2;
GINAC_ASSERT(is_ex_exactly_of_type(seq[mid].coeff, numeric));
- int cmp = ex_to_numeric(seq[mid].coeff).compare(looking_for);
+ int cmp = ex_to<numeric>(seq[mid].coeff).compare(looking_for);
switch (cmp) {
case -1:
lo = mid + 1;
}
break;
} else
- pow_a = ex_to_numeric((*a).coeff).to_int();
+ pow_a = ex_to<numeric>((*a).coeff).to_int();
// If b is empty, fill up with elements from a and stop
if (b == b_end) {
}
break;
} else
- pow_b = ex_to_numeric((*b).coeff).to_int();
+ pow_b = ex_to<numeric>((*b).coeff).to_int();
// a and b are non-empty, compare powers
if (pow_a < pow_b) {
else
op = it->rest.series(r, order, options);
if (!it->coeff.is_equal(_ex1()))
- op = ex_to_pseries(op).mul_const(ex_to_numeric(it->coeff));
+ op = ex_to<pseries>(op).mul_const(ex_to<numeric>(it->coeff));
// Series addition
- acc = ex_to_pseries(acc).add_series(ex_to_pseries(op));
+ acc = ex_to<pseries>(acc).add_series(ex_to<pseries>(op));
}
return acc;
}
if (op.info(info_flags::numeric)) {
// series * const (special case, faster)
ex f = power(op, it->coeff);
- acc = ex_to_pseries(acc).mul_const(ex_to_numeric(f));
+ acc = ex_to<pseries>(acc).mul_const(ex_to<numeric>(f));
continue;
} else if (!is_ex_exactly_of_type(op, pseries))
op = op.series(r, order, options);
if (!it->coeff.is_equal(_ex1()))
- op = ex_to_pseries(op).power_const(ex_to_numeric(it->coeff), order);
+ op = ex_to<pseries>(op).power_const(ex_to<numeric>(it->coeff), order);
// Series multiplication
- acc = ex_to_pseries(acc).mul_series(ex_to_pseries(op));
+ acc = ex_to<pseries>(acc).mul_series(ex_to<pseries>(op));
}
return acc;
}
}
// Power e
- return ex_to_pseries(e).power_const(ex_to_numeric(exponent), order);
+ return ex_to<pseries>(e).power_const(ex_to<numeric>(exponent), order);
}
epvector new_seq;
epvector::const_iterator it = seq.begin(), itend = seq.end();
while (it != itend) {
- int o = ex_to_numeric(it->coeff).to_int();
+ int o = ex_to<numeric>(it->coeff).to_int();
if (o >= order) {
new_seq.push_back(expair(Order(_ex1()), o));
break;
relational rel_;
if (is_ex_exactly_of_type(r,relational))
- rel_ = ex_to_relational(r);
+ rel_ = ex_to<relational>(r);
else if (is_ex_exactly_of_type(r,symbol))
rel_ = relational(r,_ex0());
else
// cannot decide on non-numerical results
return o==not_equal ? true : false;
- int cmpval = ex_to_numeric(df).compare(_num0());
+ int cmpval = ex_to<numeric>(df).compare(_num0());
switch (o) {
case equal:
return cmpval==0;
// utility functions
-/** Return the relational object handled by an ex.
+/** Return the relational object handled by an ex. Deprecated: use ex_to<relational>().
* This is unsafe: you need to check the type first. */
inline const relational &ex_to_relational(const ex &e)
{
extern const type_info & typeid_${STRUCTURE};
extern const unsigned tinfo_${STRUCTURE};
-// macros
-
-#define ex_to_${STRUCTURE}(X) (static_cast<${STRUCTURE} const &>(*(X).bp))
-
} // namespace GiNaC
#endif // ndef _${STRUCTURE_UC}_H_
// If symbol is in sym_lst, return the existing symbol
for (unsigned i=0; i<sym_lst.nops(); i++) {
- if (is_ex_of_type(sym_lst.op(i), symbol) && (ex_to_symbol(sym_lst.op(i)).name == ex_to_symbol(s).name))
+ if (is_ex_of_type(sym_lst.op(i), symbol) && (ex_to<symbol>(sym_lst.op(i)).name == ex_to<symbol>(s).name))
return sym_lst.op(i);
}
return s;
// utility functions
-/** Return the symbol object handled by an ex.
+/** Return the symbol object handled by an ex. Deprecated: use ex_to<symbol>().
* This is unsafe: you need to check the type first. */
inline const symbol &ex_to_symbol(const ex &e)
{
while (true) {
ex e;
if (n.find_ex("child", e, sym_lst, i))
- add(ex_to_symmetry(e));
+ add(ex_to<symmetry>(e));
else
break;
i++;
// All children must have the same number of indices
if (type != none && !children.empty()) {
GINAC_ASSERT(is_ex_exactly_of_type(children[0], symmetry));
- if (ex_to_symmetry(children[0]).indices.size() != c.indices.size())
+ if (ex_to<symmetry>(children[0]).indices.size() != c.indices.size())
throw (std::logic_error("symmetry:add(): children must have same number of indices"));
}
{
GINAC_ASSERT(is_ex_exactly_of_type(lh, symmetry));
GINAC_ASSERT(is_ex_exactly_of_type(rh, symmetry));
- GINAC_ASSERT(ex_to_symmetry(lh).indices.size() == ex_to_symmetry(rh).indices.size());
- std::set<unsigned>::const_iterator ait = ex_to_symmetry(lh).indices.begin(), aitend = ex_to_symmetry(lh).indices.end(), bit = ex_to_symmetry(rh).indices.begin();
+ GINAC_ASSERT(ex_to<symmetry>(lh).indices.size() == ex_to<symmetry>(rh).indices.size());
+ std::set<unsigned>::const_iterator ait = ex_to<symmetry>(lh).indices.begin(), aitend = ex_to<symmetry>(lh).indices.end(), bit = ex_to<symmetry>(rh).indices.begin();
while (ait != aitend) {
int cmpval = v[*ait].compare(v[*bit]);
if (cmpval < 0)
{
GINAC_ASSERT(is_ex_exactly_of_type(lh, symmetry));
GINAC_ASSERT(is_ex_exactly_of_type(rh, symmetry));
- GINAC_ASSERT(ex_to_symmetry(lh).indices.size() == ex_to_symmetry(rh).indices.size());
- std::set<unsigned>::const_iterator ait = ex_to_symmetry(lh).indices.begin(), aitend = ex_to_symmetry(lh).indices.end(), bit = ex_to_symmetry(rh).indices.begin();
+ GINAC_ASSERT(ex_to<symmetry>(lh).indices.size() == ex_to<symmetry>(rh).indices.size());
+ std::set<unsigned>::const_iterator ait = ex_to<symmetry>(lh).indices.begin(), aitend = ex_to<symmetry>(lh).indices.end(), bit = ex_to<symmetry>(rh).indices.begin();
while (ait != aitend) {
v[*ait].swap(v[*bit]);
++ait; ++bit;
exvector::const_iterator first = symm.children.begin(), last = symm.children.end();
while (first != last) {
GINAC_ASSERT(is_ex_exactly_of_type(*first, symmetry));
- int child_sign = canonicalize(v, ex_to_symmetry(*first));
+ int child_sign = canonicalize(v, ex_to<symmetry>(*first));
if (child_sign == 0)
return 0;
if (child_sign != INT_MAX) {
// global functions
-inline const symmetry &ex_to_symmetry(const ex &e)
-{
- return static_cast<const symmetry &>(*e.bp);
-}
-
inline symmetry &ex_to_nonconst_symmetry(const ex &e)
{
return static_cast<symmetry &>(*e.bp);
GINAC_ASSERT(i.nops() == 3);
GINAC_ASSERT(is_ex_of_type(i.op(0), tensdelta));
- const idx & i1 = ex_to_idx(i.op(1));
- const idx & i2 = ex_to_idx(i.op(2));
+ const idx & i1 = ex_to<idx>(i.op(1));
+ const idx & i2 = ex_to<idx>(i.op(2));
// Trace of delta tensor is the dimension of the space
if (is_dummy_pair(i1, i2))
// Numeric evaluation
if (static_cast<const indexed &>(i).all_index_values_are(info_flags::integer)) {
- int n1 = ex_to_numeric(i1.get_value()).to_int(), n2 = ex_to_numeric(i2.get_value()).to_int();
+ int n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
if (n1 == n2)
return _ex1();
else
GINAC_ASSERT(is_ex_of_type(i.op(1), varidx));
GINAC_ASSERT(is_ex_of_type(i.op(2), varidx));
- const varidx & i1 = ex_to_varidx(i.op(1));
- const varidx & i2 = ex_to_varidx(i.op(2));
+ const varidx & i1 = ex_to<varidx>(i.op(1));
+ const varidx & i2 = ex_to<varidx>(i.op(2));
// A metric tensor with one covariant and one contravariant index gets
// replaced by a delta tensor
GINAC_ASSERT(is_ex_of_type(i.op(1), varidx));
GINAC_ASSERT(is_ex_of_type(i.op(2), varidx));
- const varidx & i1 = ex_to_varidx(i.op(1));
- const varidx & i2 = ex_to_varidx(i.op(2));
+ const varidx & i1 = ex_to<varidx>(i.op(1));
+ const varidx & i2 = ex_to<varidx>(i.op(2));
// Numeric evaluation
if (static_cast<const indexed &>(i).all_index_values_are(info_flags::nonnegint)) {
- int n1 = ex_to_numeric(i1.get_value()).to_int(), n2 = ex_to_numeric(i2.get_value()).to_int();
+ int n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
if (n1 != n2)
return _ex0();
else if (n1 == 0)
GINAC_ASSERT(is_ex_of_type(i.op(1), spinidx));
GINAC_ASSERT(is_ex_of_type(i.op(2), spinidx));
- const spinidx & i1 = ex_to_spinidx(i.op(1));
- const spinidx & i2 = ex_to_spinidx(i.op(2));
+ const spinidx & i1 = ex_to<spinidx>(i.op(1));
+ const spinidx & i2 = ex_to<spinidx>(i.op(2));
// Convolutions are zero
if (static_cast<const indexed &>(i).get_dummy_indices().size() != 0)
// Numeric evaluation
if (static_cast<const indexed &>(i).all_index_values_are(info_flags::nonnegint)) {
- int n1 = ex_to_numeric(i1.get_value()).to_int(), n2 = ex_to_numeric(i2.get_value()).to_int();
+ int n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
if (n1 == n2)
return _ex0();
else if (n1 < n2)
std::vector<int> v;
v.reserve(i.nops() - 1);
for (unsigned j=1; j<i.nops(); j++)
- v.push_back(ex_to_numeric(ex_to_idx(i.op(j)).get_value()).to_int());
+ v.push_back(ex_to<numeric>(ex_to<idx>(i.op(j)).get_value()).to_int());
int sign = permutation_sign(v.begin(), v.end());
// In a Minkowski space, check for covariant indices
const ex & x = i.op(j);
if (!is_ex_of_type(x, varidx))
throw(std::runtime_error("indices of epsilon tensor in Minkowski space must be of type varidx"));
- if (ex_to_varidx(x).is_covariant())
- if (ex_to_idx(x).get_value().is_zero())
+ if (ex_to<varidx>(x).is_covariant())
+ if (ex_to<idx>(x).get_value().is_zero())
sign = (pos_sig ? -sign : sign);
else
sign = (pos_sig ? sign : -sign);
GINAC_ASSERT(is_ex_of_type(self->op(0), tensdelta));
// Try to contract first index
- const idx *self_idx = &ex_to_idx(self->op(1));
- const idx *free_idx = &ex_to_idx(self->op(2));
+ const idx *self_idx = &ex_to<idx>(self->op(1));
+ const idx *free_idx = &ex_to<idx>(self->op(2));
bool first_index_tried = false;
again:
if (self_idx->is_symbolic()) {
for (int i=1; i<other->nops(); i++) {
- const idx &other_idx = ex_to_idx(other->op(i));
+ const idx &other_idx = ex_to<idx>(other->op(i));
if (is_dummy_pair(*self_idx, other_idx)) {
// Contraction found, remove delta tensor and substitute
if (!first_index_tried) {
// No contraction with first index found, try second index
- self_idx = &ex_to_idx(self->op(2));
- free_idx = &ex_to_idx(self->op(1));
+ self_idx = &ex_to<idx>(self->op(2));
+ free_idx = &ex_to<idx>(self->op(1));
first_index_tried = true;
goto again;
}
return false;
// Try to contract first index
- const idx *self_idx = &ex_to_idx(self->op(1));
- const idx *free_idx = &ex_to_idx(self->op(2));
+ const idx *self_idx = &ex_to<idx>(self->op(1));
+ const idx *free_idx = &ex_to<idx>(self->op(2));
bool first_index_tried = false;
again:
if (self_idx->is_symbolic()) {
for (int i=1; i<other->nops(); i++) {
- const idx &other_idx = ex_to_idx(other->op(i));
+ const idx &other_idx = ex_to<idx>(other->op(i));
if (is_dummy_pair(*self_idx, other_idx)) {
// Contraction found, remove metric tensor and substitute
if (!first_index_tried) {
// No contraction with first index found, try second index
- self_idx = &ex_to_idx(self->op(2));
- free_idx = &ex_to_idx(self->op(1));
+ self_idx = &ex_to<idx>(self->op(2));
+ free_idx = &ex_to<idx>(self->op(1));
first_index_tried = true;
goto again;
}
// Contractions between spinor metrics
if (is_ex_of_type(other->op(0), spinmetric)) {
- const idx &self_i1 = ex_to_idx(self->op(1));
- const idx &self_i2 = ex_to_idx(self->op(2));
- const idx &other_i1 = ex_to_idx(other->op(1));
- const idx &other_i2 = ex_to_idx(other->op(2));
+ const idx &self_i1 = ex_to<idx>(self->op(1));
+ const idx &self_i2 = ex_to<idx>(self->op(2));
+ const idx &other_i1 = ex_to<idx>(other->op(1));
+ const idx &other_i2 = ex_to<idx>(other->op(2));
if (is_dummy_pair(self_i1, other_i1)) {
if (is_dummy_pair(self_i2, other_i2))
return false;
// Try to contract first index
- const idx *self_idx = &ex_to_idx(self->op(1));
- const idx *free_idx = &ex_to_idx(self->op(2));
+ const idx *self_idx = &ex_to<idx>(self->op(1));
+ const idx *free_idx = &ex_to<idx>(self->op(2));
bool first_index_tried = false;
int sign = 1;
again:
if (self_idx->is_symbolic()) {
for (int i=1; i<other->nops(); i++) {
- const idx &other_idx = ex_to_idx(other->op(i));
+ const idx &other_idx = ex_to<idx>(other->op(i));
if (is_dummy_pair(*self_idx, other_idx)) {
// Contraction found, remove metric tensor and substitute
if (!first_index_tried) {
// No contraction with first index found, try second index
- self_idx = &ex_to_idx(self->op(2));
- free_idx = &ex_to_idx(self->op(1));
+ self_idx = &ex_to<idx>(self->op(2));
+ free_idx = &ex_to<idx>(self->op(1));
first_index_tried = true;
sign = -sign;
goto again;
{
if (!is_ex_of_type(i1, spinidx) || !is_ex_of_type(i2, spinidx))
throw(std::invalid_argument("indices of spinor metric must be of type spinidx"));
- if (!ex_to_idx(i1).get_dim().is_equal(2) || !ex_to_idx(i2).get_dim().is_equal(2))
+ if (!ex_to<idx>(i1).get_dim().is_equal(2) || !ex_to<idx>(i2).get_dim().is_equal(2))
throw(std::runtime_error("index dimension for spinor metric must be 2"));
return indexed(spinmetric(), sy_anti(), i1, i2);
if (!is_ex_of_type(i1, idx) || !is_ex_of_type(i2, idx))
throw(std::invalid_argument("indices of epsilon tensor must be of type idx"));
- ex dim = ex_to_idx(i1).get_dim();
- if (!dim.is_equal(ex_to_idx(i2).get_dim()))
+ ex dim = ex_to<idx>(i1).get_dim();
+ if (!dim.is_equal(ex_to<idx>(i2).get_dim()))
throw(std::invalid_argument("all indices of epsilon tensor must have the same dimension"));
- if (!ex_to_idx(i1).get_dim().is_equal(_ex2()))
+ if (!ex_to<idx>(i1).get_dim().is_equal(_ex2()))
throw(std::runtime_error("index dimension of epsilon tensor must match number of indices"));
return indexed(tensepsilon(), sy_anti(), i1, i2);
if (!is_ex_of_type(i1, idx) || !is_ex_of_type(i2, idx) || !is_ex_of_type(i3, idx))
throw(std::invalid_argument("indices of epsilon tensor must be of type idx"));
- ex dim = ex_to_idx(i1).get_dim();
- if (!dim.is_equal(ex_to_idx(i2).get_dim()) || !dim.is_equal(ex_to_idx(i3).get_dim()))
+ ex dim = ex_to<idx>(i1).get_dim();
+ if (!dim.is_equal(ex_to<idx>(i2).get_dim()) || !dim.is_equal(ex_to<idx>(i3).get_dim()))
throw(std::invalid_argument("all indices of epsilon tensor must have the same dimension"));
- if (!ex_to_idx(i1).get_dim().is_equal(_ex3()))
+ if (!ex_to<idx>(i1).get_dim().is_equal(_ex3()))
throw(std::runtime_error("index dimension of epsilon tensor must match number of indices"));
return indexed(tensepsilon(), sy_anti(), i1, i2, i3);
if (!is_ex_of_type(i1, varidx) || !is_ex_of_type(i2, varidx) || !is_ex_of_type(i3, varidx) || !is_ex_of_type(i4, varidx))
throw(std::invalid_argument("indices of Lorentz epsilon tensor must be of type varidx"));
- ex dim = ex_to_idx(i1).get_dim();
- if (!dim.is_equal(ex_to_idx(i2).get_dim()) || !dim.is_equal(ex_to_idx(i3).get_dim()) || !dim.is_equal(ex_to_idx(i4).get_dim()))
+ ex dim = ex_to<idx>(i1).get_dim();
+ if (!dim.is_equal(ex_to<idx>(i2).get_dim()) || !dim.is_equal(ex_to<idx>(i3).get_dim()) || !dim.is_equal(ex_to<idx>(i4).get_dim()))
throw(std::invalid_argument("all indices of epsilon tensor must have the same dimension"));
- if (!ex_to_idx(i1).get_dim().is_equal(_ex4()))
+ if (!ex_to<idx>(i1).get_dim().is_equal(_ex4()))
throw(std::runtime_error("index dimension of epsilon tensor must match number of indices"));
return indexed(tensepsilon(true, pos_sig), sy_anti(), i1, i2, i3, i4);
if (!is_ex_of_type(i1, varidx) || !is_ex_of_type(i2, varidx) || !is_ex_of_type(i3, varidx) || !is_ex_of_type(i4, varidx))
throw(std::invalid_argument("indices of epsilon tensor must be of type varidx"));
- ex dim = ex_to_idx(i1).get_dim();
+ ex dim = ex_to<idx>(i1).get_dim();
if (dim.is_equal(4))
return lorentz_eps(i1, i2, i3, i4, pos_sig);
else
// utility functions
+
+/** Return the tensor object handled by an ex. Deprecated: use ex_to<tensor>().
+ * This is unsafe: you need to check the type first. */
inline const tensor &ex_to_tensor(const ex &e)
{
return static_cast<const tensor &>(*e.bp);
// utility functions
-/** Return the wildcard object handled by an ex.
+/** Return the wildcard object handled by an ex. Deprecated: use ex_to<wildcard>().
* This is unsafe: you need to check the type first. */
inline const wildcard &ex_to_wildcard(const ex &e)
{
ex e = $3;
if (!e.info(info_flags::integer))
throw (std::invalid_argument("argument to iprint() must be an integer"));
- long i = ex_to_numeric(e).to_long();
+ long i = ex_to<numeric>(e).to_long();
cout << i << endl;
cout << "#o" << oct << i << endl;
cout << "#x" << hex << i << dec << endl;
YYERROR;
}
}
- | '?' T_SYMBOL {print_help(ex_to_symbol($2).get_name());}
+ | '?' T_SYMBOL {print_help(ex_to<symbol>($2).get_name());}
| '?' T_TIME {print_help("time");}
| '?' '?' {print_help_topics();}
| T_QUIT {YYACCEPT;}
$$ = (i->second.p)(static_cast<const exprseq &>(*($3.bp)));
}
}
- | T_DIGITS '=' T_NUMBER {$$ = $3; Digits = ex_to_numeric($3).to_int();}
- | T_SYMBOL '=' exp {$$ = $3; const_cast<symbol *>(&ex_to_symbol($1))->assign($3);}
+ | T_DIGITS '=' T_NUMBER {$$ = $3; Digits = ex_to<numeric>($3).to_int();}
+ | T_SYMBOL '=' exp {$$ = $3; const_cast<symbol *>(&ex_to<symbol>($1))->assign($3);}
| exp T_EQUAL exp {$$ = $1 == $3;}
| exp T_NOTEQ exp {$$ = $1 != $3;}
| exp '<' exp {$$ = $1 < $3;}
| exp '!' {$$ = factorial($1);}
| '(' exp ')' {$$ = $2;}
| '{' list_or_empty '}' {$$ = $2;}
- | '[' matrix ']' {$$ = lst_to_matrix(ex_to_lst($2));}
+ | '[' matrix ']' {$$ = lst_to_matrix(ex_to<lst>($2));}
;
exprseq : exp {$$ = exprseq($1);}
{
CHECK_ARG(0, matrix, charpoly);
CHECK_ARG(1, symbol, charpoly);
- return ex_to_matrix(e[0]).charpoly(ex_to_symbol(e[1]));
+ return ex_to<matrix>(e[0]).charpoly(ex_to<symbol>(e[1]));
}
static ex f_coeff(const exprseq &e)
{
CHECK_ARG(2, numeric, coeff);
- return e[0].coeff(e[1], ex_to_numeric(e[2]).to_int());
+ return e[0].coeff(e[1], ex_to<numeric>(e[2]).to_int());
}
static ex f_content(const exprseq &e)
{
CHECK_ARG(1, symbol, content);
- return e[0].content(ex_to_symbol(e[1]));
+ return e[0].content(ex_to<symbol>(e[1]));
}
static ex f_determinant(const exprseq &e)
{
CHECK_ARG(0, matrix, determinant);
- return ex_to_matrix(e[0]).determinant();
+ return ex_to<matrix>(e[0]).determinant();
}
static ex f_diag(const exprseq &e)
static ex f_diff2(const exprseq &e)
{
CHECK_ARG(1, symbol, diff);
- return e[0].diff(ex_to_symbol(e[1]));
+ return e[0].diff(ex_to<symbol>(e[1]));
}
static ex f_diff3(const exprseq &e)
{
CHECK_ARG(1, symbol, diff);
CHECK_ARG(2, numeric, diff);
- return e[0].diff(ex_to_symbol(e[1]), ex_to_numeric(e[2]).to_int());
+ return e[0].diff(ex_to<symbol>(e[1]), ex_to<numeric>(e[2]).to_int());
}
static ex f_divide(const exprseq &e)
static ex f_eval2(const exprseq &e)
{
CHECK_ARG(1, numeric, eval);
- return e[0].eval(ex_to_numeric(e[1]).to_int());
+ return e[0].eval(ex_to<numeric>(e[1]).to_int());
}
static ex f_evalf2(const exprseq &e)
{
CHECK_ARG(1, numeric, evalf);
- return e[0].evalf(ex_to_numeric(e[1]).to_int());
+ return e[0].evalf(ex_to<numeric>(e[1]).to_int());
}
static ex f_inverse(const exprseq &e)
{
CHECK_ARG(0, matrix, inverse);
- return ex_to_matrix(e[0]).inverse();
+ return ex_to<matrix>(e[0]).inverse();
}
static ex f_is(const exprseq &e)
{
CHECK_ARG(0, relational, is);
- return (bool)ex_to_relational(e[0]) ? ex(1) : ex(0);
+ return (bool)ex_to<relational>(e[0]) ? ex(1) : ex(0);
}
static ex f_match(const exprseq &e)
static ex f_normal2(const exprseq &e)
{
CHECK_ARG(1, numeric, normal);
- return e[0].normal(ex_to_numeric(e[1]).to_int());
+ return e[0].normal(ex_to<numeric>(e[1]).to_int());
}
static ex f_op(const exprseq &e)
{
CHECK_ARG(1, numeric, op);
- int n = ex_to_numeric(e[1]).to_int();
+ int n = ex_to<numeric>(e[1]).to_int();
if (n < 0 || n >= (int)e[0].nops())
throw(std::out_of_range("second argument to op() is out of range"));
return e[0].op(n);
static ex f_prem(const exprseq &e)
{
CHECK_ARG(2, symbol, prem);
- return prem(e[0], e[1], ex_to_symbol(e[2]));
+ return prem(e[0], e[1], ex_to<symbol>(e[2]));
}
static ex f_primpart(const exprseq &e)
{
CHECK_ARG(1, symbol, primpart);
- return e[0].primpart(ex_to_symbol(e[1]));
+ return e[0].primpart(ex_to<symbol>(e[1]));
}
static ex f_quo(const exprseq &e)
{
CHECK_ARG(2, symbol, quo);
- return quo(e[0], e[1], ex_to_symbol(e[2]));
+ return quo(e[0], e[1], ex_to<symbol>(e[2]));
}
static ex f_rem(const exprseq &e)
{
CHECK_ARG(2, symbol, rem);
- return rem(e[0], e[1], ex_to_symbol(e[2]));
+ return rem(e[0], e[1], ex_to<symbol>(e[2]));
}
static ex f_series(const exprseq &e)
{
CHECK_ARG(2, numeric, series);
- return e[0].series(e[1], ex_to_numeric(e[2]).to_int());
+ return e[0].series(e[1], ex_to<numeric>(e[2]).to_int());
}
static ex f_sqrfree2(const exprseq &e)
{
CHECK_ARG(1, lst, sqrfree);
- return sqrfree(e[0], ex_to_lst(e[1]));
+ return sqrfree(e[0], ex_to<lst>(e[1]));
}
static ex f_subs3(const exprseq &e)
{
CHECK_ARG(1, lst, subs);
CHECK_ARG(2, lst, subs);
- return e[0].subs(ex_to_lst(e[1]), ex_to_lst(e[2]));
+ return e[0].subs(ex_to<lst>(e[1]), ex_to<lst>(e[2]));
}
static ex f_trace(const exprseq &e)
{
CHECK_ARG(0, matrix, trace);
- return ex_to_matrix(e[0]).trace();
+ return ex_to<matrix>(e[0]).trace();
}
static ex f_transpose(const exprseq &e)
{
CHECK_ARG(0, matrix, transpose);
- return ex_to_matrix(e[0]).transpose();
+ return ex_to<matrix>(e[0]).transpose();
}
static ex f_unassign(const exprseq &e)
{
CHECK_ARG(0, symbol, unassign);
- (const_cast<symbol *>(&ex_to_symbol(e[0])))->unassign();
+ (const_cast<symbol *>(&ex_to<symbol>(e[0])))->unassign();
return e[0];
}
static ex f_unit(const exprseq &e)
{
CHECK_ARG(1, symbol, unit);
- return e[0].unit(ex_to_symbol(e[1]));
+ return e[0].unit(ex_to<symbol>(e[1]));
}
static ex f_dummy(const exprseq &e)
static fcn_tab::const_iterator find_function(const ex &sym, int req_params)
{
- const string &name = ex_to_symbol(sym).get_name();
+ const string &name = ex_to<symbol>(sym).get_name();
typedef fcn_tab::const_iterator I;
pair<I, I> b = fcns.equal_range(name);
if (b.first == b.second)