File:  [CENS] / python / pyGiNaC / python1.5 / ginac.py
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Fri Apr 27 11:36:59 2001 UTC (16 years, 7 months ago) by pearu
Branches: MAIN
CVS tags: HEAD
Fixed mul bug for Python<2.1

"""See `ginac.doc' for PyGiNaC class documentation."""

# This file is part of the PyGiNaC package.
# http://cens.ioc.ee/projects/pyginac/
#
# $Revision: 1.1 $
# $Id: ginac.py,v 1.1 2001-04-27 11:36:59 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.
#

_builtin_eval = eval

import sys,types
_sys = sys
_types = types
del sys, types

import _ginac
from _ginac import *

def eval(a1,a2=None,a3=None,eval_f=_builtin_eval):
    """Fix overloading built-in eval() with _ginac.eval()."""
    if type(a1) in [_types.CodeType,_types.StringType]:
        if a2 is not None:
            if a3 is not None:
                return eval_f(a1,a2,a3)
            return eval_f(a1,a2)
        return eval_f(a1)
    if a2 is not None:
        return _ginac.eval(a1,a2)
    return _ginac.eval(a1)
del _builtin_eval

def build_function(name,texname=None,
                   eval_f=None,evalf_f=None,
                   derivative_f=None,series_f=None,
                   nofargs=None):
    """Construct symbolic function with a name `name'.

    Optional arguments:
    texname - LaTeX string;
    nofargs - the number of arguments to a function (if not specified,
      build_function tries to establish `nofargs' from functions `eval',
      `evalf', `derivative', `series'. If that fails, 12 is set.);
    eval_f    - eval_f(*args) is used for automatic non-interruptive symbolic
      evaluation;
    evalf_f   - evalf_f(*args) is used for numeric evaluation;
    derivative_f - derivative_f(*args,i) is used for computing
              the 1st derivative with respect to `i'-th argument (i>=0);
    series_f  - series_f(*args,rel,order,opts = 0) is used for computing
              the truncated series expansion around a point `rhs(rel)'
              with respect to variable `lhs(rel)'. `order' is the truncation
              order.
    """
    if nofargs is None:
        _nof_function_params = 12
        exec """\
def _get_arg_limits(f):
    '''Return the number of arguments required by a function `f\'.'''
    nofargs = len(f.func_code.co_varnames)
    argcount = f.func_code.co_argcount
    if f.func_defaults: nofdefargs = len(f.func_defaults)
    else: nofdefargs=0
    minargs1 = argcount - nofdefargs
    maxargs1 = nofargs
    if nofargs > argcount: maxargs1 = _nof_function_params
    return minargs1,maxargs1\n"""
        minargs = 0
        maxargs = _nof_function_params
        if eval_f is not None:
            mn,mx = _get_arg_limits(eval_f)
            minargs = mn
            maxargs = mx
        if evalf_f is not None:
            mn,mx = _get_arg_limits(evalf_f)
            minargs = max(minargs,mn)
            maxargs = min(maxargs,mx)
        if derivative_f is not None:
            mn,mx = _get_arg_limits(derivative_f)
            minargs = max(minargs,mn-1)
            maxargs = min(maxargs,mx-1)
        if series_f is not None:
            mn,mx = _get_arg_limits(series_f)
            minargs = max(minargs,mn-3)
            maxargs = min(maxargs,mx-3)
        if minargs <= maxargs:
            nofargs = minargs
        else:
            raise TypeError,'build_function() inconsistent arguments: minargs,maxargs=%s,%s'%(minargs,maxargs)
    else:
        minargs = maxargs = nofargs
    ser = _ginac._build_function(nofargs,name,
                                 texname=texname,
                                 eval=eval_f,evalf=evalf_f,
                                 derivative=derivative_f,series=series_f)
    if minargs==maxargs:
        exec '''
def %s(*a,**k):
    if k.has_key("hold"): hold = k["hold"]
    else: hold = 0
    args = list(a)+[_ginac._pyfunc(%s)]
    if not(%s == len(a)):
        raise TypeError,"function %s() takes exactly %s argument (%%s given)"%%(len(a))
    return _ginac._function(%s,hold,args)
fun = %s
'''%(name,ser,minargs,name,minargs,ser,name)
    else:
        exec '''
def %s(*a,**k):
    if k.has_key("hold"): hold = k["hold"]
    else: hold = 0
    args = list(a)+[_ginac._pyfunc(%s)]
    if not(%s <= len(a) <= %s):
        raise TypeError,"function %s() takes %s...%s arguments (%%s given)"%%(len(a))
    return _ginac._function(%s,hold,args)
fun = %s
'''%(name,ser,minargs,maxargs,name,minargs,maxargs,ser,name)
    return fun

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