Created
February 8, 2013 17:13
-
-
Save marionette-of-u/4740446 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{ | |
| class map_reduce_exp : public map_function{ | |
| public: | |
| ex operator ()(const ex &e){ | |
| auto f = [](const ex &a){ | |
| return !is_a<add>(a) && !is_a<mul>(a) && !is_a<power>(a) && !a.match(exp_pattern); | |
| }; | |
| if(is_a<add>(e)){ | |
| std::cout << "a : " << e << std::endl; | |
| ex r; | |
| for(std::size_t i = 0, i_ = e.nops(); i < i_; ++i){ | |
| r += (*this)(e.op(i)); | |
| } | |
| return r; | |
| }else if(is_a<mul>(e)){ | |
| std::cout << "b : " << e << std::endl; | |
| ex r, s = 1; | |
| for(std::size_t i = 0, i_ = e.nops(); i < i_; ++i){ | |
| const ex &p = e.op(i); | |
| if(p.match(exp_pattern)){ | |
| r += (*this)(p).subs(exp_pattern == exp_arg_pattern); | |
| }else{ | |
| s *= (*this)(p); | |
| } | |
| } | |
| return exp(r) * s; | |
| }else if(is_a<power>(e)){ | |
| std::cout << "c : " << e << std::endl; | |
| return e.match(exp_pow_pattern) ? (*this)(exp(e.subs(exp_pow_pattern == exp_mul_pattern))) : e; | |
| }else if(e.match(exp_pattern)){ | |
| std::cout << "d : " << e << std::endl; | |
| return exp((*this)(e.op(0))); | |
| }else{ | |
| std::cout << "e : " << e << std::endl; | |
| return e; | |
| } | |
| } | |
| private: | |
| static const ex | |
| exp_pattern, | |
| exp_arg_pattern, | |
| exp_pow_pattern, | |
| exp_mul_pattern; | |
| }; | |
| const ex | |
| map_reduce_exp::exp_pattern = exp(wild(0)), | |
| map_reduce_exp::exp_arg_pattern = wild(0), | |
| map_reduce_exp::exp_pow_pattern = pow(exp(wild(0)), wild(1)), | |
| map_reduce_exp::exp_mul_pattern = wild(0) * wild(1); | |
| } | |
| ex reduce(const ex &expression){ | |
| detail::map_reduce_exp r; | |
| return r(expression); | |
| } | |
| } // namespace ExtGiNaC | |
| int main(){ | |
| using namespace GiNaC; | |
| using namespace ExtGiNaC; | |
| { | |
| symbol x("x"), y("y"), z("z"), p("p"), q("q"); | |
| std::cout << reduce(exp(z) * exp(p) * exp(p) * exp(q) * exp(p)) << std::endl; | |
| std::cout << reduce(exp(exp(x) * exp(y))) << std::endl; | |
| std::cout << reduce(exp(exp(x)) * exp(exp(y)) * exp(exp(exp(z))) * exp(exp(exp(p))) * exp(exp(exp(q)))) << std::endl; | |
| } | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment