Skip to content

Instantly share code, notes, and snippets.

@marionette-of-u
Created February 9, 2013 17:42
Show Gist options
  • Select an option

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

Select an option

Save marionette-of-u/4746255 to your computer and use it in GitHub Desktop.
#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 <functional>
#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("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;
{
symbol x("x"), y("y"), z("z"), p("p"), q("q"), e("e");
ex expression;
std::cout << reduce(exp(z) * exp(p) * exp(p) * exp(q) * exp(p) * exp(exp(exp(e) * exp(e)) * exp(x) * exp(y) * exp(x) * exp(x))) << std::endl;
std::cout << reduce(exp(exp(x) * exp(y))) << std::endl;
std::cout << reduce(exp(exp(x) * 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