Skip to content

Instantly share code, notes, and snippets.

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

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

Select an option

Save marionette-of-u/4740446 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 <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