Last active
December 13, 2015 19:29
-
-
Save marionette-of-u/4963476 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <typeinfo> | |
| #include <cxxabi.h> | |
| #include <cstdlib> | |
| class demangle{ | |
| private: | |
| char *realname; | |
| public: | |
| demangle(const std::type_info &ti){ | |
| int status = 0; | |
| realname = abi::__cxa_demangle(ti.name(), 0, 0, &status); | |
| } | |
| demangle(const demangle&) = delete; | |
| demangle &operator =(const demangle&) = delete; | |
| ~demangle(){ | |
| std::free(realname); | |
| } | |
| operator const char *() const{ | |
| return realname; | |
| } | |
| }; | |
| #include <iostream> | |
| #include <ginac/ginac.h> | |
| namespace ExtGiNaC{ | |
| using namespace GiNaC; | |
| namespace detail{ | |
| template<class Dummy = void> | |
| struct logarithm2_template{ | |
| logarithm2_template() = delete; | |
| logarithm2_template(const ex &x_, const ex &y_) : x(x_), y(y_){} | |
| logarithm2_template(const logarithm2_template &other) : x(other.x), y(other.y){} | |
| logarithm2_template(logarithm2_template &&other) : x(other.x), y(other.y){} | |
| const char *get_class_name(){ return "log2"; } | |
| std::size_t nops() const{ | |
| return 2; | |
| } | |
| ex op(std::size_t i) const{ | |
| switch(i){ | |
| case 0: | |
| return x; | |
| case 1: | |
| return y; | |
| default: | |
| throw(std::range_error("logarithm2::op(): no such operand")); | |
| } | |
| } | |
| ex &let_op(std::size_t i){ | |
| switch(i){ | |
| case 0: | |
| return x; | |
| case 1: | |
| return y; | |
| default: | |
| throw(std::range_error("logarithm2::let_op(): no such operand")); | |
| } | |
| } | |
| ex x, y; | |
| }; | |
| } | |
| } | |
| namespace GiNaC{ | |
| using logarithm2 = structure<ExtGiNaC::detail::logarithm2_template<>>; | |
| template<> | |
| ex logarithm2::evalf(int level) const{ | |
| const ExtGiNaC::detail::logarithm2_template<> &obj = get_struct(); | |
| return (log(obj.y).evalf(level) / log(obj.x).evalf(level)).evalf(level); | |
| } | |
| template<> | |
| ex logarithm2::series(const relational &r, int order, unsigned int options) const{ | |
| const ExtGiNaC::detail::logarithm2_template<> &obj = get_struct(); | |
| return (log(obj.y) / log(obj.x)).series(r, order, options); | |
| } | |
| template<> | |
| ex logarithm2::derivative(const symbol &s) const{ | |
| const ExtGiNaC::detail::logarithm2_template<> &obj = get_struct(); | |
| return (log(obj.y) / log(obj.x)).diff(s); | |
| } | |
| template<> | |
| std::size_t logarithm2::nops() const{ | |
| return get_struct().nops(); | |
| } | |
| template<> | |
| ex logarithm2::op(std::size_t i) const{ | |
| return get_struct().op(i); | |
| } | |
| template<> | |
| ex &logarithm2::let_op(std::size_t i){ | |
| return get_struct().let_op(i); | |
| } | |
| template<> | |
| ex logarithm2::subs(const exmap &m, unsigned int options) const{ | |
| const ExtGiNaC::detail::logarithm2_template<> &obj = get_struct(); | |
| return (log(obj.y).subs(m, options) / log(obj.x).subs(m, options)).subs(m, options); | |
| } | |
| template<> | |
| ex logarithm2::map(map_function &f) const{ | |
| const ExtGiNaC::detail::logarithm2_template<> &obj = get_struct(); | |
| return (log(obj.y) / log(obj.x)).map(f); | |
| } | |
| template<> | |
| void logarithm2::print(const print_context &c, unsigned int level) const{ | |
| if(is_a<print_tree>(c)){ | |
| inherited::print(c, level); | |
| } | |
| const ExtGiNaC::detail::logarithm2_template<> &obj = get_struct(); | |
| const unsigned int prec = precedence(); | |
| c.s << "log(" << obj.x << ", " << obj.y << ")"; | |
| } | |
| } | |
| namespace ExtGiNaC{ | |
| inline logarithm2 log2(const ex &x, const ex &y){ | |
| return logarithm2(detail::logarithm2_template<>(x, y)); | |
| } | |
| namespace detail{ | |
| inline ex exp_log_alternate_form(const ex &expression){ | |
| static const exmap equations = { | |
| { | |
| pow(wild(0), wild(1)) * pow(wild(0), wild(2)), | |
| pow(wild(0), wild(1) + wild(2)) | |
| }, | |
| { | |
| pow(pow(wild(0), wild(1)), wild(2)), | |
| pow(wild(0), wild(1) * wild(2)) | |
| }, | |
| { | |
| pow(wild(0), wild(1)) / pow(wild(0), wild(2)), | |
| pow(wild(0), wild(1) - wild(2)) | |
| } | |
| }; | |
| ex current = expression; | |
| for(; ; ){ | |
| const ex temp = current.subs(equations, subs_options::algebraic); | |
| if(temp == current){ break; } | |
| current = temp; | |
| } | |
| return current; | |
| } | |
| } | |
| inline ex alternate_form(const ex &expression){ | |
| symbol e; | |
| return detail::exp_log_alternate_form(expression.subs(exp(wild(0)) == pow(e, wild(0)))).subs(pow(e, wild(0)) == exp(wild(0))); | |
| } | |
| } | |
| int main(){ | |
| using namespace ExtGiNaC; | |
| // logarithm2 test | |
| { | |
| symbol x("x"), y("y"); | |
| symbol a("a"), b("b"); | |
| ex e = log2(x, y); | |
| std::cout << latex; | |
| std::cout << e << std::endl; | |
| std::cout << e.subs(lst(x == 2, y == 1024)).eval() << std::endl; | |
| std::cout << e.subs(lst(x == 2, y == 1024)).evalf() << std::endl; | |
| std::cout << e.op(0) << std::endl; | |
| std::cout << e.op(1) << std::endl; | |
| std::cout << e.series(y == a, 4) << std::endl; | |
| std::cout << e.series(x == b, 4) << std::endl; | |
| std::cout << e.diff(y) << std::endl; | |
| std::cout << e.diff(x) << std::endl; | |
| } | |
| // alternate_form test | |
| /* | |
| { | |
| symbol x("x"), y("y"), z("z"); | |
| auto f = [&z](const ex &expression){ | |
| return pow(z, expression); | |
| }; | |
| symbol a("a"), b("b"), c("c"); | |
| ex p = exp(pow(a, b)) / exp(pow(a, c)); | |
| ex q = pow(p * exp(pow(a, c)), p * exp(pow(b, c))); | |
| std::cout << q << " = " << alternate_form(q) << std::endl; | |
| std::cout << (pow(exp(Pi), I) + 1) << " = " << alternate_form(pow(exp(Pi), I) + 1) << std::endl; | |
| } | |
| */ | |
| return 0; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment