Ticket #9706: trac_9706_new_base_classes.patch

File trac_9706_new_base_classes.patch, 6.9 KB (added by maldun, 7 years ago)

proposed new structure

  • sage/functions/orthogonal_polys.py

    # HG changeset patch
    # User Stefan Reiterer <domors@gmx.net>
    # Date 1386626456 -3600
    # Node ID 2f049badb3e1767ffa613d6396a7191ae3aa7989
    # Parent  0bb6eadb259a4824c5f8b26bf8fb7bd0ff2094db
    trac 9706: Propose new class structure
    
    diff --git a/sage/functions/orthogonal_polys.py b/sage/functions/orthogonal_polys.py
    a b  
    452452            (n, x)
    453453            sage: chebyshev_T(5,x)
    454454            16*x^5 - 20*x^3 + 5*x
    455             sage: chebyshev_T(64, x)
    456             2*(2*(2*(2*(2*(2*x^2 - 1)^2 - 1)^2 - 1)^2 - 1)^2 - 1)^2 - 1
    457             sage: chebyshev_T(n,-1)
    458             (-1)^n
    459             sage: chebyshev_T(-7,x)
    460             64*x^7 - 112*x^5 + 56*x^3 - 7*x
    461             sage: chebyshev_T(3/2,x)
    462             chebyshev_T(3/2, x)
    463             sage: R.<t> = QQ[]
    464             sage: chebyshev_T(2,t)
    465             2*t^2 - 1
    466             sage: chebyshev_U(2,t)
    467             4*t^2 - 1
    468             sage: parent(chebyshev_T(4, RIF(5)))
    469             Real Interval Field with 53 bits of precision
    470             sage: RR2 = RealField(5)
    471             sage: chebyshev_T(100000,RR2(2))
    472             8.9e57180
    473             sage: chebyshev_T(5,Qp(3)(2))
    474             2 + 3^2 + 3^3 + 3^4 + 3^5 + O(3^20)
    475             sage: chebyshev_T(100001/2, 2)
    476             doctest:...: RuntimeWarning: mpmath failed, keeping expression unevaluated
    477             chebyshev_T(100001/2, 2)
    478             sage: chebyshev_U._eval_(1.5, Mod(8,9)) is None
    479             True
    480455        """
    481         args_is_symbolic = any(is_Expression(x) for x in args)
     456        return None
    482457
    483         # n is an integer => evaluate algebraically (as polynomial)
    484         if n in ZZ:
    485             n = ZZ(n)
    486             # Expanded symbolic expression only for small values of n
    487             if args_is_symbolic and n.abs() < 32:
    488                 return self.eval_formula(n, *args)
    489             else:
    490                 return self.eval_algebraic(n, *args)
     458    def __call__(self, n, *args, **kwds):
     459        """
     460        This overides the call method from SageObject to avoid problems with coercions,
     461        since the _eval_ method is able to handle more data types than symbolic functions
     462        would normally allow.
     463        Thus we have the distinction between algebraic objects (if n is an integer),
     464        and else as symbolic function.
    491465
    492         if args_is_symbolic or is_Expression(n):
    493             # Check for known identities
    494             try:
    495                 return self._eval_special_values_(n, *args)
    496             except ValueError:
    497                 # Don't evaluate => keep symbolic
    498                 return None
     466        EXAMPLES::
    499467
    500         # n is not an integer and neither n nor x is symbolic.
    501         # We assume n and x are real/complex and evaluate numerically
    502         try:
    503             import sage.libs.mpmath.all as mpmath
    504             return self._evalf_(n, *args)
    505         except mpmath.NoConvergence:
    506             warnings.warn("mpmath failed, keeping expression unevaluated",
    507                           RuntimeWarning)
    508             return None
    509         except StandardError:
    510             # Numerical evaluation failed => keep symbolic
    511             return None
     468            sage: K.<a> = NumberField(x^3-x-1)
     469            sage: chebyshev_T(5, a)
     470            16*a^2 + a - 4
     471        """
     472        return super(OrthogonalPolynomial,self).__call__(n, *args, **kwds)
     473
     474   
     475
     476class ChebyshevPolynomial(OrthogonalPolynomial):
     477    """
     478    Super class for Chebyshev polynomials of the first and second kind.
     479
     480    EXAMPLES::
     481
     482        sage: chebyshev_T(3,x)
     483        4*x^3 - 3*x
     484
     485    """
    512486
    513487    def __call__(self, n, *args, **kwds):
    514488        """
     
    543517            except StandardError:
    544518                pass
    545519
    546         return super(OrthogonalPolynomial,self).__call__(n, *args, **kwds)
     520        return super(ChebyshevPolynomial,self).__call__(n, *args, **kwds)
     521   
    547522
    548 class Func_chebyshev_T(OrthogonalPolynomial):
     523    def _eval_(self, n, x):
     524        """
     525        The _eval_ method decides which evaluation suits best
     526        for the given input, and returns a proper value.
     527
     528        EXAMPLES::
     529
     530            sage: var('n,x')
     531            (n, x)
     532            sage: chebyshev_T(5,x)
     533            16*x^5 - 20*x^3 + 5*x
     534            sage: chebyshev_T(64, x)
     535            2*(2*(2*(2*(2*(2*x^2 - 1)^2 - 1)^2 - 1)^2 - 1)^2 - 1)^2 - 1
     536            sage: chebyshev_T(n,-1)
     537            (-1)^n
     538            sage: chebyshev_T(-7,x)
     539            64*x^7 - 112*x^5 + 56*x^3 - 7*x
     540            sage: chebyshev_T(3/2,x)
     541            chebyshev_T(3/2, x)
     542            sage: R.<t> = QQ[]
     543            sage: chebyshev_T(2,t)
     544            2*t^2 - 1
     545            sage: chebyshev_U(2,t)
     546            4*t^2 - 1
     547            sage: parent(chebyshev_T(4, RIF(5)))
     548            Real Interval Field with 53 bits of precision
     549            sage: RR2 = RealField(5)
     550            sage: chebyshev_T(100000,RR2(2))
     551            8.9e57180
     552            sage: chebyshev_T(5,Qp(3)(2))
     553            2 + 3^2 + 3^3 + 3^4 + 3^5 + O(3^20)
     554            sage: chebyshev_T(100001/2, 2)
     555            doctest:...: RuntimeWarning: mpmath failed, keeping expression unevaluated
     556            chebyshev_T(100001/2, 2)
     557            sage: chebyshev_U._eval_(1.5, Mod(8,9)) is None
     558            True
     559        """
     560        # n is an integer => evaluate algebraically (as polynomial)
     561        if n in ZZ:
     562            n = ZZ(n)
     563            # Expanded symbolic expression only for small values of n
     564            if is_Expression(x) and n.abs() < 32:
     565                return self.eval_formula(n, x)
     566            else:
     567                return self.eval_algebraic(n, x)
     568
     569        if is_Expression(x) or is_Expression(n):
     570            # Check for known identities
     571            try:
     572                return self._eval_special_values_(n, x)
     573            except ValueError:
     574                # Don't evaluate => keep symbolic
     575                return None
     576
     577        # n is not an integer and neither n nor x is symbolic.
     578        # We assume n and x are real/complex and evaluate numerically
     579        try:
     580            import sage.libs.mpmath.all as mpmath
     581            return self._evalf_(n, x)
     582        except mpmath.NoConvergence:
     583            warnings.warn("mpmath failed, keeping expression unevaluated",
     584                          RuntimeWarning)
     585            return None
     586        except StandardError:
     587            # Numerical evaluation failed => keep symbolic
     588            return None
     589
     590   
     591class Func_chebyshev_T(ChebyshevPolynomial):
    549592    """
    550593    Chebyshev polynomials of the first kind.
    551594
     
    555598
    556599    EXAMPLES::
    557600
    558        sage: chebyshev_T(3,x)
    559        4*x^3 - 3*x
    560601       sage: chebyshev_T(5,x)
    561602       16*x^5 - 20*x^3 + 5*x
    562603       sage: var('k')
     
    852893
    853894chebyshev_T = Func_chebyshev_T()
    854895
    855 class Func_chebyshev_U(OrthogonalPolynomial):
     896class Func_chebyshev_U(ChebyshevPolynomial):
    856897    """
    857898    Class for the Chebyshev polynomial of the second kind.
    858899