File:  [CENS] / python / pyGiNaC / wrappers / symbol.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: symbol.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 = []


#STARTPROTO

class symbol(basic):
    """Basic CAS symbol."""
    def __init__(self,*args):
        """symbol() - creates a symbol. Its name will be of the form 'symbol\d+'.
    symbol(name) - creates a symbol with a name `name'.
    symbol(ex(symbol(...))) - returns symbol(...).
    """
    def assign(self,expr):
        """Assign an expression `expr' to symbol."""
    def unassign(self):
        """Forget previous assignment."""
    def get_name(self):
        """Return symbol name."""
    def set_name(self,newname):
        """Set symbol name to `newname'."""
def unassign(sym):
    """Forget previous assignment of a symbol `sym'."""

#ENDPROTO

#STARTDOCTEST
def test_01_symbol():
    """
This doc string tests symbol objects
>>> import ginac

#>>> print ginac.__file__
>>> from ginac import symbol

To construct symbol with a name:
>>> x = symbol('x')
>>> print x
x
>>> x
symbol('x')

To construct symbol without a name (it will be generated in the form `symbol\d+'):
>>> y = symbol()
>>> y
symbol('symbol1')

To change the name of a symbol:
>>> y.set_name('y')
>>> print y
y

To get symbols name:
>>> y.get_name()
'y'

To assign an expression for the given symbol
>>> y.assign(x*x)
>>> print y
x ** 2

Get the name of an assigned symbol:
>>> y.get_name()
'y'

To disable previous assignment:
>>> y.unassign()
>>> print y
y

There is also a function for that:
>>> from ginac import unassign
>>> y.assign(x*x*x)
>>> y
power(symbol('x'), numeric('3'))
>>> unassign(y)
>>> y
symbol('y')

symbol requires a string input argument (see above):
>>> symbol(1)
Traceback (most recent call last):
            ...
TypeError: symbol() argument must be string|symbol|ex(symbol)

or another symbol (then symbol does nothing):
>>> symbol(y)
symbol('y')

or an ex objected holding a symbol (then unex operation is applied):
>>> from ginac import ex
>>> symbol(ex(y))
symbol('y')

If ex holds something different not, then an exception is raised:
>>> symbol(ex(2*y))
Traceback (most recent call last):
            ...
TypeError: ex_to_symbol() argument must be ex(symbol)
>>> symbol(2*y)
Traceback (most recent call last):
            ...
TypeError: symbol() argument must be string|symbol|ex(symbol)

You can use unex function to get what's inside an expression:
>>> from ginac import unex
>>> unex(ex(y))
symbol('y')

Unary operations with symbols:
>>> +x
symbol('x')
>>> -x
mul([symbol('x'), numeric('-1')])

Binary operations with symbols:
>>> x+y
add([symbol('y'), symbol('x')])
>>> x-y
add([mul([symbol('y'), numeric('-1')]), symbol('x')])
>>> x*y
mul([symbol('y'), symbol('x')])
>>> x**y
power(symbol('x'), symbol('y'))
>>> x/y
mul([power(symbol('y'), numeric('-1')), symbol('x')])

Mixed operations:
>>> x+2
add([symbol('x'), numeric('2')])
>>> 2+x
add([symbol('x'), numeric('2')])
>>> x-2
add([symbol('x'), numeric('-2')])
>>> 2-x
add([mul([symbol('x'), numeric('-1')]), numeric('2')])
>>> x*2
mul([symbol('x'), numeric('2')])
>>> 2*x
mul([symbol('x'), numeric('2')])
>>> x/2
mul([symbol('x'), numeric('1/2')])
>>> 2/x
mul([power(symbol('x'), numeric('-1')), numeric('2')])
>>> x**2
power(symbol('x'), numeric('2'))
>>> 2**x
power(numeric('2'), symbol('x'))

Symbol inherits methods also from the basic object:
>>> y.nops()
0
>>> y.op(0)
Traceback (most recent call last):
            ...
IndexError: basic.op index out of range
>>> y.has(y),y.has(x)
(1, 0)
>>> y.coeff(y), y.coeff(x)
(numeric('1'), numeric('0'))
>>> y.degree(y), y.degree(x)
(1, 0)
>>> y.ldegree(y), y.ldegree(x)
(1, 0)
>>> y.collect(y)
symbol('y')
>>> y.diff(y), y.diff(x), x.diff(x,0),x.diff(x,2)
(numeric('1'), numeric('0'), symbol('x'), numeric('0'))
>>> print y.eval(), y.evalf()
y y
>>> x.get_free_indices ()
exvector([])
>>> x.integer_content()
numeric('1')
>>> x.is_equal(x),x.is_equal(ex(x)),x.is_equal(y)
(1, 1, 0)
>>> x.get_hash() > 0
1
>>> x.max_coefficient()
numeric('1')
>>> x.normal([],[]) # may change in future releases
lst([symbol('x'), numeric('1')])
>>> ex(x).normal()
symbol('x')
>>> #x.series(x,1,2)
>>> x.smod(2)
symbol('x')
>>> x.subs(x,y)
symbol('y')
>>> x.subs(x,2)
numeric('2')
>>> x.subs(x,x)
symbol('x')
>>> x.tinfo()
131073
>>> x.to_rational((x,2))
symbol('x')

"""
#ENDDOCTEST

wrapperclass = '''
class symbol_w : public GiNaC::symbol {
  PyObject * self;
public:
  symbol_w(python::ref);
  symbol_w(const GiNaC::symbol & other)
  : GiNaC::symbol(other) {
    DEBUG_C("symbol_w::symbol_w(raw:symbol)")
  }
  symbol_w(const GiNaC::ex & other)
  : GiNaC::symbol(ex_to_symbol_w(other)) {
    DEBUG_C("symbol_w::symbol_w(raw:ex)")
  }
  symbol_w(PyObject * self_): GiNaC::symbol(), self(self_) {
    DEBUG_C("symbol_w::symbol_w()");
  }
  symbol_w(PyObject * self_, const GiNaC::symbol & other)
  : GiNaC::symbol(other), self(self_) {
    DEBUG_C("symbol_w::symbol_w(symbol)")
  }
  symbol_w(PyObject * self_, const GiNaC::ex & other)
  : GiNaC::symbol(ex_to_symbol_w(other)), self(self_) {
    DEBUG_C("symbol_w::symbol_w(ex)")
  }
  symbol_w(PyObject * self_, python::ref other)
  : GiNaC::symbol(symbol_w(other)), self(self_) {
    DEBUG_C("symbol_w::symbol_w(ref)")
  }
  ~symbol_w() {
    DEBUG_C("symbol_w::~symbol_w()");
  }
  inline void assign_w(python::ref value) { this->assign(ex_w(value)); };
};
'''

protos = '''
'''

builder = '''
python::class_builder<symbol_w> symbol_w_class(this_module, "_symbol_w");
python::class_builder<GiNaC::symbol, symbol_w> symbol_class(this_module, "symbol");
symbol_class.declare_base(symbol_w_class);
symbol_class.declare_base(basic_class);
symbol_py_class = python::as_object(symbol_class.get_extension_class());
'''

constructors = '''
symbol_class.def(python::constructor<>());
symbol_class.def(python::constructor<const GiNaC::symbol &>());
symbol_class.def(python::constructor<const GiNaC::ex &>());
symbol_class.def(python::constructor<python::ref>());
'''

defs = '''
symbol_class.def(&basic_w::python_str, "__str__");
symbol_class.def(&basic_w::python_repr, "__repr__");
symbol_class.def(&basic_w::coerce, "__coerce__");

BASIC_OPS(symbol)

symbol_class.def(&symbol_w::assign_w, "assign");
symbol_class.def(&symbol_w::unassign, "unassign");
#ifdef GINAC_VERSION_0_8_0_OR_EARLIER
symbol_class.def(&symbol_w::setname, "set_name");
symbol_class.def(&symbol_w::getname, "get_name");
#else
symbol_class.def(&symbol_w::set_name, "set_name");
symbol_class.def(&symbol_w::get_name, "get_name");
#endif

this_module.def(GiNaC::unassign, "unassign");
'''

implementation = '''
EX_TO_BASIC(symbol)

symbol_w::symbol_w(python::ref other): GiNaC::symbol() {
  PyObject * o = other.get();
  DEBUG_C("symbol_w::symbol_w(raw:ref)");
  if (PyString_Check(o))
#ifdef GINAC_VERSION_0_8_0_OR_EARLIER
    this->setname(PyString_AS_STRING(o));
#else
    this->set_name(PyString_AS_STRING(o));
#endif
  else if (SymbolInstance_Check(o))
    this->copy(BOOST_PYTHON_CONVERSION::from_python(o, python::type<const GiNaC::symbol &>()));
  else if (ExInstance_Check(o))
    this->copy(ex_to_symbol_w(BOOST_PYTHON_CONVERSION::from_python(o, python::type<const GiNaC::ex &>())));
  else {
    PyErr_SetString(PyExc_TypeError, "symbol() argument must be string|symbol|ex(symbol)");
    throw python::error_already_set();
  }
}
'''

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