bool ex_e::has(const ptr_base &what, search_flag f, bool exact_idx) const { if (what->type() == EX) { const ex_e *w = what.get<ex_e>(); int ld = m_lag - w->m_lag; bool ok = !symbolic::internal::compare(symbolic::internal::lag(m_arg, ld), w->m_arg); if (!ok) return false; switch (f) { case EXACT_T: return (ld == 0) ? true : false; case ANY_T: return true; case DIFF_T: return (ld != 0) ? true : false; case LEAD_T: return (ld > 0) ? true : false; case LAG_T: return (ld < 0) ? true : false; default: INTERNAL_ERROR } return false; } return m_arg->has(what, f, exact_idx); }
ptr_base symbolic::internal::add_idx(const ptr_base &p, const idx_ex &ie) { if (!ie) return p; unsigned t = p->type(); if (t == IDX) { const ex_idx *pt = p.get<ex_idx>(); return ex_idx::create(pt->get_ie(), add_idx(pt->get_e(), ie)); // return add_idx(pt->get_e(), ie); } else if (t == SYMB) { const ex_symb *pt = p.get<ex_symb>(); return ex_symbidx::create(pt->m_hash, 1, ie.m_id, 0, 0, 0); } else if (t == SYMBIDX) { if (p->hasidx(ie.m_id)) return p; const ex_symbidx *pt = p.get<ex_symbidx>(); unsigned no = pt->m_noid; int i1 = pt->m_idx1, i2 = pt->m_idx2, i3 = pt->m_idx3, i4 = pt->m_idx4; switch (no) { case 1: i2 = ie.m_id; break; case 2: i3 = ie.m_id; break; case 3: i4 = ie.m_id; break; default: INTERNAL_ERROR } return ex_symbidx::create(pt->m_hash, no + 1, i1, i2, i3, i4); } else if (t == VART) {
ptr_base ex_symb::diff(const ptr_base &p) const { if (p->type() != SYMB) return ex_num::zero(); const ex_symb *pp = p.get<ex_symb>(); if (!compare(*pp)) return ex_num::one(); return ex_num::zero(); }
ptr_base ex_idx::create(const idx_ex &ie, const ptr_base &e) { if (!ie) return e; if (!e->hasidx(ie.m_id)) return e; if (e->type() == IDX) { if (e.get<ex_idx>()->has_ie(ie)) return e; } return ptr_base(new ex_idx(ie, e)); }
ptr_base symbolic::internal::lag(const ptr_base &p, int l) { if (!l) return p; if (!(p->flag() & HAST)) return p; unsigned t = p->type(); if (t == VART) return p.get<ex_vart>()->lag(l); else if (t == VARTIDX) return p.get<ex_vartidx>()->lag(l); else if (t == EX) return p.get<ex_e>()->lag(l); else if (t == ADD) { const num_ex_pair_vec &in = p.get<ex_add>()->get_ops(); num_ex_pair_vec out; unsigned i, n = in.size(); out.reserve(n); for (i = 0; i < n; ++i) out.push_back(std::pair<Number, ptr_base>(in[i].first, lag(in[i].second, l))); return mk_add(out); } else if (t == MUL) { const num_ex_pair_vec &in = p.get<ex_mul>()->get_ops(); num_ex_pair_vec out; unsigned i, n = in.size(); out.reserve(n); for (i = 0; i < n; ++i) out.push_back(std::pair<Number, ptr_base>(in[i].first, lag(in[i].second, l))); return mk_mul(out); } else if (t == POW) { const ex_pow *pt = p.get<ex_pow>(); return mk_pow(lag(pt->get_base(), l), lag(pt->get_exp(), l)); } else if (t == FUN) { const ex_func *pt = p.get<ex_func>(); return mk_func(pt->get_code(), lag(pt->get_arg(), l)); } else if (t == IDX) { const ex_idx *pt = p.get<ex_idx>(); return ex_idx::create(pt->get_ie(), lag(pt->get_e(), l)); } else if (t == SUM) { const ex_sum *pt = p.get<ex_sum>(); return ex_sum::create(pt->get_ie(), lag(pt->get_e(), l)); } else if (t == PROD) { const ex_prod *pt = p.get<ex_prod>(); return ex_prod::create(pt->get_ie(), lag(pt->get_e(), l)); } else INTERNAL_ERROR }
bool ex_symb::has(const ptr_base &what, search_flag f, bool) const { if (what->type() != SYMB) return false; const ex_symb *w = what.get<ex_symb>(); if (compareT(m_hash, w->m_hash)) return false; switch (f) { case EXACT_T: case ANY_T: return true; case DIFF_T: case LEAD_T: case LAG_T: return false; default: INTERNAL_ERROR } return false; }
ptr_base symbolic::internal::drop_Es(const ptr_base &p) { if (!has_Es(p)) return p; unsigned t = p->type(); if (t == EX) { return p.get<ex_e>()->get_arg(); } else if (t == ADD) { const num_ex_pair_vec &in = p.get<ex_add>()->get_ops(); num_ex_pair_vec out; unsigned i, n = in.size(); out.reserve(n); for (i = 0; i < n; ++i) out.push_back(std::pair<Number, ptr_base>(in[i].first, drop_Es(in[i].second))); return mk_add(out); } else if (t == MUL) { const num_ex_pair_vec &in = p.get<ex_mul>()->get_ops(); num_ex_pair_vec out; unsigned i, n = in.size(); out.reserve(n); for (i = 0; i < n; ++i) out.push_back(std::pair<Number, ptr_base>(in[i].first, drop_Es(in[i].second))); return mk_mul(out); } else if (t == POW) { const ex_pow *pt = p.get<ex_pow>(); return mk_pow(drop_Es(pt->get_base()), drop_Es(pt->get_exp())); } else if (t == FUN) { const ex_func *pt = p.get<ex_func>(); return mk_func(pt->get_code(), drop_Es(pt->get_arg())); } else if (t == IDX) { const ex_idx *pt = p.get<ex_idx>(); return ex_idx::create(pt->get_ie(), drop_Es(pt->get_e())); } else if (t == SUM) { const ex_sum *pt = p.get<ex_sum>(); return ex_sum::create(pt->get_ie(), drop_Es(pt->get_e())); } else if (t == PROD) { const ex_prod *pt = p.get<ex_prod>(); return ex_prod::create(pt->get_ie(), drop_Es(pt->get_e())); } else INTERNAL_ERROR; }
ptr_base symbolic::internal::append_name(const ptr_base &p, const std::string &s) { unsigned t = p->type(); if (t == IDX) { const ex_idx *pt = p.get<ex_idx>(); return ex_idx::create(pt->get_ie(), append_name(pt->get_e(), s)); } else if (t == SYMB) { return ex_symb::create(stringhash::get_instance().append(p.get<ex_symb>()->m_hash, s)); } else if (t == SYMBIDX) { const ex_symbidx *pt = p.get<ex_symbidx>(); return ex_symbidx::create(stringhash::get_instance().append(pt->m_hash, s), pt->m_noid, pt->m_idx1, pt->m_idx2, pt->m_idx3, pt->m_idx4); } else if (t == VART) { return ex_vart::create(stringhash::get_instance().append(p.get<ex_vart>()->m_hash, s), 0); } else if (t == VARTIDX) { const ex_vartidx *pt = p.get<ex_vartidx>(); return ex_vartidx::create(stringhash::get_instance().append(pt->m_hash, s), 0, pt->m_noid, pt->m_idx1, pt->m_idx2, pt->m_idx3, pt->m_idx4); } else USER_ERROR("append_name expects parameter or variable") }