Last active
December 12, 2015 10:39
-
-
Save marionette-of-u/4760513 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 <iostream> | |
| #include <functional> | |
| #include <ginac/ginac.h> | |
| namespace ExtGiNaC{ | |
| using namespace GiNaC; | |
| namespace detail{ | |
| class exp_alternate_form{ | |
| public: | |
| ex operator ()(const ex &expression){ | |
| symbol e; | |
| return | |
| proc( | |
| expression.subs( | |
| exp(wild(0)) == pow(e, wild(0)), subs_options::algebraic | |
| ), e | |
| ).subs( | |
| pow(e, wild(0)) == exp(wild(0)), subs_options::algebraic | |
| ); | |
| } | |
| private: | |
| static ex proc(const ex &expression, const ex &base){ | |
| if(is_a<add>(expression)){ | |
| ex sum; | |
| for(std::size_t i = 0, i_ = expression.nops(); i < i_; ++i){ | |
| sum += proc(expression.op(i), base); | |
| } | |
| return sum; | |
| } | |
| const ex mul_pattern = pow(pow(base, wild(0)), wild(1)), rep_pattern = wild(0) * wild(1); | |
| if(is_a<mul>(expression)){ | |
| ex r, s = 1; | |
| const ex pow_pattern = pow(base, wild(0)); | |
| for(std::size_t i = 0, i_ = expression.nops(); i < i_; ++i){ | |
| const ex &t = expression.op(i); | |
| exmap match_result; | |
| if(t.match(pow_pattern, match_result) || t.match(pow(pow(base, wild(0)), wild(1)), match_result)){ | |
| ex prod = 1; | |
| for(const auto &item : match_result){ | |
| prod *= proc(item.second, base); | |
| } | |
| r += prod; | |
| }else{ | |
| s *= proc(t, base); | |
| s = s.subs(pow(wild(0), wild(1)) * pow(wild(0), wild(2)) == pow(wild(0), wild(1) + wild(2)), subs_options::algebraic); | |
| } | |
| } | |
| return pow(base, r) * s; | |
| }else if(is_a<power>(expression)){ | |
| ex n_expression = expression.match(mul_pattern) ? | |
| pow(base, proc(expression.subs(mul_pattern == rep_pattern), base)) : | |
| pow(proc(expression.op(0), base), proc(expression.op(1), base)); | |
| if(n_expression.match(pow(pow(wild(0), wild(1)), wild(2)))){ | |
| const ex &a = n_expression; | |
| return pow(a.op(0).op(0), proc(a.op(0).op(1) * a.op(1), a.op(0).op(0))); | |
| }else{ | |
| return n_expression; | |
| } | |
| }else{ | |
| return expression; | |
| } | |
| } | |
| }; | |
| } | |
| ex reduce(const ex &expression){ | |
| detail::exp_alternate_form r; | |
| return r(expression); | |
| } | |
| } // namespace ExtGiNaC | |
| int main(){ | |
| using namespace ExtGiNaC; | |
| symbol z("z"); | |
| auto f = [](const ex &x){ | |
| return exp(x); | |
| }; | |
| auto g = [&z](const ex &x){ | |
| return pow(z, x); | |
| }; | |
| symbol a("a"), b("b"), c("c"); | |
| ex p = f(a) * f(a) * f(a) * f(a) * f(f(b) * f(b)) * f(f(c) * f(c) * f(c)); | |
| ex q = g(a) * g(a) * g(a) * g(a) * g(g(b) * g(b)) * g(g(c) * g(c) * g(c)); | |
| ex r = q * q * q * p * p * p; | |
| std::cout << r << " = " << reduce(r) << std::endl; | |
| std::cout << (pow(exp(Pi), I) + 1) << " = " << reduce(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