Last active
December 12, 2015 09:08
-
-
Save marionette-of-u/4748791 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 <ginac/ginac.h> | |
| namespace ExtGiNaC{ | |
| using namespace GiNaC; | |
| namespace detail{ | |
| class map_reduce_exp : public map_function{ | |
| public: | |
| ex operator ()(const ex &expression){ | |
| return | |
| proc( | |
| expression.subs( | |
| exp_pattern == pow_pattern, | |
| subs_options::algebraic | |
| ) | |
| ).subs(pow_pattern == exp_pattern, subs_options::algebraic); | |
| } | |
| private: | |
| static ex proc(const ex &expression){ | |
| if(is_a<add>(expression)){ | |
| ex a; | |
| for(std::size_t i = 0, i_ = expression.nops(); i < i_; ++i){ | |
| a += proc(expression.op(i)); | |
| } | |
| return a; | |
| }else if(is_a<mul>(expression)){ | |
| ex r, s = 1; | |
| 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(mul_pattern, match_result)){ | |
| ex prod = 1; | |
| for(const auto &item : match_result){ | |
| prod *= proc(item.second); | |
| } | |
| r += prod; | |
| }else{ | |
| s *= proc(t); | |
| } | |
| } | |
| return pow(e, r) * s; | |
| }else if(is_a<power>(expression)){ | |
| return expression.match(mul_pattern) ? | |
| proc(pow(e, expression.subs(mul_pattern == rep_pattern))) : | |
| pow(proc(expression.op(0)), proc(expression.op(1))); | |
| }else{ | |
| return expression; | |
| } | |
| } | |
| static const symbol e; | |
| static const ex exp_pattern, pow_pattern, mul_pattern, rep_pattern; | |
| }; | |
| const symbol map_reduce_exp::e; | |
| const ex | |
| map_reduce_exp::exp_pattern = exp(wild(0)), | |
| map_reduce_exp::pow_pattern = pow(e, wild(0)), | |
| map_reduce_exp::mul_pattern = pow(pow(e, wild(0)), wild(1)), | |
| map_reduce_exp::rep_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; | |
| std::cout << (pow(exp(Pi), I) + 1) << std::endl; // output is "1+exp(Pi)^I". | |
| std::cout << reduce(pow(exp(Pi), I) + 1) << std::endl; // output is "0". | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment