File:  [CENS] / python / pyGiNaC / wrappers2 / python_repr.cpp
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Thu Apr 19 05:49:44 2001 UTC (16 years, 7 months ago) by pearu
Branches: MAIN
CVS tags: HEAD
Trying boost.python cross_module feature

/*
# This file is part of the PyGiNaC package.
# http://cens.ioc.ee/projects/pyginac/
#
# $Revision: 1.1 $
# $Id: python_repr.cpp,v 1.1 2001-04-19 05:49:44 pearu Exp $
#
# Copyright 2001 Pearu Peterson all rights reserved,
# Pearu Peterson <pearu@cens.ioc.ee>
# Permission to use, modify, and distribute this software is given under the
# terms of the LGPL.  See http://www.fsf.org
#
# NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
#
*/

//#include <Python.h>
#include <boost/python/class_builder.hpp>
#include "python_repr.hpp"
#include "pyfunc.hpp"


#if GINACLIB_MAJOR_VERSION == 0 && (GINACLIB_MINOR_VERSION < 8 || (GINACLIB_MINOR_VERSION == 8 && GINACLIB_MICRO_VERSION == 0))
#define GINAC_VERSION_0_8_0_OR_EARLIER
#endif

#define PYGINAC_WRAP(OBJ,CLASS) ((const wrap_##CLASS &)OBJ)

#if 0
#define DEBUG_REPR(o) cout << o << endl;
#else
#define DEBUG_REPR(o)
#endif

#ifdef GINAC_VERSION_0_8_0_OR_EARLIER
#define GINAC_python_str(e) e.print(os,level)
#define PYGINAC_FUNCTION_GETNAME(f) PYGINAC_WRAP(f,function).get_name()
#else
#define GINAC_python_str(e) e.print(print_context(os),level)
#define PYGINAC_FUNCTION_GETNAME(f) f.get_name()
#endif


namespace python = boost::python;

namespace GiNaC {

  std::map<unsigned, python::ref> constant_cache; // see wrappers/constant.py
  std::map<unsigned, python::ref> & constant_w_cache(void) {
    return constant_cache;
  }

  //#include "wrap_classes.h"



static void python_repr_ops(std::ostream &, const ex &);

class wrap_function: public function {
public:
  std::string get_name(void) const { return registered_functions()[serial].get_name(); }
};

class wrap_add: public add {
public:
  inline const epvector & get_seq(void) const { return this->seq; }
  inline const ex & get_overall_coeff(void) const { return this->overall_coeff; }
};

class wrap_mul: public mul {
public:
  inline const epvector & get_seq(void) const { return this->seq; }
  inline const ex & get_overall_coeff(void) const { return this->overall_coeff; }
};
class wrap_relational: public relational {
public:
  inline operators get_o(void) const { return this->o; }
};

class wrap_indexed: public indexed {
public:
  inline symmetry_type get_symmetry(void) const { return this->symmetry; }
  inline unsigned get_representation_label(void) const {
    return 0;
    //return ((const color &)(*this)).representation_label;
    // ask GiNaC people to make it protected
  }
};
class wrap_pseries: public pseries {
public:
  inline const epvector & get_seq(void) const { return this->seq; }
  inline const ex & get_var(void) const { return this->var; }
  inline const ex & get_point(void) const { return this->point; }
};
class wrap_matrix: public matrix {
public:
  inline const exvector & get_m(void) const { return this->m; }
};
  
void python_repr(std::ostream & os, const ex & e)
{
  DEBUG_REPR("python_repr("<<e.bp->class_name()<<",hash="<<e.bp->gethash()<<")");
  if (is_ex_of_type(e, function))
    os << PYGINAC_FUNCTION_GETNAME(ex_to_function(e));
  else
    os << e.bp->class_name();
  os << '(';
  if (is_ex_of_type(e, expairseq) || is_ex_of_type(e, lst))
    os << '[';
  if (is_ex_of_type(e, pseries))
    python_repr(os, ex_to_pseries(e));
  else if (is_ex_of_type(e, function))
    python_repr(os, ex_to_function(e));
  else if (is_ex_of_type(e, matrix))
    python_repr(os, ex_to_matrix(e));
  else if (is_ex_of_type(e, indexed))
    python_repr(os, ex_to_indexed(e));
  else
    python_repr_ops(os, e);
  if (is_ex_of_type(e, expairseq) || is_ex_of_type(e, lst))
    os << ']';
  os << ')';
}

void python_repr(std::ostream & os, const expair & v)
{
  DEBUG_REPR("python_repr_expair()");
  os << "(";
  python_repr(os, v.rest);
  os << ", ";
  python_repr(os, v.coeff);
  os << ")";
}

void python_repr(std::ostream & os, const epvector & v)
{
  DEBUG_REPR("python_repr_epvector()");
  unsigned n = v.size();
  os << "[";
  for (unsigned i=0; i<n; i++) {
    python_repr(os, v[i]);
    if (i != n-1)
      os << ", ";
  }
  os << "]";
}

void python_repr(std::ostream & os, const exvector & v)
{
  DEBUG_REPR("python_repr_exvector()");
  unsigned n = v.size();
  os << "[";
  for (unsigned i=0; i<n; i++) {
    python_repr(os, v[i]);
    if (i != n-1)
      os << ", ";
  }
  os << "]";
}

static void python_repr_ops(std::ostream & os, const ex & e) {
  DEBUG_REPR("python_repr_ops("<<e.bp->class_name()<<",hash="<<e.bp->gethash()<<")");
  unsigned n = e.nops();  
  if (n)
    for (unsigned i=0; i<n; i++) {
      python_repr(os, e.op(i));
      if (i != n-1)
        os << ", ";
    }
  else if (is_ex_of_type(e, lst))
    ;
  else
    os << "'" << e << "'";    
  if (is_ex_of_type(e, constant)) {
    const std::map<unsigned, ::python::ref>::const_iterator viter = constant_cache.find(e.bp->gethash());
    if (!(viter==constant_cache.end()))
      os << ", " << PyString_AsString(PyObject_Repr(viter->second.get()));
  }
  else if (is_ex_of_type(e, relational)) {
    if (e.bp->info(info_flags::relation_equal))
      ;
    else if (e.bp->info(info_flags::relation_not_equal))
      os << ", relational.ne";
    else if (e.bp->info(info_flags::relation_less))
      os << ", relational.lt";
    else if (e.bp->info(info_flags::relation_less_or_equal))
      os << ", relational.le";
    else if (e.bp->info(info_flags::relation_greater))
      os << ", relational.gt";
    else if (e.bp->info(info_flags::relation_greater_or_equal))
      os << ", relational.ge";
    else
      os << ", (INVALID RELATIONAL OPERATOR)";
  }
  else if (is_ex_of_type(e, idx)) {
    os << ", ";
    python_repr(os, ex_to_idx(e).get_dim());
    if (is_ex_of_type(e, varidx) && ex_to_varidx(e).is_covariant())
      os << ", 1";
  }
}

void python_repr(std::ostream & os, const matrix & m)
{
  DEBUG_REPR("python_repr_matrix("<<",hash="<<m.gethash()<<")");
  unsigned rows = m.rows();
  unsigned cols = m.cols();
  os << "[";
  for (unsigned j=0; j<rows; ++j) {
    if (j>0)
      os << "        ";
    os << "[";
    for (unsigned i=0; i<cols-1; ++i) {
      python_repr(os, m(j,i));
      os << ", ";
    }
    python_repr(os, m(j,cols-1));
    os << "]";
    if (j<rows-1)
      os << "," << std::endl;
  }
  os << "]";
}

void python_repr(std::ostream & os, const pseries & s)
{
  DEBUG_REPR("python_repr_pseries("<<s.class_name()<<",hash="<<s.gethash()<<")");
  python_repr(os, PYGINAC_WRAP(s,pseries).get_var());
  os << ", ";
  python_repr(os, PYGINAC_WRAP(s,pseries).get_point());
  os << ", ";
  python_repr(os, PYGINAC_WRAP(s,pseries).get_seq());
}

void python_repr(std::ostream & os, const function & f)
{
  DEBUG_REPR("python_repr_function("<<f.class_name()<<",hash="<<f.gethash()<<")");
  unsigned n = f.nops();
  if (n>0
#ifdef PYGINAC_pyfunc
      && !is_ex_exactly_of_type(f.op(0), pyfunc)
#endif
      )
    python_repr(os, f.op(0));
  for (unsigned i=1; i<n-1; ++i) {
    os << ", ";
    python_repr(os, f.op(i));
  }
  if (n>1
#ifdef PYGINAC_pyfunc
      && !is_ex_exactly_of_type(f.op(n-1), pyfunc)
#endif
      ) {
    os << ", ";
    python_repr(os, f.op(n-1));
  }
}

void python_repr(std::ostream & os, const indexed & s)
{
  DEBUG_REPR("python_repr_indexed("<<s.class_name()<<",hash="<<s.gethash()<<")");
  unsigned n = s.nops();
  indexed::symmetry_type symmetry = PYGINAC_WRAP(s,indexed).get_symmetry();
  if (is_ex_of_type(ex(s), clifford)) {
    if (n==1)
      python_repr(os,s.op(0));
    else if (n==2) {
      python_repr(os,s.op(0));
      os << ", ";
      python_repr(os,s.op(1));
    }
    else if (n>0) {
      os << '[';
      python_repr(os,s.op(0));
      for (unsigned i=1; i<n; ++i) {
	os << ", ";
	python_repr(os,s.op(i));
      }
      os << ']';
    }
  }
  else if (is_ex_of_type(ex(s), color)) {
    unsigned rl = PYGINAC_WRAP(s,indexed).get_representation_label();
    if (n==1) {
      python_repr(os,s.op(0));
      if (rl>0)
	os << ", " << rl;
    }
    else if (n==2) {
      python_repr(os,s.op(0));
      os << ", ";
      python_repr(os,s.op(1));
      if (rl>0)
	os << ", " << rl;
    }
    else {
      os << rl << ", [";
      if (n>0)
	python_repr(os,s.op(0));
      for (unsigned i=1; i<n; ++i) {
	os << ", ";
	python_repr(os,s.op(i));
      } 
      os << "]";
    }
  }
  else {
    if (n>0)
      python_repr(os,s.op(0));
    if (n>1) {
      switch (symmetry) {
      case indexed::symmetric: os << ", indexed.symmetric"; break;
      case indexed::antisymmetric: os << ", indexed.antisymmetric"; break;
      case indexed::mixed: os << ", indexed.mixed"; break;
      case indexed::unknown: break;
      default: os << "(INVALID SYMMETRY TYPE)";
      }
      os << ", [";
      python_repr(os,s.op(1));
    }
    for (unsigned i=2; i<n; ++i) {
      os << ", ";
      python_repr(os,s.op(i));
    }
    if (n>1)
      os << ']';
  }
}

}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>