def _init(): """ Internal function which checks if Maxima has loaded the "orthopoly" package. All functions using this in this file should call this function first. TEST: The global starts ``False``:: sage: sage.functions.orthogonal_polys._done False Then after using one of these functions, it changes:: sage: from sage.functions.orthogonal_polys import chebyshev_T sage: chebyshev_T(2,x) 2*(x - 1)^2 + 4*x - 3 sage: sage.functions.orthogonal_polys._done True Note that because here we use a Pynac variable ``x``, the representation of the function is different from its actual doctest, where a polynomial indeterminate ``x`` is used. """ global _done if _done: return maxima.eval('load("orthopoly");') # TODO -- make it possible to use the intervals returned # instead of just discarding this info! maxima.eval('orthopoly_returns_intervals:false;') _done = True
def _init(): """ Internal function which checks if Maxima has loaded the "orthopoly" package. All functions using this in this file should call this function first. TEST: The global starts ``False``:: sage: sage.functions.orthogonal_polys._done False Then after using one of these functions, it changes:: sage: from sage.functions.orthogonal_polys import chebyshev_T sage: chebyshev_T(2,x) 2*(x - 1)^2 + 4*x - 3 sage: sage.functions.orthogonal_polys._done True Note that because here we use a Pynac variable ``x``, the representation of the function is different from its actual doctest, where a polynomial indeterminate ``x`` is used. """ global _done if _done: return maxima.eval('load("orthopoly");') # TODO -- make it possible to use the intervals returned # instead of just discarding this info! maxima.eval("orthopoly_returns_intervals:false;") _done = True
def _init(): """ Internal function which checks if Maxima has loaded the "orthopoly" package. All functions using this in this file should call this function first. TEST: The global starts ``False``:: sage: sage.functions.special._done False Then after using one of the MaximaFunctions, it changes:: sage: from sage.functions.special import elliptic_ec sage: elliptic_ec(0.1) 1.53075763689776 sage: sage.functions.special._done True """ global _done if _done: return maxima.eval('load("orthopoly");') maxima.eval('orthopoly_returns_intervals:false;') _done = True
def assume(self): """ TEST:: sage: from sage.symbolic.assumptions import GenericDeclaration sage: decl = GenericDeclaration(x, 'even') sage: decl.assume() sage: cos(x*pi).simplify() 1 sage: decl2 = GenericDeclaration(x, 'odd') sage: decl2.assume() Traceback (most recent call last): ... ValueError: Assumption is inconsistent sage: decl.forget() """ from sage.calculus.calculus import maxima if self._context is None: # We get the list here because features may be added with time. valid_features = list(maxima("features")) if self._assumption not in [repr(x).strip() for x in list(valid_features)]: raise ValueError, "%s not a valid assumption, must be one of %s" % (self._assumption, valid_features) cur = maxima.get("context") self._context = maxima.newcontext('context' + maxima._next_var_name()) try: maxima.eval("declare(%s, %s)" % (repr(self._var), self._assumption)) # except TypeError, mess: # if 'inconsistent' in str(mess): # note Maxima doesn't tell you if declarations are redundant # raise ValueError, "Assumption is inconsistent" except RuntimeError, mess: if 'inconsistent' in str(mess): # note Maxima doesn't tell you if declarations are redundant raise ValueError, "Assumption is inconsistent" else: raise maxima.set("context", cur)
def _init(): """ Internal function which checks if Maxima has loaded the "orthopoly" package. All functions using this in this file should call this function first. TEST: The global starts ``False``:: sage: sage.functions.special._done False Then after using one of these functions, it changes:: sage: from sage.functions.special import airy_ai sage: airy_ai(1.0) 0.135292416313 sage: sage.functions.special._done True """ global _done if _done: return maxima.eval('load("orthopoly");') maxima.eval('orthopoly_returns_intervals:false;') _done = True
def gen_laguerre(n, a, x): """ Returns the generalized Laguerre polynomial for integers `n > -1`. Typically, `a = 1/2` or `a = -1/2`. REFERENCES: - Table on page 789 in [ASHandbook]_. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: gen_laguerre(2,1,x) 1/2*x^2 - 3*x + 3 sage: gen_laguerre(2,1/2,x) 1/2*x^2 - 5/2*x + 15/8 sage: gen_laguerre(2,-1/2,x) 1/2*x^2 - 3/2*x + 3/8 sage: gen_laguerre(2,0,x) 1/2*x^2 - 2*x + 1 sage: gen_laguerre(3,0,x) -1/6*x^3 + 3/2*x^2 - 3*x + 1 """ _init() return sage_eval(maxima.eval("gen_laguerre(%s,%s,x)" % (ZZ(n), a)), locals={"x": x})
def gen_laguerre(n, a, x): """ Returns the generalized Laguerre polynomial for integers `n > -1`. Typically, a = 1/2 or a = -1/2. REFERENCE: - table on page 789 in AS. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: gen_laguerre(2,1,x) 1/2*x^2 - 3*x + 3 sage: gen_laguerre(2,1/2,x) 1/2*x^2 - 5/2*x + 15/8 sage: gen_laguerre(2,-1/2,x) 1/2*x^2 - 3/2*x + 3/8 sage: gen_laguerre(2,0,x) 1/2*x^2 - 2*x + 1 sage: gen_laguerre(3,0,x) -1/6*x^3 + 3/2*x^2 - 3*x + 1 """ from sage.functions.all import sqrt _init() return sage_eval(maxima.eval('gen_laguerre(%s,%s,x)' % (ZZ(n), a)), locals={'x': x})
def hermite(n, x): """ Returns the Hermite polynomial for integers `n > -1`. REFERENCE: - AS 22.5.40 and 22.5.41, page 779. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: hermite(2,x) 4*x^2 - 2 sage: hermite(3,x) 8*x^3 - 12*x sage: hermite(3,2) 40 sage: S.<y> = PolynomialRing(RR) sage: hermite(3,y) 8.00000000000000*y^3 - 12.0000000000000*y sage: R.<x,y> = QQ[] sage: hermite(3,y^2) 8*y^6 - 12*y^2 sage: w = var('w') sage: hermite(3,2*w) 8*(8*w^2 - 3)*w """ _init() return sage_eval(maxima.eval('hermite(%s,x)' % ZZ(n)), locals={'x': x})
def legendre_P(n, x): """ Returns the Legendre polynomial of the first kind for integers `n > -1`. REFERENCE: - AS 22.5.35 page 779. EXAMPLES:: sage: P.<t> = QQ[] sage: legendre_P(2,t) 3/2*t^2 - 1/2 sage: legendre_P(3, 1.1) 1.67750000000000 sage: legendre_P(3, 1 + I) 7/2*I - 13/2 sage: legendre_P(3, MatrixSpace(ZZ, 2)([1, 2, -4, 7])) [-179 242] [-484 547] sage: legendre_P(3, GF(11)(5)) 8 """ _init() return sage_eval(maxima.eval('legendre_p(%s,x)' % ZZ(n)), locals={'x': x})
def ultraspherical(n, a, x): """ Returns the ultraspherical (or Gegenbauer) polynomial for integers `n > -1`. Computed using Maxima. REFERENCE: - AS 22.5.27 EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: ultraspherical(2,3/2,x) 15/2*x^2 - 3/2 sage: ultraspherical(2,1/2,x) 3/2*x^2 - 1/2 sage: ultraspherical(1,1,x) 2*x sage: t = PolynomialRing(RationalField(),"t").gen() sage: gegenbauer(3,2,t) 32*t^3 - 12*t """ _init() return sage_eval(maxima.eval('ultraspherical(%s,%s,x)' % (ZZ(n), a)), locals={'x': x})
def gen_laguerre(n, a, x): """ Returns the generalized Laguerre polynomial for integers `n > -1`. Typically, a = 1/2 or a = -1/2. REFERENCE: - table on page 789 in AS. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: gen_laguerre(2,1,x) 1/2*x^2 - 3*x + 3 sage: gen_laguerre(2,1/2,x) 1/2*x^2 - 5/2*x + 15/8 sage: gen_laguerre(2,-1/2,x) 1/2*x^2 - 3/2*x + 3/8 sage: gen_laguerre(2,0,x) 1/2*x^2 - 2*x + 1 sage: gen_laguerre(3,0,x) -1/6*x^3 + 3/2*x^2 - 3*x + 1 """ from sage.functions.all import sqrt _init() return sage_eval(maxima.eval("gen_laguerre(%s,%s,x)" % (ZZ(n), a)), locals={"x": x})
def legendre_P(n, x): """ Returns the Legendre polynomial of the first kind for integers `n > -1`. REFERENCE: - AS 22.5.35 page 779. EXAMPLES:: sage: P.<t> = QQ[] sage: legendre_P(2,t) 3/2*t^2 - 1/2 sage: legendre_P(3, 1.1) 1.67750000000000 sage: legendre_P(3, 1 + I) 7/2*I - 13/2 sage: legendre_P(3, MatrixSpace(ZZ, 2)([1, 2, -4, 7])) [-179 242] [-484 547] sage: legendre_P(3, GF(11)(5)) 8 """ _init() return sage_eval(maxima.eval("legendre_p(%s,x)" % ZZ(n)), locals={"x": x})
def hermite(n, x): """ Returns the Hermite polynomial for integers `n > -1`. REFERENCE: - AS 22.5.40 and 22.5.41, page 779. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: hermite(2,x) 4*x^2 - 2 sage: hermite(3,x) 8*x^3 - 12*x sage: hermite(3,2) 40 sage: S.<y> = PolynomialRing(RR) sage: hermite(3,y) 8.00000000000000*y^3 - 12.0000000000000*y sage: R.<x,y> = QQ[] sage: hermite(3,y^2) 8*y^6 - 12*y^2 sage: w = var('w') sage: hermite(3,2*w) 8*(8*w^2 - 3)*w """ _init() return sage_eval(maxima.eval("hermite(%s,x)" % ZZ(n)), locals={"x": x})
def ultraspherical(n, a, x): """ Returns the ultraspherical (or Gegenbauer) polynomial for integers `n > -1`. Computed using Maxima. REFERENCE: - AS 22.5.27 EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: ultraspherical(2,3/2,x) 15/2*x^2 - 3/2 sage: ultraspherical(2,1/2,x) 3/2*x^2 - 1/2 sage: ultraspherical(1,1,x) 2*x sage: t = PolynomialRing(RationalField(),"t").gen() sage: gegenbauer(3,2,t) 32*t^3 - 12*t """ _init() return sage_eval(maxima.eval("ultraspherical(%s,%s,x)" % (ZZ(n), a)), locals={"x": x})
def gen_laguerre(n, a, x): """ Returns the generalized Laguerre polynomial for integers `n > -1`. Typically, `a = 1/2` or `a = -1/2`. REFERENCES: - Table on page 789 in [ASHandbook]_. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: gen_laguerre(2,1,x) 1/2*x^2 - 3*x + 3 sage: gen_laguerre(2,1/2,x) 1/2*x^2 - 5/2*x + 15/8 sage: gen_laguerre(2,-1/2,x) 1/2*x^2 - 3/2*x + 3/8 sage: gen_laguerre(2,0,x) 1/2*x^2 - 2*x + 1 sage: gen_laguerre(3,0,x) -1/6*x^3 + 3/2*x^2 - 3*x + 1 """ _init() return sage_eval(maxima.eval('gen_laguerre(%s,%s,x)' % (ZZ(n), a)), locals={'x': x})
def bessel_Y(nu,z,algorithm="maxima", prec=53): r""" Implements the "Y-Bessel function", or "Bessel function of the 2nd kind", with index (or "order") nu and argument z. .. note:: Currently only prec=53 is supported. Defn:: cos(pi n)*bessel_J(nu, z) - bessel_J(-nu, z) ------------------------------------------------- sin(nu*pi) if nu is not an integer and by taking a limit otherwise. Sometimes bessel_Y(n,z) is denoted Y_n(z) in the literature. This is computed using Maxima by default. EXAMPLES:: sage: bessel_Y(2,1.1,"scipy") -1.4314714939... sage: bessel_Y(2,1.1) -1.4314714939590... sage: bessel_Y(3.001,2.1) -1.0299574976424... TESTS:: sage: bessel_Y(2,1.1, algorithm="pari") Traceback (most recent call last): ... NotImplementedError: The Y-Bessel function is only implemented for the maxima and scipy algorithms """ if algorithm=="scipy": if prec != 53: raise ValueError, "for the scipy algorithm the precision must be 53" import scipy.special ans = str(scipy.special.yv(float(nu),complex(real(z),imag(z)))) ans = ans.replace("(","") ans = ans.replace(")","") ans = ans.replace("j","*I") ans = sage_eval(ans) return real(ans) if z in RR else ans elif algorithm == "maxima": if prec != 53: raise ValueError, "for the maxima algorithm the precision must be 53" return RR(maxima.eval("bessel_y(%s,%s)"%(float(nu),float(z)))) elif algorithm == "pari": raise NotImplementedError, "The Y-Bessel function is only implemented for the maxima and scipy algorithms" else: raise ValueError, "unknown algorithm '%s'"%algorithm
def bessel_Y(nu, z, algorithm="maxima", prec=53): r""" Implements the "Y-Bessel function", or "Bessel function of the 2nd kind", with index (or "order") nu and argument z. .. note:: Currently only prec=53 is supported. Defn:: cos(pi n)*bessel_J(nu, z) - bessel_J(-nu, z) ------------------------------------------------- sin(nu*pi) if nu is not an integer and by taking a limit otherwise. Sometimes bessel_Y(n,z) is denoted Y_n(z) in the literature. This is computed using Maxima by default. EXAMPLES:: sage: bessel_Y(2,1.1,"scipy") -1.4314714939... sage: bessel_Y(2,1.1) -1.4314714939590... sage: bessel_Y(3.001,2.1) -1.0299574976424... TESTS:: sage: bessel_Y(2,1.1, algorithm="pari") Traceback (most recent call last): ... NotImplementedError: The Y-Bessel function is only implemented for the maxima and scipy algorithms """ if algorithm == "scipy": if prec != 53: raise ValueError, "for the scipy algorithm the precision must be 53" import scipy.special ans = str(scipy.special.yv(float(nu), complex(real(z), imag(z)))) ans = ans.replace("(", "") ans = ans.replace(")", "") ans = ans.replace("j", "*I") ans = sage_eval(ans) return real(ans) if z in RR else ans elif algorithm == "maxima": if prec != 53: raise ValueError, "for the maxima algorithm the precision must be 53" return RR(maxima.eval("bessel_y(%s,%s)" % (float(nu), float(z)))) elif algorithm == "pari": raise NotImplementedError, "The Y-Bessel function is only implemented for the maxima and scipy algorithms" else: raise ValueError, "unknown algorithm '%s'" % algorithm
def _maxima_init_evaled_(self, n, x): """ Evaluate the Chebyshev polynomial ``self`` with maxima. EXAMPLES:: sage: var('n, x') (n, x) sage: chebyshev_T._maxima_init_evaled_(1,x) '_SAGE_VAR_x' sage: maxima(chebyshev_T(n, chebyshev_T(n, x))) chebyshev_t(_SAGE_VAR_n,chebyshev_t(_SAGE_VAR_n,_SAGE_VAR_x)) """ return maxima.eval("chebyshev_t({0},{1})".format(n._maxima_init_(), x._maxima_init_()))
def _maxima_init_evaled_(self, n, x): """ Evaluate the Chebyshev polynomial ``self`` with maxima. EXAMPLES:: sage: var('n, x') (n, x) sage: chebyshev_T._maxima_init_evaled_(1,x) '_SAGE_VAR_x' sage: maxima(chebyshev_T(n, chebyshev_T(n, x))) chebyshev_t(_SAGE_VAR_n,chebyshev_t(_SAGE_VAR_n,_SAGE_VAR_x)) """ return maxima.eval('chebyshev_t({0},{1})'.format( n._maxima_init_(), x._maxima_init_()))
def _maxima_init_evaled_(self, n, x): """ Uses maxima to evaluate ``self``. EXAMPLES:: sage: var('n, x') (n, x) sage: maxima(chebyshev_U(5,x)) 32*_SAGE_VAR_x^5-32*_SAGE_VAR_x^3+6*_SAGE_VAR_x sage: maxima(chebyshev_U(n,x)) chebyshev_u(_SAGE_VAR_n,_SAGE_VAR_x) sage: maxima(chebyshev_U(2,x)) 4*_SAGE_VAR_x^2-1 """ return maxima.eval("chebyshev_u({0},{1})".format(n._maxima_init_(), x._maxima_init_()))
def chebyshev_U(n, x): """ Returns the Chebyshev function of the second kind for integers `n>-1`. REFERENCE: - AS, 22.8.3 page 783 and AS 6.1.22 page 256. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: chebyshev_U(2,x) 4*x^2 - 1 """ _init() return sage_eval(maxima.eval('chebyshev_u(%s,x)' % ZZ(n)), locals={'x': x})
def chebyshev_U(n, x): """ Returns the Chebyshev function of the second kind for integers `n>-1`. REFERENCE: - AS, 22.8.3 page 783 and AS 6.1.22 page 256. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: chebyshev_U(2,x) 4*x^2 - 1 """ _init() return sage_eval(maxima.eval("chebyshev_u(%s,x)" % ZZ(n)), locals={"x": x})
def hermite(n,x): """ Returns the Hermite polynomial for integers `n > -1`. REFERENCE: - [ASHandbook]_ 22.5.40 and 22.5.41, page 779. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: hermite(2,x) 4*x^2 - 2 sage: hermite(3,x) 8*x^3 - 12*x sage: hermite(3,2) 40 sage: S.<y> = PolynomialRing(RR) sage: hermite(3,y) 8.00000000000000*y^3 - 12.0000000000000*y sage: R.<x,y> = QQ[] sage: hermite(3,y^2) 8*y^6 - 12*y^2 sage: w = var('w') sage: hermite(3,2*w) 8*(8*w^2 - 3)*w Check that :trac:`17192` is fixed:: sage: x = PolynomialRing(QQ, 'x').gen() sage: hermite(0,x) 1 sage: hermite(-1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -1 sage: hermite(-7,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -7 """ if not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) _init() return sage_eval(maxima.eval('hermite(%s,x)'%ZZ(n)), locals={'x':x})
def hermite(n, x): """ Returns the Hermite polynomial for integers `n > -1`. REFERENCE: - [ASHandbook]_ 22.5.40 and 22.5.41, page 779. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: hermite(2,x) 4*x^2 - 2 sage: hermite(3,x) 8*x^3 - 12*x sage: hermite(3,2) 40 sage: S.<y> = PolynomialRing(RR) sage: hermite(3,y) 8.00000000000000*y^3 - 12.0000000000000*y sage: R.<x,y> = QQ[] sage: hermite(3,y^2) 8*y^6 - 12*y^2 sage: w = var('w') sage: hermite(3,2*w) 8*(8*w^2 - 3)*w Check that :trac:`17192` is fixed:: sage: x = PolynomialRing(QQ, 'x').gen() sage: hermite(0,x) 1 sage: hermite(-1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -1 sage: hermite(-7,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -7 """ if not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) _init() return sage_eval(maxima.eval('hermite(%s,x)' % ZZ(n)), locals={'x': x})
def chebyshev_T(n, x): """ Returns the Chebyshev function of the first kind for integers `n>-1`. REFERENCE: - AS 22.5.31 page 778 and AS 6.1.22 page 256. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: chebyshev_T(2,x) 2*x^2 - 1 """ _init() return sage_eval(maxima.eval('chebyshev_t(%s,x)' % ZZ(n)), locals={'x': x})
def chebyshev_T(n, x): """ Returns the Chebyshev function of the first kind for integers `n>-1`. REFERENCE: - AS 22.5.31 page 778 and AS 6.1.22 page 256. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: chebyshev_T(2,x) 2*x^2 - 1 """ _init() return sage_eval(maxima.eval("chebyshev_t(%s,x)" % ZZ(n)), locals={"x": x})
def _maxima_init_evaled_(self, n, x): """ Uses maxima to evaluate ``self``. EXAMPLES:: sage: var('n, x') (n, x) sage: maxima(chebyshev_U(5,x)) 32*_SAGE_VAR_x^5-32*_SAGE_VAR_x^3+6*_SAGE_VAR_x sage: maxima(chebyshev_U(n,x)) chebyshev_u(_SAGE_VAR_n,_SAGE_VAR_x) sage: maxima(chebyshev_U(2,x)) 4*_SAGE_VAR_x^2-1 """ return maxima.eval('chebyshev_u({0},{1})'.format( n._maxima_init_(), x._maxima_init_()))
def ultraspherical(n, a, x): """ Returns the ultraspherical (or Gegenbauer) polynomial for integers `n > -1`. Computed using Maxima. REFERENCE: - [ASHandbook]_ 22.5.27 EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: ultraspherical(2,3/2,x) 15/2*x^2 - 3/2 sage: ultraspherical(2,1/2,x) 3/2*x^2 - 1/2 sage: ultraspherical(1,1,x) 2*x sage: t = PolynomialRing(RationalField(),"t").gen() sage: gegenbauer(3,2,t) 32*t^3 - 12*t Check that :trac:`17192` is fixed:: sage: x = PolynomialRing(QQ, 'x').gen() sage: ultraspherical(0,1,x) 1 sage: ultraspherical(-1,1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -1 sage: ultraspherical(-7,1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -7 """ if not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) _init() return sage_eval(maxima.eval('ultraspherical(%s,%s,x)' % (ZZ(n), a)), locals={'x': x})
def ultraspherical(n,a,x): """ Returns the ultraspherical (or Gegenbauer) polynomial for integers `n > -1`. Computed using Maxima. REFERENCE: - [ASHandbook]_ 22.5.27 EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: ultraspherical(2,3/2,x) 15/2*x^2 - 3/2 sage: ultraspherical(2,1/2,x) 3/2*x^2 - 1/2 sage: ultraspherical(1,1,x) 2*x sage: t = PolynomialRing(RationalField(),"t").gen() sage: gegenbauer(3,2,t) 32*t^3 - 12*t Check that :trac:`17192` is fixed:: sage: x = PolynomialRing(QQ, 'x').gen() sage: ultraspherical(0,1,x) 1 sage: ultraspherical(-1,1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -1 sage: ultraspherical(-7,1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -7 """ if not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) _init() return sage_eval(maxima.eval('ultraspherical(%s,%s,x)'%(ZZ(n),a)), locals={'x':x})
def gen_laguerre(n, a, x): """ Returns the generalized Laguerre polynomial for integers `n > -1`. Typically, `a = 1/2` or `a = -1/2`. REFERENCES: - Table on page 789 in [ASHandbook]_. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: gen_laguerre(2,1,x) 1/2*x^2 - 3*x + 3 sage: gen_laguerre(2,1/2,x) 1/2*x^2 - 5/2*x + 15/8 sage: gen_laguerre(2,-1/2,x) 1/2*x^2 - 3/2*x + 3/8 sage: gen_laguerre(2,0,x) 1/2*x^2 - 2*x + 1 sage: gen_laguerre(3,0,x) -1/6*x^3 + 3/2*x^2 - 3*x + 1 Check that :trac:`17192` is fixed:: sage: x = PolynomialRing(QQ, 'x').gen() sage: gen_laguerre(0,1,x) 1 sage: gen_laguerre(-1,1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -1 sage: gen_laguerre(-7,1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -7 """ if not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) _init() return sage_eval(maxima.eval('gen_laguerre(%s,%s,x)' % (ZZ(n), a)), locals={'x': x})
def gen_laguerre(n,a,x): """ Returns the generalized Laguerre polynomial for integers `n > -1`. Typically, `a = 1/2` or `a = -1/2`. REFERENCES: - Table on page 789 in [ASHandbook]_. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: gen_laguerre(2,1,x) 1/2*x^2 - 3*x + 3 sage: gen_laguerre(2,1/2,x) 1/2*x^2 - 5/2*x + 15/8 sage: gen_laguerre(2,-1/2,x) 1/2*x^2 - 3/2*x + 3/8 sage: gen_laguerre(2,0,x) 1/2*x^2 - 2*x + 1 sage: gen_laguerre(3,0,x) -1/6*x^3 + 3/2*x^2 - 3*x + 1 Check that :trac:`17192` is fixed:: sage: x = PolynomialRing(QQ, 'x').gen() sage: gen_laguerre(0,1,x) 1 sage: gen_laguerre(-1,1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -1 sage: gen_laguerre(-7,1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -7 """ if not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) _init() return sage_eval(maxima.eval('gen_laguerre(%s,%s,x)'%(ZZ(n),a)), locals={'x':x})
def jacobi_P(n, a, b, x): r""" Returns the Jacobi polynomial `P_n^{(a,b)}(x)` for integers `n > -1` and a and b symbolic or `a > -1` and `b > -1`. The Jacobi polynomials are actually defined for all a and b. However, the Jacobi polynomial weight `(1-x)^a(1+x)^b` isn't integrable for `a \leq -1` or `b \leq -1`. REFERENCE: - Table on page 789 in [ASHandbook]_. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: jacobi_P(2,0,0,x) 3/2*x^2 - 1/2 sage: jacobi_P(2,1,2,1.2) # random output of low order bits 5.009999999999998 Check that :trac:`17192` is fixed:: sage: x = PolynomialRing(QQ, 'x').gen() sage: jacobi_P(0,0,0,x) 1 sage: jacobi_P(-1,0,0,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -1 sage: jacobi_P(-7,0,0,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -7 """ if not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) _init() return sage_eval(maxima.eval('jacobi_p(%s,%s,%s,x)' % (ZZ(n), a, b)), locals={'x': x})
def gen_legendre_Q(n, m, x): """ Returns the generalized (or associated) Legendre function of the second kind for integers `n>-1`, `m>-1`. Maxima restricts m = n. Hence the cases m n are computed using the same recursion used for gen_legendre_P(n,m,x) when m is odd and 1. EXAMPLES:: sage: P.<t> = QQ[] sage: gen_legendre_Q(2,0,t) 3/4*t^2*log(-(t + 1)/(t - 1)) - 3/2*t - 1/4*log(-(t + 1)/(t - 1)) sage: gen_legendre_Q(2,0,t) - legendre_Q(2, t) 0 sage: gen_legendre_Q(3,1,0.5) 2.49185259170895 sage: gen_legendre_Q(0, 1, x) -1/sqrt(-x^2 + 1) sage: gen_legendre_Q(2, 4, x).factor() 48*x/((x - 1)^2*(x + 1)^2) """ from sage.functions.all import sqrt if m <= n: _init() return sage_eval(maxima.eval('assoc_legendre_q(%s,%s,x)' % (ZZ(n), ZZ(m))), locals={'x': x}) if m == n + 1 or n == 0: if m.mod(2).is_zero(): denom = (1 - x**2)**(m / 2) else: denom = sqrt(1 - x**2) * (1 - x**2)**((m - 1) / 2) if m == n + 1: return (-1)**m * (m - 1).factorial() * 2**n / denom else: return (-1)**m * (m - 1).factorial() * ((x + 1)**m - (x - 1)**m) / (2 * denom) else: return ((n - m + 1) * x * gen_legendre_Q(n, m - 1, x) - (n + m - 1) * gen_legendre_Q(n - 1, m - 1, x)) / sqrt(1 - x**2)
def laguerre(n, x): """ Returns the Laguerre polynomial for integers `n > -1`. REFERENCE: - AS 22.5.16, page 778 and AS page 789. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: laguerre(2,x) 1/2*x^2 - 2*x + 1 sage: laguerre(3,x) -1/6*x^3 + 3/2*x^2 - 3*x + 1 sage: laguerre(2,2) -1 """ _init() return sage_eval(maxima.eval('laguerre(%s,x)' % ZZ(n)), locals={'x': x})
def legendre_Q(n,x): """ Returns the Legendre function of the second kind. Computed using Maxima. EXAMPLES:: sage: P.<t> = QQ[] sage: legendre_Q(2, t) 3/4*t^2*log(-(t + 1)/(t - 1)) - 3/2*t - 1/4*log(-(t + 1)/(t - 1)) sage: legendre_Q(3, 0.5) -0.198654771479482 sage: legendre_Q(4, 2) 443/16*I*pi + 443/16*log(3) - 365/12 sage: legendre_Q(4, 2.0) 0.00116107583162324 + 86.9828465962674*I """ _init() return sage_eval(maxima.eval('legendre_q(%s,x)'%ZZ(n)), locals={'x':x})
def laguerre(n, x): """ Returns the Laguerre polynomial for integers `n > -1`. REFERENCE: - AS 22.5.16, page 778 and AS page 789. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: laguerre(2,x) 1/2*x^2 - 2*x + 1 sage: laguerre(3,x) -1/6*x^3 + 3/2*x^2 - 3*x + 1 sage: laguerre(2,2) -1 """ _init() return sage_eval(maxima.eval("laguerre(%s,x)" % ZZ(n)), locals={"x": x})
def legendre_Q(n, x): """ Returns the Legendre function of the second kind. Computed using Maxima. EXAMPLES:: sage: P.<t> = QQ[] sage: legendre_Q(2, t) 3/4*t^2*log(-(t + 1)/(t - 1)) - 3/2*t - 1/4*log(-(t + 1)/(t - 1)) sage: legendre_Q(3, 0.5) -0.198654771479482 sage: legendre_Q(4, 2) 443/16*I*pi + 443/16*log(3) - 365/12 sage: legendre_Q(4, 2.0) 0.00116107583162324 + 86.9828465962674*I """ _init() return sage_eval(maxima.eval('legendre_q(%s,x)' % ZZ(n)), locals={'x': x})
def jacobi_P(n,a,b,x): r""" Returns the Jacobi polynomial `P_n^{(a,b)}(x)` for integers `n > -1` and a and b symbolic or `a > -1` and `b > -1`. The Jacobi polynomials are actually defined for all a and b. However, the Jacobi polynomial weight `(1-x)^a(1+x)^b` isn't integrable for `a \leq -1` or `b \leq -1`. REFERENCE: - Table on page 789 in [ASHandbook]_. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: jacobi_P(2,0,0,x) 3/2*x^2 - 1/2 sage: jacobi_P(2,1,2,1.2) # random output of low order bits 5.009999999999998 Check that :trac:`17192` is fixed:: sage: x = PolynomialRing(QQ, 'x').gen() sage: jacobi_P(0,0,0,x) 1 sage: jacobi_P(-1,0,0,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -1 sage: jacobi_P(-7,0,0,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -7 """ if not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) _init() return sage_eval(maxima.eval('jacobi_p(%s,%s,%s,x)'%(ZZ(n),a,b)), locals={'x':x})
def gen_legendre_P(n, m, x): r""" Returns the generalized (or associated) Legendre function of the first kind for integers `n > -1, m > -1`. The awkward code for when m is odd and 1 results from the fact that Maxima is happy with, for example, `(1 - t^2)^3/2`, but Sage is not. For these cases the function is computed from the (m-1)-case using one of the recursions satisfied by the Legendre functions. REFERENCE: - Gradshteyn and Ryzhik 8.706 page 1000. EXAMPLES:: sage: P.<t> = QQ[] sage: gen_legendre_P(2, 0, t) 3/2*t^2 - 1/2 sage: gen_legendre_P(2, 0, t) == legendre_P(2, t) True sage: gen_legendre_P(3, 1, t) -3/2*sqrt(-t^2 + 1)*(5*t^2 - 1) sage: gen_legendre_P(4, 3, t) 105*sqrt(-t^2 + 1)*(t^2 - 1)*t sage: gen_legendre_P(7, 3, I).expand() -16695*sqrt(2) sage: gen_legendre_P(4, 1, 2.5) -583.562373654533*I """ from sage.functions.all import sqrt _init() if m.mod(2).is_zero() or m.is_one(): return sage_eval(maxima.eval('assoc_legendre_p(%s,%s,x)' % (ZZ(n), ZZ(m))), locals={'x': x}) else: return sqrt(1 - x**2) * ( ((n - m + 1) * x * gen_legendre_P(n, m - 1, x) - (n + m - 1) * gen_legendre_P(n - 1, m - 1, x)) / (1 - x**2))
def gen_legendre_P(n, m, x): r""" Returns the generalized (or associated) Legendre function of the first kind for integers `n > -1, m > -1`. The awkward code for when m is odd and 1 results from the fact that Maxima is happy with, for example, `(1 - t^2)^3/2`, but Sage is not. For these cases the function is computed from the (m-1)-case using one of the recursions satisfied by the Legendre functions. REFERENCE: - Gradshteyn and Ryzhik 8.706 page 1000. EXAMPLES:: sage: P.<t> = QQ[] sage: gen_legendre_P(2, 0, t) 3/2*t^2 - 1/2 sage: gen_legendre_P(2, 0, t) == legendre_P(2, t) True sage: gen_legendre_P(3, 1, t) -3/2*sqrt(-t^2 + 1)*(5*t^2 - 1) sage: gen_legendre_P(4, 3, t) 105*sqrt(-t^2 + 1)*(t^2 - 1)*t sage: gen_legendre_P(7, 3, I).expand() -16695*sqrt(2) sage: gen_legendre_P(4, 1, 2.5) -583.562373654533*I """ from sage.functions.all import sqrt _init() if m.mod(2).is_zero() or m.is_one(): return sage_eval(maxima.eval("assoc_legendre_p(%s,%s,x)" % (ZZ(n), ZZ(m))), locals={"x": x}) else: return sqrt(1 - x ** 2) * ( ((n - m + 1) * x * gen_legendre_P(n, m - 1, x) - (n + m - 1) * gen_legendre_P(n - 1, m - 1, x)) / (1 - x ** 2) )
def gen_legendre_Q(n, m, x): """ Returns the generalized (or associated) Legendre function of the second kind for integers `n>-1`, `m>-1`. Maxima restricts m = n. Hence the cases m n are computed using the same recursion used for gen_legendre_P(n,m,x) when m is odd and 1. EXAMPLES:: sage: P.<t> = QQ[] sage: gen_legendre_Q(2,0,t) 3/4*t^2*log(-(t + 1)/(t - 1)) - 3/2*t - 1/4*log(-(t + 1)/(t - 1)) sage: gen_legendre_Q(2,0,t) - legendre_Q(2, t) 0 sage: gen_legendre_Q(3,1,0.5) 2.49185259170895 sage: gen_legendre_Q(0, 1, x) -1/sqrt(-x^2 + 1) sage: gen_legendre_Q(2, 4, x).factor() 48*x/((x - 1)^2*(x + 1)^2) """ from sage.functions.all import sqrt if m <= n: _init() return sage_eval(maxima.eval("assoc_legendre_q(%s,%s,x)" % (ZZ(n), ZZ(m))), locals={"x": x}) if m == n + 1 or n == 0: if m.mod(2).is_zero(): denom = (1 - x ** 2) ** (m / 2) else: denom = sqrt(1 - x ** 2) * (1 - x ** 2) ** ((m - 1) / 2) if m == n + 1: return (-1) ** m * (m - 1).factorial() * 2 ** n / denom else: return (-1) ** m * (m - 1).factorial() * ((x + 1) ** m - (x - 1) ** m) / (2 * denom) else: return ((n - m + 1) * x * gen_legendre_Q(n, m - 1, x) - (n + m - 1) * gen_legendre_Q(n - 1, m - 1, x)) / sqrt( 1 - x ** 2 )
def laguerre(n,x): """ Return the Laguerre polynomial for integers `n > -1`. REFERENCE: - [ASHandbook]_ 22.5.16, page 778 and page 789. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: laguerre(2,x) 1/2*x^2 - 2*x + 1 sage: laguerre(3,x) -1/6*x^3 + 3/2*x^2 - 3*x + 1 sage: laguerre(2,2) -1 Check that :trac:`17192` is fixed:: sage: x = PolynomialRing(QQ, 'x').gen() sage: laguerre(0,x) 1 sage: laguerre(-1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -1 sage: laguerre(-7,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -7 """ if not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) _init() return sage_eval(maxima.eval('laguerre(%s,x)'%ZZ(n)), locals={'x':x})
def laguerre(n, x): """ Return the Laguerre polynomial for integers `n > -1`. REFERENCE: - [ASHandbook]_ 22.5.16, page 778 and page 789. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: laguerre(2,x) 1/2*x^2 - 2*x + 1 sage: laguerre(3,x) -1/6*x^3 + 3/2*x^2 - 3*x + 1 sage: laguerre(2,2) -1 Check that :trac:`17192` is fixed:: sage: x = PolynomialRing(QQ, 'x').gen() sage: laguerre(0,x) 1 sage: laguerre(-1,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -1 sage: laguerre(-7,x) Traceback (most recent call last): ... ValueError: n must be greater than -1, got n = -7 """ if not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) _init() return sage_eval(maxima.eval('laguerre(%s,x)' % ZZ(n)), locals={'x': x})
def jacobi_P(n,a,b,x): r""" Returns the Jacobi polynomial `P_n^{(a,b)}(x)` for integers `n > -1` and a and b symbolic or `a > -1` and `b > -1`. The Jacobi polynomials are actually defined for all a and b. However, the Jacobi polynomial weight `(1-x)^a(1+x)^b` isn't integrable for `a \leq -1` or `b \leq -1`. REFERENCE: - table on page 789 in AS. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: jacobi_P(2,0,0,x) 3/2*x^2 - 1/2 sage: jacobi_P(2,1,2,1.2) # random output of low order bits 5.009999999999998 """ _init() return sage_eval(maxima.eval('jacobi_p(%s,%s,%s,x)'%(ZZ(n),a,b)), locals={'x':x})
def jacobi_P(n, a, b, x): r""" Returns the Jacobi polynomial `P_n^{(a,b)}(x)` for integers `n > -1` and a and b symbolic or `a > -1` and `b > -1`. The Jacobi polynomials are actually defined for all a and b. However, the Jacobi polynomial weight `(1-x)^a(1+x)^b` isn't integrable for `a \leq -1` or `b \leq -1`. REFERENCE: - table on page 789 in AS. EXAMPLES:: sage: x = PolynomialRing(QQ, 'x').gen() sage: jacobi_P(2,0,0,x) 3/2*x^2 - 1/2 sage: jacobi_P(2,1,2,1.2) # random output of low order bits 5.009999999999998 """ _init() return sage_eval(maxima.eval("jacobi_p(%s,%s,%s,x)" % (ZZ(n), a, b)), locals={"x": x})
def assume(self): """ Make this assumption. TESTS:: sage: from sage.symbolic.assumptions import GenericDeclaration sage: decl = GenericDeclaration(x, 'even') sage: decl.assume() sage: cos(x*pi).simplify() 1 sage: decl2 = GenericDeclaration(x, 'odd') sage: decl2.assume() Traceback (most recent call last): ... ValueError: Assumption is inconsistent sage: decl.forget() """ if self in _assumptions: return from sage.calculus.calculus import maxima cur = None context = None if self._context is None: self._validate_feature() cur = maxima.get("context") # newcontext makes a fresh context that only has $global as # a subcontext, and makes it the current $context, # but does not deactivate other current contexts. context = maxima.newcontext('context' + maxima._next_var_name()) must_declare = True elif not maxima.featurep(self._var, self._assumption): # Reactivating a previously active context. # Run $declare again with the assumption # to catch possible inconsistency # with the active contexts. cur = maxima.get("context") # Redeclaring on the existing context does not seem to trigger # inconsistency checking. ## maxima.set("context", self._context._maxima_init_()) # Instead, use a temporary context for this purpose context = maxima.newcontext('context' + maxima._next_var_name()) must_declare = True else: must_declare = False if must_declare: try: maxima.eval("declare(%s, %s)" % (self._var._maxima_init_(), self._assumption)) except RuntimeError as mess: if 'inconsistent' in str( mess ): # note Maxima doesn't tell you if declarations are redundant # Inconsistency with one of the active contexts. raise ValueError("Assumption is inconsistent") else: raise else: if self._context is None: self._context = context context = None finally: assert cur is not None maxima.set("context", cur) if context is not None: maxima.killcontext(context) maxima.activate(self._context) self._var.decl_assume(self._assumption) _assumptions[self] = True
def bessel_I(nu,z,algorithm = "pari",prec=53): r""" Implements the "I-Bessel function", or "modified Bessel function, 1st kind", with index (or "order") nu and argument z. INPUT: - ``nu`` - a real (or complex, for pari) number - ``z`` - a real (positive) algorithm - "pari" or "maxima" or "scipy" prec - real precision (for PARI only) DEFINITION:: Maxima: inf ==== - nu - 2 k nu + 2 k \ 2 z > ------------------- / k! Gamma(nu + k + 1) ==== k = 0 PARI: inf ==== - 2 k 2 k \ 2 z Gamma(nu + 1) > ----------------------- / k! Gamma(nu + k + 1) ==== k = 0 Sometimes ``bessel_I(nu,z)`` is denoted ``I_nu(z)`` in the literature. .. warning:: In Maxima (the manual says) i0 is deprecated but ``bessel_i(0,*)`` is broken. (Was fixed in recent CVS patch though.) EXAMPLES:: sage: bessel_I(1,1,"pari",500) 0.565159103992485027207696027609863307328899621621092009480294489479255640964371134092664997766814410064677886055526302676857637684917179812041131208121 sage: bessel_I(1,1) 0.565159103992485 sage: bessel_I(2,1.1,"maxima") 0.16708949925104... sage: bessel_I(0,1.1,"maxima") 1.32616018371265... sage: bessel_I(0,1,"maxima") 1.2660658777520... sage: bessel_I(1,1,"scipy") 0.565159103992... Check whether the return value is real whenever the argument is real (#10251):: sage: bessel_I(5, 1.5, algorithm='scipy') in RR True """ if algorithm=="pari": from sage.libs.pari.all import pari try: R = RealField(prec) nu = R(nu) z = R(z) except TypeError: C = ComplexField(prec) nu = C(nu) z = C(z) K = C K = z.parent() return K(pari(nu).besseli(z, precision=prec)) elif algorithm=="scipy": if prec != 53: raise ValueError, "for the scipy algorithm the precision must be 53" import scipy.special ans = str(scipy.special.iv(float(nu),complex(real(z),imag(z)))) ans = ans.replace("(","") ans = ans.replace(")","") ans = ans.replace("j","*I") ans = sage_eval(ans) return real(ans) if z in RR else ans # Return real value when arg is real elif algorithm == "maxima": if prec != 53: raise ValueError, "for the maxima algorithm the precision must be 53" return sage_eval(maxima.eval("bessel_i(%s,%s)"%(float(nu),float(z)))) else: raise ValueError, "unknown algorithm '%s'"%algorithm
def bessel_I(nu, z, algorithm="pari", prec=53): r""" Implements the "I-Bessel function", or "modified Bessel function, 1st kind", with index (or "order") nu and argument z. INPUT: - ``nu`` - a real (or complex, for pari) number - ``z`` - a real (positive) algorithm - "pari" or "maxima" or "scipy" prec - real precision (for PARI only) DEFINITION:: Maxima: inf ==== - nu - 2 k nu + 2 k \ 2 z > ------------------- / k! Gamma(nu + k + 1) ==== k = 0 PARI: inf ==== - 2 k 2 k \ 2 z Gamma(nu + 1) > ----------------------- / k! Gamma(nu + k + 1) ==== k = 0 Sometimes ``bessel_I(nu,z)`` is denoted ``I_nu(z)`` in the literature. .. warning:: In Maxima (the manual says) i0 is deprecated but ``bessel_i(0,*)`` is broken. (Was fixed in recent CVS patch though.) EXAMPLES:: sage: bessel_I(1,1,"pari",500) 0.565159103992485027207696027609863307328899621621092009480294489479255640964371134092664997766814410064677886055526302676857637684917179812041131208121 sage: bessel_I(1,1) 0.565159103992485 sage: bessel_I(2,1.1,"maxima") 0.16708949925104... sage: bessel_I(0,1.1,"maxima") 1.32616018371265... sage: bessel_I(0,1,"maxima") 1.2660658777520... sage: bessel_I(1,1,"scipy") 0.565159103992... Check whether the return value is real whenever the argument is real (#10251):: sage: bessel_I(5, 1.5, algorithm='scipy') in RR True """ if algorithm == "pari": from sage.libs.pari.all import pari try: R = RealField(prec) nu = R(nu) z = R(z) except TypeError: C = ComplexField(prec) nu = C(nu) z = C(z) K = C K = z.parent() return K(pari(nu).besseli(z, precision=prec)) elif algorithm == "scipy": if prec != 53: raise ValueError, "for the scipy algorithm the precision must be 53" import scipy.special ans = str(scipy.special.iv(float(nu), complex(real(z), imag(z)))) ans = ans.replace("(", "") ans = ans.replace(")", "") ans = ans.replace("j", "*I") ans = sage_eval(ans) return real( ans) if z in RR else ans # Return real value when arg is real elif algorithm == "maxima": if prec != 53: raise ValueError, "for the maxima algorithm the precision must be 53" return sage_eval(maxima.eval("bessel_i(%s,%s)" % (float(nu), float(z)))) else: raise ValueError, "unknown algorithm '%s'" % algorithm