Ticket #14403: trac_14403_symbolic_charpoly_v2.patch

File trac_14403_symbolic_charpoly_v2.patch, 4.3 KB (added by gagern, 9 years ago)
  • sage/matrix/matrix_symbolic_dense.pyx

    # HG changeset patch
    # User Martin von Gagern <Martin.vGagern@gmx.net>
    # Date 1374571714 -7200
    #      Tue Jul 23 11:28:34 2013 +0200
    # Node ID 34ded95e582a49864154dc28c5589dfc4858fb3c
    # Parent  0f8fd922eaed351e39f913f1317d319dcceb4c01
    Trac 14403: fix charpoly for symbolic matrices
    
    diff --git a/sage/matrix/matrix_symbolic_dense.pyx b/sage/matrix/matrix_symbolic_dense.pyx
    a b  
    392392
    393393        return z._sage_()
    394394
    395     def charpoly(self, var='x', algorithm=None):
     395    def charpoly(self, var=None, algorithm=None):
    396396        """
    397397        Compute the characteristic polynomial of self, using maxima.
    398398       
     
    422422            sage: A._cache['charpoly']
    423423            x^2 - 3*x - 2
    424424
     425        Ensure the variable name of the polynomial does not conflict
     426        with variables used within the matrix (:trac:`14403`)::
     427
     428            sage: Matrix(SR, [[sqrt(x), x],[1,x]]).charpoly()
     429            x1^2 + (-x - sqrt(x))*x1 + x^(3/2) - x
     430            sage: _.list()
     431            [x^(3/2) - x, -x - sqrt(x), 1]
    425432        """
    426433        cache_key = 'charpoly'
    427434        cp = self.fetch(cache_key)
    428         if cp is not None:
    429             return cp.change_variable_name(var)
     435        if cp is None:
     436            from sage.symbolic.ring import SR
    430437
    431         from sage.symbolic.ring import SR
    432         # Maxima has the definition det(matrix-xI) instead of
    433         # det(xI-matrix), which is what Sage uses elsewhere.  We
    434         # correct for the discrepancy.
    435         cp = self._maxima_(maxima).charpoly(var)._sage_()
    436         cp = cp.expand().polynomial(None, ring=SR[var])
    437         if self.nrows() % 2 == 1:
    438             cp = -cp
     438            # We must not use a variable name already present in the matrix
     439            variables = [repr(v) for v in self.variables()]
     440            varname = 'x'
     441            varcounter = 0
     442            while varname in variables:
     443                varcounter += 1
     444                varname = 'x' + str(varcounter)
     445            varsymbol = SR(varname)
    439446
    440         self.cache(cache_key, cp)
     447            cp = self._maxima_(maxima).charpoly(varname)._sage_().expand()
     448            cp = [cp.coefficient(varsymbol, i) for i in range(self.nrows() + 1)]
     449            cp = SR[varname](cp)
     450
     451            # Maxima has the definition det(matrix-xI) instead of
     452            # det(xI-matrix), which is what Sage uses elsewhere.  We
     453            # correct for the discrepancy.
     454            if self.nrows() % 2 == 1:
     455                cp = -cp
     456
     457            self.cache(cache_key, cp)
     458        if var is not None:
     459            cp = cp.change_variable_name(var)
    441460        return cp
    442461
    443462    def fcp(self, var='x'):
  • sage/symbolic/expression_conversions.py

    diff --git a/sage/symbolic/expression_conversions.py b/sage/symbolic/expression_conversions.py
    a b  
    898898
    899899        if ring is not None:
    900900            base_ring = ring.base_ring()
    901             G = ring.variable_names_recursive()
     901            self.varnames = ring.variable_names_recursive()
    902902            for v in ex.variables():
    903                 if repr(v) not in G and v not in base_ring:
     903                if repr(v) not in self.varnames and v not in base_ring:
    904904                    raise TypeError, "%s is not a variable of %s" %(v, ring)
    905905            self.ring = ring
    906906            self.base_ring = base_ring
     
    911911                vars = ['x']
    912912            from sage.rings.all import PolynomialRing
    913913            self.ring = PolynomialRing(self.base_ring, names=vars)
     914            self.varnames = self.ring.variable_names()
    914915        else:
    915916            raise TypeError, "either a ring or base ring must be specified"
    916917
     
    9991000            sage: p = PolynomialConverter(x+y, base_ring=RR)
    10001001            sage: p.arithmetic(x*y+y^2, operator.add)
    10011002            x*y + y^2
     1003
     1004            sage: p = PolynomialConverter(y^(3/2), ring=SR['x'])
     1005            sage: p.arithmetic(y^(3/2), operator.pow)
     1006            y^(3/2)
     1007            sage: _.parent()
     1008            Symbolic Ring
    10021009        """
    1003         if len(ex.variables()) == 0:
     1010        if not any(repr(v) in self.varnames for v in ex.variables()):
    10041011            return self.base_ring(ex)
    10051012        elif operator == _operator.pow:
    10061013            from sage.rings.all import Integer