Ticket #12075: trac_12298-v2.patch

File trac_12298-v2.patch, 13.5 KB (added by gbe, 9 years ago)

Apply instead of trac_12298.patch

  • module_list.py

    # HG changeset patch
    # User Geoffrey Ehrman <gehrman@gmail.com>
    # Date 1326400602 28800
    # Node ID f1653677327b707dfe1387b7247b4fa53150a8ab
    # Parent  92c93226b64f933e0af00bbcbd1a8a79c444f43f
    Trac ticket 12075: (Create callable matrices in function notation)
    
    diff --git a/module_list.py b/module_list.py
    a b  
    988988    Extension('sage.matrix.matrix_symbolic_dense',
    989989              sources = ['sage/matrix/matrix_symbolic_dense.pyx']),
    990990
     991    Extension('sage.matrix.matrix_callable_symbolic_dense',
     992              sources = ['sage/matrix/matrix_callable_symbolic_dense.pyx']),
     993
    991994    Extension('sage.matrix.matrix_window',
    992995              sources = ['sage/matrix/matrix_window.pyx']),
    993996
  • sage/calculus/all.py

    diff --git a/sage/calculus/all.py b/sage/calculus/all.py
    a b  
    2121lazy_import("sage.calculus.interpolators",["polygon_spline","complex_cubic_spline"])
    2222
    2323from sage.modules.all import vector
     24from sage.matrix.all import matrix
    2425
    2526def symbolic_expression(x):
    2627    """
    27     Create a symbolic expression or vector of symbolic expressions from x.
     28    From x, create one of the following:
     29
     30        -a symbolic expression,
     31
     32        -a vector of symbolic expressions,
     33
     34        -a matrix of symbolic expressions.
    2835
    2936    INPUT:
    3037
     
    6370        sage: symbolic_expression(E) in SR
    6471        True         
    6572       
    66     If x is a list or tuple, create a vector of symbolic expressions::
     73    If x is a list or tuple one level deep, create a vector of symbolic expressions::
    6774   
    6875        sage: v=symbolic_expression([x,1]); v
    6976        (x, 1)
     
    8390        (x*y + y^2 + y == x^3 + x^2 - 10*x - 10, x*y + y^2 + y == x^3 + x^2 - 10*x - 10)
    8491        sage: v.base_ring()
    8592        Symbolic Ring
     93
     94    If x and x[0] are lists or tuples, create a matrix of symbolic expressions::
     95
     96        sage: m=symbolic_expression([[x,1],[0,x]]); m
     97        [x 1]
     98        [0 x]
     99        sage: m.base_ring()
     100        Symbolic Ring
     101        sage: m=symbolic_expression(((x,1),(0,x))); m
     102        [x 1]
     103        [0 x]
     104        sage: m=symbolic_expression(([x,1],(0,x))); m #mixing tuples and lists is fine
     105        [x 1]
     106        [0 x]
     107        sage: m.base_ring()               
     108        Symbolic Ring
     109        sage: m=symbolic_expression(((3,0),(1,1))); m
     110        [3 0]
     111        [1 1]
     112        sage: v.base_ring()               
     113        Symbolic Ring
     114        sage: E = EllipticCurve('15a'); E
     115        Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 - 10*x - 10 over Rational Field
     116        sage: m=symbolic_expression([[E,E],[E,E]]); m
     117        [x*y + y^2 + y == x^3 + x^2 - 10*x - 10 x*y + y^2 + y == x^3 + x^2 - 10*x - 10]
     118        [x*y + y^2 + y == x^3 + x^2 - 10*x - 10 x*y + y^2 + y == x^3 + x^2 - 10*x - 10]
     119        sage: m.base_ring()
     120        Symbolic Ring
    86121    """
    87122    from sage.symbolic.expression import Expression
    88123    from sage.symbolic.ring import SR
     
    90125        return x
    91126    elif hasattr(x, '_symbolic_'):
    92127        return x._symbolic_(SR)
    93     elif isinstance(x, (tuple,list)):
    94         return vector(SR,x)
     128    elif isinstance(x, (tuple, list)):
     129        if isinstance(x[0], (tuple, list)):
     130            return matrix(SR, x)
     131        else:
     132            return vector(SR, x)
    95133    else:
    96134        return SR(x)
    97135
  • sage/matrix/matrix2.pyx

    diff --git a/sage/matrix/matrix2.pyx b/sage/matrix/matrix2.pyx
    a b  
    1161811618                companions.append(sage.matrix.constructor.companion_matrix(poly, format=format))
    1161911619            return sage.matrix.constructor.block_diagonal_matrix(companions, subdivide=subdivide)
    1162011620
     11621    def function(self, *args):
     11622        """
     11623        Returns a matrix over a calllable symbolic expression ring. This is
     11624        needed to create matrices with callable entries with function syntax.
     11625
     11626        EXAMPLES::
     11627
     11628            sage: x, y, t = var('x y t')
     11629            sage: m = matrix([[x, x*y - t^2*y*x],[0,y]])
     11630            sage: f = m.function([x, y, t]); f
     11631            [             (x, y, t) |--> x (x, y, t) |--> -t^2*x*y + x*y]
     11632            [             (x, y, t) |--> 0              (x, y, t) |--> y]
     11633            sage: f.base_ring()
     11634            Callable function ring with arguments (x, y, t)
     11635            sage: f(0, 0, 1)
     11636                           [0 0]
     11637            (x, y, t) |--> [0 0]
     11638            sage: f(1, 1, 0)
     11639                           [1 1]
     11640            (x, y, t) |--> [0 1]
     11641            sage: f(1, 1, 1)
     11642                           [1 0]
     11643            (x, y, t) |--> [0 1]
     11644            sage: f(1, 3)
     11645                           [         1 -3*t^2 + 3]
     11646            (x, y, t) |--> [         0          3]
     11647            sage: f(t=0)
     11648                           [  x x*y]
     11649            (x, y, t) |--> [  0   y]
     11650            sage: f(y=2,t=1/2,x=4)
     11651                           [4 6]
     11652            (x, y, t) |--> [0 2]
     11653        """
     11654        from sage.symbolic.callable import CallableSymbolicExpressionRing
     11655        return matrix_space.MatrixSpace(CallableSymbolicExpressionRing(args), self.nrows(), self.ncols())(self.list())
     11656
    1162111657    # A limited number of access-only properties are provided for matrices
    1162211658    property T:
    1162311659        r"""
  • new file sage/matrix/matrix_callable_symbolic_dense.pxd

    diff --git a/sage/matrix/matrix_callable_symbolic_dense.pxd b/sage/matrix/matrix_callable_symbolic_dense.pxd
    new file mode 100644
    - +  
     1cimport matrix_generic_dense
     2
     3cdef class Matrix_callable_symbolic_dense(matrix_symbolic_dense.Matrix_symbolic_dense):
     4    pass
  • new file sage/matrix/matrix_callable_symbolic_dense.pyx

    diff --git a/sage/matrix/matrix_callable_symbolic_dense.pyx b/sage/matrix/matrix_callable_symbolic_dense.pyx
    new file mode 100644
    - +  
     1"""
     2Matrices over callable symbolic rings
     3
     4Though we inherit from Matrix_symbolic dense, even the methods defined in this file are based strongly on matrix_symbolic_dense.
     5
     6AUTHOR:
     7    -- Geoffrey Ehrman (2012)
     8
     9EXAMPLES::
     10    sage: l(t) = ((cos(t), 0), (0, sin(t))); l
     11           [cos(t)      0]
     12    t |--> [     0 sin(t)]
     13    sage: l*l #matrix multiplication works
     14    sage: m(theta, z) = [[cos(theta), -sin(theta), 0],[sin(theta), cos(theta), 0],[0,0,z]]
     15    sage: m.parent()
     16    Full MatrixSpace of 3 by 3 dense matrices over Callable function ring with arguments (theta, z)
     17    sage: m
     18                    [ cos(theta) -sin(theta)           0]
     19    (theta, z) |--> [ sin(theta)  cos(theta)           0]
     20                    [          0           0           z]
     21    sage: type(m)
     22    <type 'sage.matrix.matrix_callable_symbolic_dense.Matrix_callable_symbolic_dense'>
     23    sage: m(0)
     24                    [1 0 0]
     25    (theta, z) |--> [0 1 0]
     26                    [0 0 z]
     27    sage: m(z = 4)
     28                    [ cos(theta) -sin(theta)           0]
     29    (theta, z) |--> [ sin(theta)  cos(theta)           0]
     30                    [          0           0           4]
     31    sage: m(pi/2, 1)
     32    [ 0 -1  0]
     33    [ 1  0  0]
     34    [ 0  0  1]
     35    sage: m.trace()
     36    (theta, z) |--> z + 2*cos(theta)
     37    sage: m.kernel()
     38    Vector space of degree 3 and dimension 0 over Callable function ring with arguments (theta, z)
     39    Basis matrix:
     40    []
     41    sage: m.image()
     42    Vector space of degree 3 and dimension 3 over Callable function ring with arguments (theta, z)
     43    Basis matrix:
     44    [(theta, z) |--> 1 (theta, z) |--> 0 (theta, z) |--> 0]
     45    [(theta, z) |--> 0 (theta, z) |--> 1 (theta, z) |--> 0]
     46    [(theta, z) |--> 0 (theta, z) |--> 0 (theta, z) |--> 1]
     47
     48TESTS::
     49
     50    sage: m(u,v,w) = ((2*u+v,u-w),(u*v*w,w^2+u))
     51    sage: loads(dumps(m)) == m
     52    True
     53
     54
     55"""
     56
     57#*****************************************************************************
     58#       Copyright (C) 2012 Geoffrey Ehrman <gehrman@gmail.com>
     59#
     60#  Distributed under the terms of the GNU General Public License (GPL)
     61#
     62#    This code is distributed in the hope that it will be useful,
     63#    but WITHOUT ANY WARRANTY; without even the implied warranty of
     64#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     65#    General Public License for more details.
     66#
     67#  The full text of the GPL is available at:
     68#
     69#                  http://www.gnu.org/licenses/
     70#*****************************************************************************
     71
     72from sage.symbolic.ring import SR
     73# use a different name to avoid collision with the matrix class; needed in call
     74from sage.matrix.constructor import matrix as make_matrix
     75
     76cimport matrix_symbolic_dense
     77cimport matrix
     78
     79cdef class Matrix_callable_symbolic_dense(matrix_symbolic_dense.Matrix_symbolic_dense):
     80    """
     81    Matrices over callable symbolic rings.
     82   
     83    Both the methods  _repr_() and _latex_() are
     84    """
     85    def _new_c(self):
     86        """
     87        Called when creating a new matrix.
     88
     89        EXAMPLES::
     90       
     91            #sage: matrix(SR,0)   # this implicitly calls _new_c
     92            #[]
     93        """
     94        cdef Matrix_callable_symbolic_dense M \
     95                = Matrix_callable_symbolic_dense.__new__(Matrix_callable_symbolic_dense, 0, 0, 0)
     96        matrix.Matrix.__init__(M, self._parent)
     97        return M
     98
     99
     100
     101    def __call__(self, *args, **kwargs):
     102        """
     103        Calling a matrix returns the result of calling each entry.
     104       
     105        EXAMPLES::
     106       
     107        """
     108        return make_matrix([
     109                           [e(*args, **kwargs) for e in row]
     110                           for row in self])
     111
     112
     113    def __repr__(self):
     114        """
     115        Return the string representation of the matrix.
     116
     117        EXAMPLES::
     118            sage: column(x, y, z) = [[x],[y],[z]]; column
     119            sage: row(x, y, z) = [[x, y, z]]; row
     120            sage: m(theta, z) = [[cos(theta), -sin(theta), 0],[sin(theta), cos(theta), 0],[0,0,z]]; m
     121            sage: l(t) = ((cos(t), 0), (0, sin(t))); l
     122        """
     123        from sage.functions.other import floor
     124       
     125        ring = self.base_ring()
     126        args = ring.arguments()
     127        if len(args) == 1:
     128            prepend = "%s |--> " % args[0]
     129        else:
     130            args = ", ".join(map(str, args))
     131            prepend = "(%s) |--> " % args
     132        enough_space = " "*len(prepend)       
     133
     134        repr_x = self.change_ring(SR).__repr__()
     135        numlines = repr_x.count("\n") + 1
     136
     137        if numlines == 1:
     138            return "".join([prepend, repr_x])
     139        elif numlines == 2:
     140            newline = repr_x.index("\n") + 1
     141            return "".join([enough_space, repr_x[:newline], prepend, repr_x[newline:]])
     142        else:
     143            repr_x = repr_x.split("\n")
     144            middle = floor(len(repr_x)/2)
     145            output = []
     146            for s in repr_x[:middle]:
     147                output.append("".join([" "*len(prepend), s, "\n"]))
     148            output.append("".join([prepend, repr_x[middle], "\n"]))
     149            for s in repr_x[middle + 1:-1]:
     150                output.append("".join([" "*len(prepend), s, "\n"]))
     151            output.append("".join([" "*len(prepend), repr_x[-1]]))
     152            return "".join(output)
     153
     154
     155
     156#            str = "%s |--> %s" % (args[0], repr_x)
     157#            lin
     158#        else:
     159#            args = ", ".join(map(str, args))
     160#            return "(%s) |---------------------> %s (long maps to!!!!!!!!!!)" % (args, repr_x)
     161
     162
     163    def _latex_(self):
     164        """
     165        Returns the latex representation of the vector
     166       
     167        TODO:
     168            It may be best to rewrite this (at least partially) when mathjax is
     169            integrated into the notebook in 5.0. Note the comment regarding
     170            working around a JsMath bug.
     171
     172        EXAMPLES::
     173            #sage: m(theta, z) = [[cos(theta), -sin(theta), 0],[sin(theta), cos(theta), 0],[0,0,z]]
     174            #sage: latex(m)
     175            #sage: l(t) = ((cos(t), 0), (0, sin(t)))
     176            #sage: latex(l)
     177        """
     178        from sage.misc.latex import latex
     179        ring=self.base_ring()
     180        args = ring.arguments()
     181        args = [latex(arg) for arg in args]
     182        latex_x = self.change_ring(SR)._latex_()
     183        if len(args) == 1:
     184            return r"%s \ {\mapsto}\ %s" % (args[0], latex_x)
     185        else:
     186            vars = ", ".join(args)
     187            # the weird TeX is to workaround an apparent JsMath bug
     188            return r"\left( %s \right) \ {\mapsto} \ %s" % (vars, latex_x)
     189
  • sage/matrix/matrix_space.py

    diff --git a/sage/matrix/matrix_space.py b/sage/matrix/matrix_space.py
    a b  
    416416                return self.__matrix_class(self, None, coerce=coerce, copy=copy)
    417417
    418418        if isinstance(entries, (list, tuple)) and len(entries) > 0 and \
    419            sage.modules.free_module_element.is_FreeModuleElement(entries[0]):
     419            sage.modules.free_module_element.is_FreeModuleElement(entries[0]):
    420420            #Try to determine whether or not the entries should
    421421            #be rows or columns
    422422            if rows is None:
     
    921921                return matrix_mod2e_dense.Matrix_mod2e_dense
    922922            elif sage.rings.polynomial.multi_polynomial_ring_generic.is_MPolynomialRing(R) and R.base_ring().is_field():
    923923                return matrix_mpolynomial_dense.Matrix_mpolynomial_dense
     924            elif sage.symbolic.callable.is_CallableSymbolicExpressionRing(R):
     925                import matrix_callable_symbolic_dense
     926                return matrix_callable_symbolic_dense.Matrix_callable_symbolic_dense
    924927            #elif isinstance(R, sage.rings.padics.padic_ring_capped_relative.pAdicRingCappedRelative):
    925928            #    return padics.matrix_padic_capped_relative_dense
    926929            # the default