Ticket #1722: 1722.patch

File 1722.patch, 9.3 KB (added by Mike Hansen, 15 years ago)
  • sage/matrix/matrix_symbolic_dense.pxd

    # HG changeset patch
    # User Mike Hansen <mhansen@gmail.com>
    # Date 1204143022 28800
    # Node ID f1e4f2ffd21362988cf96a43eccf9c2e7fe985a2
    # Parent  f71e603a6089a157d683711d48d46298e39f5d71
    Fixed #1722
    
    diff -r f71e603a6089 -r f1e4f2ffd213 sage/matrix/matrix_symbolic_dense.pxd
    a b cdef class Matrix_symbolic_dense(matrix_ 
    33cdef class Matrix_symbolic_dense(matrix_dense.Matrix_dense):
    44    cdef object _maxima
    55    cdef set_from_list(self, entries)
     6    cdef object __variables
     7    cdef object __number_of_args
     8
     9    cdef public object _simp
  • sage/matrix/matrix_symbolic_dense.pyx

    diff -r f71e603a6089 -r f1e4f2ffd213 sage/matrix/matrix_symbolic_dense.pyx
    a b cdef maxima 
    1515cdef maxima
    1616from sage.calculus.calculus import maxima
    1717
    18 from sage.calculus.calculus import symbolic_expression_from_maxima_string, SymbolicVariable
     18from sage.calculus.calculus import symbolic_expression_from_maxima_string, SymbolicVariable, var_cmp
    1919
    2020cdef class Matrix_symbolic_dense(matrix_dense.Matrix_dense):
    2121    r"""
    cdef class Matrix_symbolic_dense(matrix_ 
    4848            [0 t]
    4949        """
    5050        matrix.Matrix.__init__(self, parent)
    51 
     51        self.__variables = None
     52        self._simp = None
     53       
    5254        cdef Py_ssize_t i, n
    5355       
    5456        if entries is None:
    cdef class Matrix_symbolic_dense(matrix_ 
    534536    #############################################
    535537    # Simplification commands
    536538    #############################################
     539    def is_simplified(self):
     540        """
     541        Return True if self is the result of running simplify() on a symbolic
     542        matrix.  This has the semantics of 'has_been_simplified'.
     543       
     544        EXAMPLES:
     545            sage: var('x,y,z')
     546            (x, y, z)
     547            sage: m = matrix([[z, (x+y)/(x+y)], [x^2, y^2+2]]); m
     548            [      z       1]
     549            [    x^2 y^2 + 2]
     550            sage: m.is_simplified()
     551            False
     552            sage: ms = m.simplify(); ms
     553            [      z       1]
     554            [    x^2 y^2 + 2]
     555
     556            sage: m.is_simplified()
     557            False
     558            sage: ms.is_simplified()
     559            True
     560        """
     561       
     562        return self._simp is self
     563   
     564    def simplify(self):
     565        """
     566        Simplifies self.
     567
     568        EXAMPLES:
     569            sage: var('x,y,z')
     570            (x, y, z)
     571            sage: m = matrix([[z, (x+y)/(x+y)], [x^2, y^2+2]]); m
     572            [      z       1]
     573            [    x^2 y^2 + 2]
     574            sage: m.simplify()
     575            [      z       1]
     576            [    x^2 y^2 + 2]           
     577        """
     578        if self._simp is not None:
     579            return self._simp
     580
     581        S = self.parent()([x.simplify() for x in self.list()])
     582        S._simp = S
     583        self._simp = S
     584        return S
     585
    537586
    538587    def simplify_trig(self):
    539588        """
    cdef class Matrix_symbolic_dense(matrix_ 
    601650        return M
    602651
    603652
     653
     654    def variables(self, vars=tuple([])):
     655        """
     656        Returns the variables of self.
     657
     658        EXAMPLES:
     659            sage: var('a,b,c,x,y')
     660            (a, b, c, x, y)
     661            sage: m = matrix([[x, x+2], [x^2, x^2+2]]); m
     662            [      x   x + 2]
     663            [    x^2 x^2 + 2]
     664            sage: m.variables()
     665            (x,)
     666            sage: m = matrix([[a, b+c], [x^2, y^2+2]]); m
     667            [      a   c + b]
     668            [    x^2 y^2 + 2]
     669            sage: m.variables()
     670            (a, b, c, x, y)
     671        """
     672        if self.__variables is not None:
     673            return self.__variables
     674
     675        vars = list(set(sum([list(op.variables()) for op in self.list()], list(vars))))
     676       
     677        vars.sort(var_cmp)
     678        vars = tuple(vars)
     679        self.__variables = vars
     680        return vars
     681
     682    def number_of_arguments(self):
     683        """
     684        Returns the number of arguments that self can take.
     685
     686        EXAMPLES:
     687            sage: var('a,b,c,x,y')
     688            (a, b, c, x, y)
     689            sage: m = matrix([[a, (x+y)/(x+y)], [x^2, y^2+2]]); m
     690            [      a       1]
     691            [    x^2 y^2 + 2]
     692            sage: m.number_of_arguments()
     693            3
     694
     695            sage: M = MatrixSpace(SR,2,2)
     696            sage: m = M(sin+1)
     697            sage: m.variables()
     698            ()
     699            sage: m.number_of_arguments()
     700            1
     701
     702        """
     703        if self.__number_of_args is not None:
     704            return self.__number_of_args
     705
     706        variables = self.variables()
     707        if not self.is_simplified():
     708            n = self.simplify().number_of_arguments()
     709        else:
     710            # We need to do this maximum to correctly handle the case where
     711            # self is something like (sin+1)
     712            n = max( max([i.number_of_arguments() for i in self.list()]+[0]), len(variables) )
     713        self.__number_of_args = n
     714        return n
     715
     716    def arguments(self):
     717        """
     718        Returns a tuple of the arguments that self can take.
     719
     720        EXAMPLES:
     721            sage: var('x,y,z')
     722            (x, y, z)
     723            sage: M = MatrixSpace(SR,2,2)
     724            sage: M(x).arguments()
     725            (x,)
     726            sage: M(x+sin).arguments()
     727            (x,)
     728
     729            sage: M(sin+1).arguments()
     730            ()
     731            sage: M(sin+1).number_of_arguments()
     732            1
     733        """
     734        return self.variables()
     735
     736    def __call__(self, *args, **kwargs):
     737        """
     738        EXAMPLES:
     739            sage: var('x,y,z')
     740            (x, y, z)
     741            sage: M = MatrixSpace(SR,2,2)
     742            sage: h = M(sin+cos)
     743            sage: h
     744            [sin + cos         0]
     745            [        0 sin + cos]
     746            sage: h(1)
     747            [sin(1) + cos(1)               0]
     748            [              0 sin(1) + cos(1)]
     749            sage: h(x)
     750            [sin(x) + cos(x)               0]
     751            [              0 sin(x) + cos(x)]
     752            sage: h = 3*M(sin)
     753            sage: h(1)
     754            [3*sin(1)        0]
     755            [       0 3*sin(1)]
     756            sage: h(x)
     757            [3*sin(x)        0]
     758            [       0 3*sin(x)]
     759
     760            sage: M(sin+1)(1)
     761            [sin(1) + 1          0]
     762            [         0 sin(1) + 1]
     763            sage: M(x+sin)(5)
     764            [sin(5) + 5          0]
     765            [         0 sin(5) + 5]
     766
     767            sage: f = M([0,x,y,z]); f
     768            [0 x]
     769            [y z]
     770            sage: f.arguments()
     771            (x, y, z)
     772            sage: f()
     773            [0 x]
     774            [y z]
     775            sage: f(1)
     776            [0 1]
     777            [y z]
     778            sage: f(1,2)
     779            [0 1]
     780            [2 z]
     781            sage: f(1,2,3)
     782            [0 1]
     783            [2 3]
     784            sage: f(x=1)
     785            [0 1]
     786            [y z]
     787            sage: f(x=1,y=2)
     788            [0 1]
     789            [2 z]
     790            sage: f(x=1,y=2,z=3)
     791            [0 1]
     792            [2 3]
     793            sage: f({x:1,y:2,z:3})
     794            [0 1]
     795            [2 3]
     796
     797            sage: f(1, x=2)
     798            Traceback (most recent call last):
     799            ...
     800            ValueError: args and kwargs cannot both be specified
     801            sage: f(1,2,3,4)
     802            Traceback (most recent call last):
     803            ...
     804            ValueError: the number of arguments must be less than or equal to 3
     805        """
     806        if kwargs and args:
     807            raise ValueError, "args and kwargs cannot both be specified"
     808
     809        if len(args) == 1 and isinstance(args[0], dict):
     810            kwargs = dict([(repr(x[0]), x[1]) for x in args[0].iteritems()])
     811
     812        if kwargs:
     813            #Handle the case where kwargs are specified
     814            new_entries = []
     815            for entry in self.list():
     816                try:
     817                    new_entries.append( entry(**kwargs) )
     818                except ValueError:
     819                    new_entries.append(entry)
     820        else:
     821            #Handle the case where args are specified
     822
     823            #Get all the variables
     824            variables = list( self.arguments() )
     825
     826            if len(args) > self.number_of_arguments():
     827                raise ValueError, "the number of arguments must be less than or equal to %s"%self.number_of_arguments()
     828           
     829            new_entries = []
     830            for entry in self.list():
     831                try:
     832                    entry_vars = entry.variables()
     833                    if len(entry_vars) == 0:
     834                        if len(args) != 0:
     835                            new_entries.append( entry(args[0]) )
     836                        else:
     837                            new_entries.append( entry )
     838                        continue
     839                    else: 
     840                        indices = [i for i in map(variables.index, entry_vars) if i < len(args)]
     841                        if len(indices) == 0:
     842                            new_entries.append( entry )
     843                        else:
     844                            new_entries.append( entry(*[args[i] for i in indices]) )
     845                except ValueError:
     846                    new_entries.append( entry )
     847
     848        return self.parent(new_entries)
    604849    def fcp(self, var='x'):
    605850        """
    606851        Return the factorization of the characteristic polynomial of self.