#include #include #include #include #include namespace GiNaC { //////////////////////////////////////////////////////////////////////////////// class newfunction : public exprseq { GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(newfunction, exprseq) virtual newfunction* duplicate() const { return new newfunction(*this); } virtual void accept(GiNaC::visitor& v) const { if (visitor* p = dynamic_cast(&v)) { p->visit(*this); } else { inherited::accept(v); } } protected: virtual int compare_same_type(const basic& other) const { return exprseq::compare_same_type(other); } virtual bool is_equal_same_type(const basic& other) const { return exprseq::compare_same_type(other); } public: virtual void print(const print_context& c, unsigned level = 0) const; public: newfunction(tinfo_t ti) { tinfo_key = ti; } newfunction(tinfo_t ti, const ex& x1) : inherited(x1) { tinfo_key = ti; } newfunction(tinfo_t ti, const ex& x1, const ex& x2) : inherited(x1, x2) { tinfo_key = ti; } newfunction(tinfo_t ti, const ex& x1, const ex& x2, const ex& x3) : inherited(x1, x2, x3) { tinfo_key = ti; } // ... }; GINAC_IMPLEMENT_REGISTERED_CLASS(newfunction, exprseq) newfunction::newfunction(const GiNaC::archive_node& n, GiNaC::lst& sym_lst) : inherited(n, sym_lst) { } void newfunction::archive(GiNaC::archive_node& n) const { inherited::archive(n); } GiNaC::ex newfunction::unarchive(const GiNaC::archive_node& n, GiNaC::lst& sym_lst) { return (new newfunction(n, sym_lst))->setflag(status_flags::dynallocated); } void newfunction::print(const print_context& c, unsigned level) const { const std::vector& pdt = get_class_info().options.get_print_dispatch_table(); unsigned id = c.get_class_info().options.get_id(); if (id >= pdt.size() || !(pdt[id].is_valid())) { if (is_a(c)) { c.s << std::string(level, ' ') << class_name() << " @" << this << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec << ", nops=" << nops() << std::endl; unsigned delta_indent = static_cast(c).delta_indent; for (size_t i=0; i(c)) { c.s << "\\mbox{" << class_name() << "}"; inherited::do_print(c,level); } else { c.s << class_name(); inherited::do_print(c,level); } } else { pdt[id](*this, c, level); } } //////////////////////////////////////////////////////////////////////////////// class polylog : public newfunction { // a new GINAC_DECLARE_FUNCTION macro will replace this GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(polylog, newfunction) // will be part of GINAC_DECLARE_FUNCTION macro virtual polylog* duplicate() const { return new polylog(*this); } // will be part of GINAC_DECLARE_FUNCTION macro virtual void accept(GiNaC::visitor& v) const { if (visitor* p = dynamic_cast(&v)) { p->visit(*this); } else { inherited::accept(v); } } public: polylog(const ex& x1, const ex& x2) : inherited(&polylog::tinfo_static, x1, x2) { } protected: void do_print_latex(const print_context& c, unsigned level) const; public: virtual ex eval(int level = 0) const; }; GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(polylog, exprseq, print_func(&polylog::do_print_latex)) // will be part of GINAC_IMPLEMENT_FUNCTION macro polylog::polylog(const GiNaC::archive_node& n, GiNaC::lst& sym_lst) : inherited(n, sym_lst) { } // will be part of GINAC_IMPLEMENT_FUNCTION macro void polylog::archive(GiNaC::archive_node& n) const { inherited::archive(n); } // will be part of GINAC_IMPLEMENT_FUNCTION macro GiNaC::ex polylog::unarchive(const GiNaC::archive_node& n, GiNaC::lst& sym_lst) { return (new polylog(n, sym_lst))->setflag(status_flags::dynallocated); } void polylog::do_print_latex(const print_context& c, unsigned level) const { c.s << "\\mbox{Li}"; inherited::do_print(c,level); } ex polylog::eval(int level) const { if (op(0).is_equal(1)) { return zeta(op(1)); } else { return this->hold(); } } //////////////////////////////////////////////////////////////////////////////// class log10_ginac : public newfunction { GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(log10_ginac, newfunction) virtual log10_ginac* duplicate() const { return new log10_ginac(*this); } virtual void accept(GiNaC::visitor& v) const { if (visitor* p = dynamic_cast(&v)) { p->visit(*this); } else { inherited::accept(v); } } public: log10_ginac(const ex& x) : inherited(&log10_ginac::tinfo_static, x) { } protected: void do_print(const print_context& c, unsigned level) const; void do_print_latex(const print_context& c, unsigned level) const; public: virtual ex eval(int level = 0) const; }; GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(log10_ginac, newfunction, print_func(&log10_ginac::do_print). print_func(&log10_ginac::do_print_latex)) log10_ginac::log10_ginac(const GiNaC::archive_node& n, GiNaC::lst& sym_lst) : inherited(n, sym_lst) { } void log10_ginac::archive(GiNaC::archive_node& n) const { inherited::archive(n); } GiNaC::ex log10_ginac::unarchive(const GiNaC::archive_node& n, GiNaC::lst& sym_lst) { return (new log10_ginac(n, sym_lst))->setflag(status_flags::dynallocated); } void log10_ginac::do_print(const print_context& c, unsigned level) const { std::string classname(class_name()); c.s << classname.erase(classname.find("_ginac",0),6); inherited::do_print(c,level); } void log10_ginac::do_print_latex(const print_context& c, unsigned level) const { c.s << "\\log"; inherited::do_print(c,level); } ex log10_ginac::eval(int level) const { if (op(0).is_equal(0)) { return 666; } else { return this->hold(); } } template const GiNaC::log10_ginac log10(const T1& x) { return log10_ginac(x); } const GiNaC::log10_ginac log10(double x) { return log10_ginac(x); } const GiNaC::log10_ginac log10(float x) { return log10_ginac(x); } //////////////////////////////////////////////////////////////////////////////// } // namespace GiNaC //using namespace std; using namespace GiNaC; int main() { try { symbol x("x"); ex r1 = polylog(x,3) + polylog(1,3) + 6*GiNaC::log10(3.0f) - log10(x); std::cout << dflt << r1 << std::endl; std::cout << tree << r1 << std::endl; std::cout << latex << r1 << std::endl; } catch (const std::exception& e) { std::cout << e.what() << std::endl; } return 0; }