File:  [CENS] / python / pyGiNaC / wrappers / constant.py
Revision 1.4: download - view: text, annotated - select for diffs - revision graph
Tue Apr 17 22:39:25 2001 UTC (16 years, 7 months ago) by pearu
Branches: MAIN
CVS tags: HEAD
Fixed bugs. Exposed/checked functions. Started testing framework.

# This file is part of the PyGiNaC package.
# http://cens.ioc.ee/projects/pyginac/
#
# $Revision: 1.4 $
# $Id: constant.py,v 1.4 2001-04-17 22:39:25 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.
#

depends = ['basic']

uses = ['numeric','ex']


#STARTPROTO

class constant(basic):
    """Holds constants, symbols with specific numerical value."""

    def __init__(self,name,value_func = None):
        """constant(name) - create a constant with a name `name'.
    constant(name, value) - create a constant with a value `value'.
    constant(name, func) - create a constant with a value computed
        as func().
    constant(ex(constant(...))) - returns constant(...).
    """

Pi = '3.1415926535897932385...'
Euler = '0.5772156649015328606...'
Catalan = '0.91596559417721901505...'

#ENDPROTO

wrapperclass = '''
class constant_w : public GiNaC::constant {
  PyObject * self;
public:
  static GiNaC::ex dummy(void) {
    PyErr_SetString(PyExc_RuntimeError,"constant() internal error (dummy accessed)");
    throw python::error_already_set();
  }
  constant_w(python::ref);

  constant_w(PyObject *, python::ref, python::ref);
  constant_w(PyObject * self_, python::ref c)
  : GiNaC::constant(constant_w(c)) {
    DEBUG_C("constant_w::constant_w(constant)");
  }
  constant_w(PyObject * self_, const GiNaC::constant & c)
  : GiNaC::constant(c) {
    DEBUG_C("constant_w::constant_w(constant)");
  }
  constant_w(PyObject * self_, const GiNaC::ex & c)
  : GiNaC::constant(ex_to_constant_w(c)) {
    DEBUG_C("constant_w::constant_w(ex)");
  }

  ~constant_w() {
    DEBUG_C("constant_w::~constant_w()");
    std::map<unsigned, python::ref> & constant_cache = GiNaC::constant_w_cache();
    const std::map<unsigned, python::ref>::const_iterator viter = constant_cache.find(this->gethash());
    if (!(viter==constant_cache.end())) {
      Py_XDECREF(viter->second.get());
      constant_cache.erase(this->gethash());
    }
  }
};

'''

protos = '''
'''

builder = '''
python::class_builder<constant_w> constant_w_class(this_module, "_constant_w");
python::class_builder<GiNaC::constant, constant_w> constant_class(this_module, "constant");
constant_py_class = python::as_object(constant_class.get_extension_class());
constant_class.declare_base(constant_w_class);
constant_class.declare_base(basic_class);
'''

constructors = '''\
constant_class.def(python::constructor<const GiNaC::constant &>());
constant_class.def(python::constructor<const GiNaC::ex &>());
constant_class.def(python::constructor<python::ref>());
constant_class.def(python::constructor<python::ref, python::ref>());
'''

defs = '''
this_module.add(BOOST_PYTHON_CONVERSION::to_python(GiNaC::Pi), "Pi");
this_module.add(BOOST_PYTHON_CONVERSION::to_python(GiNaC::Catalan), "Catalan");
this_module.add(BOOST_PYTHON_CONVERSION::to_python(GiNaC::Euler), "Euler");

constant_class.def(&basic_w::python_str, "__str__");
constant_class.def(&basic_w::python_repr, "__repr__");
constant_class.def(&basic_w::coerce, "__coerce__");
BASIC_OPS(constant)

//constant_class.def(python::operators<(python::op_sub | python::op_add | python::op_mul | python::op_div | python::op_neg | python::op_pos)>());
'''

implementation = '''
EX_TO_BASIC(constant)

constant_w::constant_w(PyObject * self_, python::ref name, python::ref other)
: GiNaC::constant(PyString_AS_STRING(PyObject_Str(name.get())),dummy), self(self_) {
  PyObject * obj = other.get();
  DEBUG_C("constant_w::constant_w(ref,ref)");
  if (!(PyString_Check(name.get()))) {
    PyErr_SetString(PyExc_TypeError,"constant() first argument must be a string");
    throw python::error_already_set();
  }
  if (!PyCallable_Check(obj))
    obj = BOOST_PYTHON_CONVERSION::to_python(GiNaC::ex(ex_w(python::ref(obj))));
  Py_INCREF(obj);
  GiNaC::constant_w_cache()[this->gethash()] = python::ref(obj);
}

constant_w::constant_w(python::ref name)
: GiNaC::constant(PyString_AS_STRING(PyObject_Str(name.get()))) {
  DEBUG_C("constant_w::constant_w(raw:ref)");
  if (!(PyString_Check(name.get()))) {
    PyErr_SetString(PyExc_TypeError,"constant() argument must be string|string,ex|string,lambda:ex");
    throw python::error_already_set();
  }
}
'''

GiNaC_implementation = '''
ex constant::evalf(int level) const
{
    std::map<unsigned, python::ref> & constant_cache = GiNaC::constant_w_cache();
        if (ef==::constant_w::dummy) {
           const std::map<unsigned, python::ref>::const_iterator viter = constant_cache.find(this->gethash());
           if (viter==constant_cache.end()) {
             PyErr_SetString(PyExc_RuntimeError,"constant() internal error (cache failed)");
             throw python::error_already_set();
           }
           PyObject * ret = viter->second.get();
           if (PyCallable_Check(ret))
             ret = PyObject_CallFunction(ret,NULL);
           if (ret==NULL)
             throw python::error_already_set();
           ex r = ::ex_w(python::ref(ret));
           return r.evalf();
        }
        if (ef!=0) {
          return ef();
        } else if (number != 0) {
                return number->evalf();
        }
        return *this;
}
'''



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