Ticket #11576: trac_11576-indexed_expression.patch

File trac_11576-indexed_expression.patch, 9.2 KB (added by vbraun, 6 years ago)

Rebased patch

  • sage/libs/ginac.pxd

    # HG changeset patch
    # User Burcin Erocal <burcin@erocal.org>
    # Date 1321619725 -3600
    #      Fri Nov 18 13:35:25 2011 +0100
    # Node ID 62900b98a0c9b12dc767ad5f26de51ba47c65cbc
    # Parent  5d98b0e4a5023ecd4be23fb6630bb0e712bf9da5
    Prototype implementation for indexed symbolic expressions.
    
    diff --git a/sage/libs/ginac.pxd b/sage/libs/ginac.pxd
    a b  
    2020   
    2121    # forward declaration of GEx
    2222    ctypedef struct GEx "ex"
     23    ctypedef struct GExVector "exvector"
    2324
    2425    ctypedef struct GBasic "basic":
    2526        unsigned int gethash()
     
    9899        GEx real_part()               except +
    99100        GEx imag_part()               except +
    100101        bint info(unsigned)           except +
     102        GEx simplify_indexed(unsigned int options) except +
     103        GExVector get_free_indices()  except +
    101104
    102105    GExPair make_pair "std::make_pair" (GEx, GEx)
    103106
     
    233236
    234237    void g_list_symbols "list_symbols" (GEx e, GExSet s)
    235238
     239    # indexed expressions
     240    ctypedef struct GIdx "idx":
     241        GEx get_value()
     242        GEx get_dim()
     243
     244    GIdx ginac_idx "GiNaC::idx" (GEx v, GEx d) except +
     245    GEx ginac_indexed_p "GiNaC::indexed" (GEx v, GIdx i) except +
     246    GEx ginac_indexed_pp "GiNaC::indexed" (GEx v, GIdx i, GIdx j) except +
     247    bint is_a_idx "is_a<idx>" (GEx e)
     248    GIdx ex_to_idx "ex_to<idx>" (GEx e)
     249
    236250    # more is_a tests
    237251    bint is_a_add "is_a<add>" (GEx e)
    238252    bint is_a_mul "is_a<mul>" (GEx e)
  • sage/symbolic/expression.pyx

    diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
    a b  
    142142import sage.rings.integer
    143143import sage.rings.rational
    144144from sage.structure.element cimport ModuleElement, RingElement, Element
    145 from sage.symbolic.getitem cimport OperandsWrapper
     145from sage.symbolic.pynac cimport exvector_to_PyTuple
     146from sage.symbolic.getitem cimport OperandsWrapper, IndexWrapper
    146147from sage.symbolic.function import get_sfunction_from_serial, SymbolicFunction
    147148from sage.rings.rational import Rational  # Used for sqrt.
    148149from sage.misc.derivative import multi_derivative
     
    43264327            res._expr = self
    43274328            return res
    43284329
     4330    property ind:
     4331        def __get__(self):
     4332            """
     4333            sage: ex = x + 1
     4334            sage: id = ex.ind[Permutation([2,1,3])]
     4335            sage: id.get_index()
     4336            """
     4337            cdef IndexWrapper res = IndexWrapper.__new__(IndexWrapper)
     4338            res._expr = self
     4339            return res
     4340
     4341    def simplify_indexed(self):
     4342        from sage.symbolic.ring import SR
     4343        return new_Expression_from_GEx(SR, self._gobj.simplify_indexed(0))
     4344
     4345    def get_free_indices(self):
     4346        cdef GExVector vec = self._gobj.get_free_indices()
     4347        return exvector_to_PyTuple(vec)
     4348
    43294349    def _numerical_approx(self, prec=None, digits=None):
    43304350        """
    43314351        Return a numerical approximation this symbolic expression as
  • sage/symbolic/getitem.pxd

    diff --git a/sage/symbolic/getitem.pxd b/sage/symbolic/getitem.pxd
    a b  
    33
    44cdef class OperandsWrapper(SageObject):
    55    cdef Expression _expr
     6
     7cdef class IndexWrapper(SageObject):
     8    cdef Expression _expr
  • sage/symbolic/getitem.pyx

    diff --git a/sage/symbolic/getitem.pyx b/sage/symbolic/getitem.pyx
    a b  
    11###############################################################################
    22#   Sage: Open Source Mathematical Software
    3 #       Copyright (C) 2011 Burcin Erocal <burcin@erocal.org>
     3#       Copyright (C) 2011-2013 Burcin Erocal <burcin@erocal.org>
    44#  Distributed under the terms of the GNU General Public License (GPL),
    55#  version 2 or any later version.  The full text of the GPL is available at:
    66#                  http://www.gnu.org/licenses/
    77###############################################################################
    8 from sage.libs.ginac cimport GEx, GEx_construct_ex
     8from sage.libs.ginac cimport GEx, GEx_construct_ex, GIdx, is_a_idx, ex_to_idx, \
     9    is_a_numeric, py_object_from_numeric, ginac_idx, ginac_indexed_p
    910from sage.symbolic.expression cimport new_Expression_from_GEx
    1011
    1112cdef inline int normalize_index(object arg, int nops, object err_msg) except -1:
     
    5657    """
    5758    return normalize_index(arg, nops, "some error message")
    5859
     60cdef extract_object(object parent, GEx arg):
     61    """
     62    TEST::
     63
     64        sage: ex = x + 1
     65        sage: p = Permutation([2,1,3])
     66        sage: id = ex.ind[p]
     67        sage: id.op[1] # indirect doctest
     68        [2, 1, 3]
     69        sage: id.op[1] is p
     70        True
     71    """
     72    cdef GEx res
     73    if is_a_idx(arg):
     74        res = ex_to_idx(arg).get_value()
     75        if is_a_numeric(res):
     76            return py_object_from_numeric(res)
     77        return new_Expression_from_GEx(parent, res)
     78    return new_Expression_from_GEx(parent, arg)
     79
    5980cdef class OperandsWrapper(SageObject):
    6081    """
    6182    Operands wrapper for symbolic expressions.
     
    129150                    raise ValueError, "step value must be an integer"
    130151            else:
    131152                step = 1
    132             return [new_Expression_from_GEx(self._expr._parent,
     153            return [extract_object(self._expr._parent,
    133154                self._expr._gobj.op(ind)) for ind in xrange(bind, eind, step)]
    134155
    135156
     
    145166                    raise TypeError, "expressions containing only a numeric coefficient, constant or symbol have no operands"
    146167                ind = normalize_index(x, nops, ind_err_msg)
    147168                cur_ex = cur_ex.op(ind)
    148             return new_Expression_from_GEx(self._expr._parent, cur_ex)
     169            return extract_object(self._expr._parent, cur_ex)
    149170
    150171        ind = normalize_index(arg, self._expr._gobj.nops(), ind_err_msg)
    151         return new_Expression_from_GEx(self._expr._parent,
     172        return extract_object(self._expr._parent,
    152173                self._expr._gobj.op(ind))
    153174
    154175    def _repr_(self):
     
    165186        TESTS::
    166187
    167188            sage: latex((x^2).op)
    168             \text{Operands wrapper for expression }x^{2}
     189            \text{Operands of expression }x^{2}
    169190        """
    170         return r"\text{Operands wrapper for expression }%s"%(self._expr._latex_())
     191        return r"\text{Operands of expression }%s"%(self._expr._latex_())
    171192
    172193    def __reduce__(self):
    173194        """
     
    189210        Operands of x^2
    190211    """
    191212    return expr.op
     213
     214cdef object dummy_ind = None
     215
     216cdef object get_dummy_ind_symbol():
     217    global dummy_ind
     218    if dummy_ind is None:
     219        from sage.symbolic.ring import SR
     220        dummy_ind = SR.symbol()
     221    return dummy_ind
     222
     223cdef class IndexWrapper(SageObject):
     224    """
     225    """
     226    def __getitem__(self, arg):
     227        """
     228        argument must be a hashable python object or a slice with variable and
     229        dimension, for example, i:3
     230
     231
     232        TESTS::
     233
     234           sage: t = 1+x+x^2
     235           sage: t.ind[1:]
     236           [x, 1]
     237        """
     238        cdef Expression py_ind, py_dim
     239        cdef GIdx g_ind
     240        if isinstance(arg, tuple):
     241            raise NotImplementedError("don't know what to do with multiple indices yet!")
     242        elif isinstance(arg, slice):
     243            if arg.step:
     244                raise ValueError("only variable and dimension expected in slice")
     245            ind = arg.start
     246            if arg.stop is None: # handle t.ind[1:]
     247                raise ValueError("variable dimension must be specified when using slice syntax")
     248            try:
     249                py_dim = self._expr.coerce_in(arg.stop)
     250            except TypeError:
     251                py_dim = self._expr._parent._force_pyobject(arg.stop)
     252        else:
     253            ind = arg
     254            py_dim = get_dummy_ind_symbol()
     255
     256        try:
     257            py_ind = self._expr.coerce_in(ind)
     258        except TypeError:
     259            py_ind = self._expr._parent._force_pyobject(ind)
     260        g_ind = ginac_idx(py_ind._gobj, py_dim._gobj)
     261        from sage.symbolic.ring import SR
     262        return new_Expression_from_GEx(SR,
     263                ginac_indexed_p(self._expr._gobj, g_ind))
     264
     265    def _repr_(self):
     266        """
     267        TESTS::
     268
     269            sage: (x^2).ind
     270            Index wrapper for expression x^2
     271        """
     272        return "Index wrapper for expression %s"%(self._expr)
     273
     274    def _latex_(self):
     275        r"""
     276        TESTS::
     277
     278            sage: latex((x^2).ind)
     279            \text{Index wrapper for expression }x^{2}
     280        """
     281        return r"\text{Index wrapper for expression }%s"%(self._expr._latex_())
     282
     283    def __reduce__(self):
     284        """
     285        TESTS::
     286
     287            sage: (x^2).ind.__reduce__()
     288            (<built-in function restore_ind_wrapper>, (x^2,))
     289            sage: loads(dumps((x^2).ind))
     290            Index wrapper for expression x^2
     291        """
     292        return restore_op_wrapper, (self._expr,)
     293
     294def restore_ind_wrapper(expr):
     295    """
     296    TESTS::
     297
     298        sage: from sage.symbolic.getitem import restore_op_wrapper
     299        sage: restore_ind_wrapper(x^2)
     300        Index wrapper for expression x^2
     301    """
     302    return expr.ind
  • new file sage/symbolic/pynac.pxd

    diff --git a/sage/symbolic/pynac.pxd b/sage/symbolic/pynac.pxd
    new file mode 100644
    - +  
     1from sage.libs.ginac cimport GExVector
     2
     3cdef public object exvector_to_PyTuple(GExVector seq)