Skip to content

Instantly share code, notes, and snippets.

@marionette-of-u
Last active December 12, 2015 09:08
Show Gist options
  • Select an option

  • Save marionette-of-u/4748791 to your computer and use it in GitHub Desktop.

Select an option

Save marionette-of-u/4748791 to your computer and use it in GitHub Desktop.
#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