def _eval_(self, n, m, theta, phi, **kwargs): r""" TESTS:: sage: x, y = var('x y') sage: spherical_harmonic(1, 2, x, y) 0 sage: spherical_harmonic(1, -2, x, y) 0 sage: spherical_harmonic(1/2, 2, x, y) spherical_harmonic(1/2, 2, x, y) sage: spherical_harmonic(3, 2, x, y) 1/8*sqrt(30)*sqrt(7)*cos(x)*e^(2*I*y)*sin(x)^2/sqrt(pi) sage: spherical_harmonic(3, 2, 1, 2) 1/8*sqrt(30)*sqrt(7)*cos(1)*e^(4*I)*sin(1)^2/sqrt(pi) sage: spherical_harmonic(3 + I, 2., 1, 2) -0.351154337307488 - 0.415562233975369*I Check that :trac:`20939` is fixed:: sage: ex = spherical_harmonic(3,2,1,2*pi/3) sage: QQbar(ex * sqrt(pi)/cos(1)/sin(1)^2).minpoly() x^4 + 105/32*x^2 + 11025/1024 """ if n in ZZ and m in ZZ and n > -1: if abs(m) > n: return ZZ(0) if m == 0 and theta.is_zero(): return sqrt((2*n+1)/4/pi) from sage.arith.misc import factorial from sage.functions.trig import cos from sage.functions.orthogonal_polys import gen_legendre_P return (sqrt(factorial(n-m) * (2*n+1) / (4*pi * factorial(n+m))) * exp(I*m*phi) * gen_legendre_P(n, m, cos(theta)) * (-1)**m).simplify_trig()
def _derivative_(self, u, m, diff_param): """ EXAMPLES:: sage: x,m = var('x,m') sage: elliptic_eu(x,m).diff(x) sqrt(-m*jacobi_sn(x, m)^2 + 1)*jacobi_dn(x, m) sage: elliptic_eu(x,m).diff(m) 1/2*(elliptic_eu(x, m) - elliptic_f(jacobi_am(x, m), m))/m - 1/2*(m*jacobi_cn(x, m)*jacobi_sn(x, m) - (m - 1)*x - elliptic_eu(x, m)*jacobi_dn(x, m))*sqrt(-m*jacobi_sn(x, m)^2 + 1)/((m - 1)*m) """ from sage.functions.jacobi import jacobi, jacobi_am if diff_param == 0: return (sqrt(-m * jacobi('sn', u, m) ** Integer(2) + Integer(1)) * jacobi('dn', u, m)) elif diff_param == 1: return (Integer(1) / Integer(2) * (elliptic_eu(u, m) - elliptic_f(jacobi_am(u, m), m)) / m - Integer(1) / Integer(2) * sqrt(-m * jacobi('sn', u, m) ** Integer(2) + Integer(1)) * (m * jacobi('sn', u, m) * jacobi('cn', u, m) - (m - Integer(1)) * u - elliptic_eu(u, m) * jacobi('dn', u, m)) / ((m - Integer(1)) * m))
def Weyl_law_N(self,T,T1=None): r""" The counting function for this space. N(T)=#{disc. ev.<=T} INPUT: - ``T`` -- double EXAMPLES:: sage: M=MaassWaveForms(MySubgroup(Gamma0(1)) sage: M.Weyl_law_N(10) 0.572841337202191 """ (c1,c2,c3,c4,c5)=self._Weyl_law_const cc1=RR(c1); cc2=RR(c2); cc3=RR(c3); cc4=RR(c4); cc5=RR(c5) #print "c1,c2,c3,c4,c5=",cc1,cc2,cc3,cc4,cc5 t=sqrt(T*T+0.25) try: lnt=ln(t) except TypeError: lnt=mpmath.ln(t) #print "t,ln(t)=",t,lnt NT=cc1*t*t-cc2*t*lnt+cc3*t+cc4*t+cc5 if(T1<>None): t=sqrt(T1*T1+0.25) NT1=cc1*(T1*T1+0.25)-cc2*t*ln(t)+cc3*t+cc4*t+cc5 return RR(abs(NT1-NT)) else: return RR(NT)
def _derivative_(self, n, z, m, diff_param): """ EXAMPLES:: sage: n,z,m = var('n,z,m') sage: elliptic_pi(n,z,m).diff(n) 1/4*(sqrt(-m*sin(z)^2 + 1)*n*sin(2*z)/(n*sin(z)^2 - 1) + 2*(m - n)*elliptic_f(z, m)/n + 2*(n^2 - m)*elliptic_pi(n, z, m)/n + 2*elliptic_e(z, m))/((m - n)*(n - 1)) sage: elliptic_pi(n,z,m).diff(z) -1/(sqrt(-m*sin(z)^2 + 1)*(n*sin(z)^2 - 1)) sage: elliptic_pi(n,z,m).diff(m) 1/4*(m*sin(2*z)/(sqrt(-m*sin(z)^2 + 1)*(m - 1)) - 2*elliptic_e(z, m)/(m - 1) - 2*elliptic_pi(n, z, m))/(m - n) """ if diff_param == 0: return ((Integer(1) / (Integer(2) * (m - n) * (n - Integer(1)))) * (elliptic_e(z, m) + ((m - n) / n) * elliptic_f(z, m) + ((n ** Integer(2) - m) / n) * elliptic_pi(n, z, m) - (n * sqrt(Integer(1) - m * sin(z) ** Integer(2)) * sin(Integer(2) * z)) / (Integer(2) * (Integer(1) - n * sin(z) ** Integer(2))))) elif diff_param == 1: return (Integer(1) / (sqrt(Integer(1) - m * sin(z) ** Integer(Integer(2))) * (Integer(1) - n * sin(z) ** Integer(2)))) elif diff_param == 2: return ((Integer(1) / (Integer(2) * (n - m))) * (elliptic_e(z, m) / (m - Integer(1)) + elliptic_pi(n, z, m) - (m * sin(Integer(2) * z)) / (Integer(2) * (m - Integer(1)) * sqrt(Integer(1) - m * sin(z) ** Integer(2)))))
def _derivative_(self, u, m, diff_param): """ EXAMPLES:: sage: x,m = var('x,m') sage: elliptic_eu(x,m).diff(x) sqrt(-m*jacobi_sn(x, m)^2 + 1)*jacobi_dn(x, m) sage: elliptic_eu(x,m).diff(m) 1/2*(elliptic_eu(x, m) - elliptic_f(jacobi_am(x, m), m))/m - 1/2*(m*jacobi_cn(x, m)*jacobi_sn(x, m) - (m - 1)*x - elliptic_eu(x, m)*jacobi_dn(x, m))*sqrt(-m*jacobi_sn(x, m)^2 + 1)/((m - 1)*m) """ from sage.functions.jacobi import jacobi, jacobi_am if diff_param == 0: return (sqrt(-m * jacobi('sn', u, m)**Integer(2) + Integer(1)) * jacobi('dn', u, m)) elif diff_param == 1: return (Integer(1) / Integer(2) * (elliptic_eu(u, m) - elliptic_f(jacobi_am(u, m), m)) / m - Integer(1) / Integer(2) * sqrt(-m * jacobi('sn', u, m)**Integer(2) + Integer(1)) * (m * jacobi('sn', u, m) * jacobi('cn', u, m) - (m - Integer(1)) * u - elliptic_eu(u, m) * jacobi('dn', u, m)) / ((m - Integer(1)) * m))
def _derivative_(self, n, z, m, diff_param): """ EXAMPLES:: sage: n,z,m = var('n,z,m') sage: elliptic_pi(n,z,m).diff(n) 1/4*(sqrt(-m*sin(z)^2 + 1)*n*sin(2*z)/(n*sin(z)^2 - 1) + 2*(m - n)*elliptic_f(z, m)/n + 2*(n^2 - m)*elliptic_pi(n, z, m)/n + 2*elliptic_e(z, m))/((m - n)*(n - 1)) sage: elliptic_pi(n,z,m).diff(z) -1/(sqrt(-m*sin(z)^2 + 1)*(n*sin(z)^2 - 1)) sage: elliptic_pi(n,z,m).diff(m) 1/4*(m*sin(2*z)/(sqrt(-m*sin(z)^2 + 1)*(m - 1)) - 2*elliptic_e(z, m)/(m - 1) - 2*elliptic_pi(n, z, m))/(m - n) """ if diff_param == 0: return ((Integer(1) / (Integer(2) * (m - n) * (n - Integer(1)))) * (elliptic_e(z, m) + ((m - n) / n) * elliptic_f(z, m) + ((n**Integer(2) - m) / n) * elliptic_pi(n, z, m) - (n * sqrt(Integer(1) - m * sin(z)**Integer(2)) * sin(Integer(2) * z)) / (Integer(2) * (Integer(1) - n * sin(z)**Integer(2))))) elif diff_param == 1: return (Integer(1) / (sqrt(Integer(1) - m * sin(z)**Integer(Integer(2))) * (Integer(1) - n * sin(z)**Integer(2)))) elif diff_param == 2: return ((Integer(1) / (Integer(2) * (n - m))) * ( elliptic_e(z, m) / (m - Integer(1)) + elliptic_pi(n, z, m) - (m * sin(Integer(2) * z)) / (Integer(2) * (m - Integer(1)) * sqrt(Integer(1) - m * sin(z)**Integer(2)))) )
def plot_slope_field(f, xrange, yrange, **kwds): r""" ``plot_slope_field`` takes a function of two variables xvar and yvar (for instance, if the variables are `x` and `y`, take `f(x,y)`), and at representative points `(x_i,y_i)` between xmin, xmax, and ymin, ymax respectively, plots a line with slope `f(x_i,y_i)` (see below). ``plot_slope_field(f, (xvar, xmin, xmax), (yvar, ymin, ymax))`` EXAMPLES: A logistic function modeling population growth:: sage: x,y = var('x y') sage: capacity = 3 # thousand sage: growth_rate = 0.7 # population increases by 70% per unit of time sage: plot_slope_field(growth_rate*(1-y/capacity)*y, (x,0,5), (y,0,capacity*2)) Graphics object consisting of 1 graphics primitive Plot a slope field involving sin and cos:: sage: x,y = var('x y') sage: plot_slope_field(sin(x+y)+cos(x+y), (x,-3,3), (y,-3,3)) Graphics object consisting of 1 graphics primitive Plot a slope field using a lambda function:: sage: plot_slope_field(lambda x,y: x+y, (-2,2), (-2,2)) Graphics object consisting of 1 graphics primitive TESTS: Verify that we're not getting warnings due to use of headless quivers (trac #11208):: sage: x,y = var('x y') sage: import numpy # bump warnings up to errors for testing purposes sage: old_err = numpy.seterr('raise') sage: plot_slope_field(sin(x+y)+cos(x+y), (x,-3,3), (y,-3,3)) Graphics object consisting of 1 graphics primitive sage: dummy_err = numpy.seterr(**old_err) """ slope_options = { 'headaxislength': 0, 'headlength': 1e-9, 'pivot': 'middle' } slope_options.update(kwds) from sage.functions.all import sqrt from inspect import isfunction if isfunction(f): norm_inverse = lambda x, y: 1 / sqrt(f(x, y)**2 + 1) f_normalized = lambda x, y: f(x, y) * norm_inverse(x, y) else: norm_inverse = 1 / sqrt((f**2 + 1)) f_normalized = f * norm_inverse return plot_vector_field((norm_inverse, f_normalized), xrange, yrange, **slope_options)
def plot_slope_field(f, xrange, yrange, **kwds): r""" ``plot_slope_field`` takes a function of two variables xvar and yvar (for instance, if the variables are `x` and `y`, take `f(x,y)`), and at representative points `(x_i,y_i)` between xmin, xmax, and ymin, ymax respectively, plots a line with slope `f(x_i,y_i)` (see below). ``plot_slope_field(f, (xvar, xmin, xmax), (yvar, ymin, ymax))`` EXAMPLES: A logistic function modeling population growth:: sage: x,y = var('x y') sage: capacity = 3 # thousand sage: growth_rate = 0.7 # population increases by 70% per unit of time sage: plot_slope_field(growth_rate*(1-y/capacity)*y, (x,0,5), (y,0,capacity*2)) Graphics object consisting of 1 graphics primitive Plot a slope field involving sin and cos:: sage: x,y = var('x y') sage: plot_slope_field(sin(x+y)+cos(x+y), (x,-3,3), (y,-3,3)) Graphics object consisting of 1 graphics primitive Plot a slope field using a lambda function:: sage: plot_slope_field(lambda x,y: x+y, (-2,2), (-2,2)) Graphics object consisting of 1 graphics primitive TESTS: Verify that we're not getting warnings due to use of headless quivers (trac #11208):: sage: x,y = var('x y') sage: import numpy # bump warnings up to errors for testing purposes sage: old_err = numpy.seterr('raise') sage: plot_slope_field(sin(x+y)+cos(x+y), (x,-3,3), (y,-3,3)) Graphics object consisting of 1 graphics primitive sage: dummy_err = numpy.seterr(**old_err) """ slope_options = {'headaxislength': 0, 'headlength': 1e-9, 'pivot': 'middle'} slope_options.update(kwds) from sage.functions.all import sqrt from inspect import isfunction if isfunction(f): norm_inverse=lambda x,y: 1/sqrt(f(x,y)**2+1) f_normalized=lambda x,y: f(x,y)*norm_inverse(x,y) else: norm_inverse = 1/sqrt((f**2+1)) f_normalized=f*norm_inverse return plot_vector_field((norm_inverse, f_normalized), xrange, yrange, **slope_options)
def volcano_schoof(E, volcano_2=True): q = E.base_field().order() residues = [] moduli = [] l = 2 while prod(moduli) <= 4 * sqrt(q): if q % l == 0: l = next_prime(l) res = finding_t_modln(E, l, volcano_2=volcano_2) residues.append(res[0]) moduli.append(res[1]) l = next_prime(l) t = CRT_list(residues, moduli) if t > 2 * sqrt(q): t = t - prod(moduli) return t
def is_triangular_number(n): """ Determines if the integer n is a triangular number. (I.e. determine if n = a*(a+1)/2 for some natural number a.) If so, return the number a, otherwise return False. Note: As a convention, n=0 is considered triangular for the number a=0 only (and not for a=-1). WARNING: Any non-zero value will return True, so this will test as True iff n is triangular and not zero. If n is zero, then this will return the integer zero, which tests as False, so one must test if is_triangular_number(n) != False: instead of if is_triangular_number(n): to get zero to appear triangular. INPUT: an integer OUTPUT: either False or a non-negative integer EXAMPLES: sage: is_triangular_number(3) 2 sage: is_triangular_number(1) 1 sage: is_triangular_number(2) False sage: is_triangular_number(0) 0 sage: is_triangular_number(-1) False sage: is_triangular_number(-11) False sage: is_triangular_number(-1000) False sage: is_triangular_number(-0) 0 sage: is_triangular_number(10^6 * (10^6 +1)/2) 1000000 """ if n < 0: return False elif n == 0: return ZZ(0) else: from sage.functions.all import sqrt ## Try to solve for the integer a try: disc_sqrt = ZZ(sqrt(1+8*n)) a = ZZ( (ZZ(-1) + disc_sqrt) / ZZ(2) ) return a except StandardError: return False
def is_triangular_number(n): """ Determines if the integer n is a triangular number. (I.e. determine if n = a*(a+1)/2 for some natural number a.) If so, return the number a, otherwise return False. Note: As a convention, n=0 is considered triangular for the number a=0 only (and not for a=-1). WARNING: Any non-zero value will return True, so this will test as True iff n is triangular and not zero. If n is zero, then this will return the integer zero, which tests as False, so one must test if is_triangular_number(n) != False: instead of if is_triangular_number(n): to get zero to appear triangular. INPUT: an integer OUTPUT: either False or a non-negative integer EXAMPLES: sage: is_triangular_number(3) 2 sage: is_triangular_number(1) 1 sage: is_triangular_number(2) False sage: is_triangular_number(0) 0 sage: is_triangular_number(-1) False sage: is_triangular_number(-11) False sage: is_triangular_number(-1000) False sage: is_triangular_number(-0) 0 sage: is_triangular_number(10^6 * (10^6 +1)/2) 1000000 """ if n < 0: return False elif n == 0: return ZZ(0) else: from sage.functions.all import sqrt ## Try to solve for the integer a try: disc_sqrt = ZZ(sqrt(1 + 8 * n)) a = ZZ((ZZ(-1) + disc_sqrt) / ZZ(2)) return a except StandardError: return False
def schoof(E, info=False): q = E.base_field().order() residues = [trace_of_frobenius_mod_2(E)] moduli = [2] l = 3 while prod(moduli) <= 4 * sqrt(q): if q % l == 0: l = next_prime(l) residues.append(trace_of_frobenius_mod(E, l)) moduli.append(l) l = next_prime(l) t = CRT_list(residues, moduli) if t > 2 * sqrt(q): t = t - prod(moduli) if info: return t, moduli return t
def _2x2_matrix_entries(self, beta): r""" Young's representations are constructed by combining `2\times2`-matrices that depend on ``beta`` For the orthogonal representation, this is the following matrix:: ``[ -beta sqrt(1-beta^2) ]`` ``[ sqrt(1-beta^2) beta ]`` EXAMPLES:: sage: from sage.combinat.symmetric_group_representations import YoungRepresentation_Orthogonal sage: orth = YoungRepresentation_Orthogonal([2,1]) sage: orth._2x2_matrix_entries(1/2) (-1/2, 1/2*sqrt(3), 1/2*sqrt(3), 1/2) """ return (-beta, sqrt(1-beta**2), sqrt(1-beta**2), beta)
def _2x2_matrix_entries(self, beta): r""" Young's representations are constructed by combining `2 \times 2`-matrices that depend on ``beta``. For the orthogonal representation, this is the following matrix:: [ -beta sqrt(1-beta^2) ] [ sqrt(1-beta^2) beta ] EXAMPLES:: sage: orth = SymmetricGroupRepresentation([2,1], "orthogonal") sage: orth._2x2_matrix_entries(1/2) (-1/2, 1/2*sqrt(3), 1/2*sqrt(3), 1/2) """ return (-beta, sqrt(1 - beta**2), sqrt(1 - beta**2), beta)
def set_params(lam, k): n = pow(2, ceil(log(lam**2 * k)/log(2))) # dim of poly ring, closest power of 2 to k(lam^2) q = next_prime(ZZ(2)**(8*k*lam) * n**k, proof=False) # prime modulus sigma = int(sqrt(lam * n)) sigma_prime = lam * int(n**(1.5)) return (n, q, sigma, sigma_prime, k)
def _2x2_matrix_entries(self, beta): r""" Young's representations are constructed by combining `2\times2`-matrices that depend on ``beta`` For the orthogonal representation, this is the following matrix:: ``[ -beta sqrt(1-beta^2) ]`` ``[ sqrt(1-beta^2) beta ]`` EXAMPLES:: sage: from sage.combinat.symmetric_group_representations import YoungRepresentation_Orthogonal sage: orth = YoungRepresentation_Orthogonal([2,1]) sage: orth._2x2_matrix_entries(1/2) (-1/2, 1/2*sqrt(3), 1/2*sqrt(3), 1/2) """ return (-beta, sqrt(1 - beta**2), sqrt(1 - beta**2), beta)
def __lalg__(self, D): r""" For positive `D`, this function evaluates the quotient `L(E_D,1)\cdot \sqrt(D)/\Omega_E` where `E_D` is the twist of `E` by `D`, `\Omega_E` is the least positive period of `E`. For negative `E`, it is the quotient `L(E_D,1)\cdot \sqrt(-D)/\Omega^{-}_E` where `\Omega^{-}_E` is the least positive imaginary part of a non-real period of `E`. EXAMPLES:: sage: E = EllipticCurve('11a1') sage: m = E.modular_symbol(sign=+1) sage: m.__lalg__(1) 1/5 sage: m.__lalg__(3) 5/2 """ from sage.functions.all import sqrt # the computation of the L-value could take a lot of time, # but then the conductor is so large # that the computation of modular symbols for E took even longer E = self._E ED = E.quadratic_twist(D) lv = ED.lseries().L_ratio( ) # this is L(ED,1) divided by the Neron period omD of ED lv *= ED.real_components() # now it is by the least positive period omD = ED.period_lattice().basis()[0] if D > 0: om = E.period_lattice().basis()[0] q = sqrt(D) * omD / om * 8 else: om = E.period_lattice().basis()[1].imag() if E.real_components() == 1: om *= 2 q = sqrt(-D) * omD / om * 8 # see padic_lseries.pAdicLeries._quotient_of_periods_to_twist # for the explanation of the second factor verbose('real approximation is %s' % q) return lv / 8 * QQ(int(round(q)))
def __lalg__(self,D): r""" For positive `D`, this function evaluates the quotient `L(E_D,1)\cdot \sqrt(D)/\Omega_E` where `E_D` is the twist of `E` by `D`, `\Omega_E` is the least positive period of `E`. For negative `E`, it is the quotient `L(E_D,1)\cdot \sqrt(-D)/\Omega^{-}_E` where `\Omega^{-}_E` is the least positive imaginary part of a non-real period of `E`. EXAMPLES:: sage: E = EllipticCurve('11a1') sage: m = E.modular_symbol(sign=+1, implementation='sage') sage: m.__lalg__(1) 1/5 sage: m.__lalg__(3) 5/2 """ from sage.functions.all import sqrt # the computation of the L-value could take a lot of time, # but then the conductor is so large # that the computation of modular symbols for E took even longer E = self._E ED = E.quadratic_twist(D) lv = ED.lseries().L_ratio() # this is L(ED,1) divided by the Néron period omD of ED lv *= ED.real_components() # now it is by the least positive period omD = ED.period_lattice().basis()[0] if D > 0 : om = E.period_lattice().basis()[0] q = sqrt(D)*omD/om * 8 else : om = E.period_lattice().basis()[1].imag() if E.real_components() == 1: om *= 2 q = sqrt(-D)*omD/om*8 # see padic_lseries.pAdicLeries._quotient_of_periods_to_twist # for the explanation of the second factor verbose('real approximation is %s'%q) return lv/8 * QQ(int(round(q)))
def _derivative_(self, x, diff_param=None): """ Derivative of inverse erf function. EXAMPLES:: sage: erfinv(x).diff(x) 1/2*sqrt(pi)*e^(erfinv(x)^2) """ return sqrt(pi)*exp(erfinv(x)**2)/2
def _derivative_(self, x, diff_param=None): """ Derivative of inverse erf function. EXAMPLES:: sage: erfinv(x).diff(x) 1/2*sqrt(pi)*e^(erfinv(x)^2) """ return sqrt(pi) * exp(erfinv(x)**2) / 2
def _derivative_(self, x, diff_param=None): """ Derivative of erfc function. EXAMPLES:: sage: erfc(x).diff(x) -2*e^(-x^2)/sqrt(pi) """ return -2*exp(-x**2)/sqrt(pi)
def _derivative_(self, x, diff_param=None): """ Derivative of erfc function. EXAMPLES:: sage: erfc(x).diff(x) -2*e^(-x^2)/sqrt(pi) """ return -2 * exp(-x**2) / sqrt(pi)
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 _derivative_(self, x, diff_param=None): """ Derivative of erfi function. EXAMPLES:: sage: erfi(x).diff(x) 2*e^(x^2)/sqrt(pi) """ return 2*exp(x**2)/sqrt(pi)
def mrrw1_bound_asymp(delta,q): """ Computes the first asymptotic McEliese-Rumsey-Rodemich-Welsh bound for the information rate, provided `0 < \delta < 1-1/q`. EXAMPLES:: sage: mrrw1_bound_asymp(1/4,2) 0.354578902665 """ return RDF(entropy((q-1-delta*(q-2)-2*sqrt((q-1)*delta*(1-delta)))/q,q))
def set_params(lam, k): n = pow(2, ceil( log(lam**2 * k) / log(2))) # dim of poly ring, closest power of 2 to k(lam^2) q = next_prime(ZZ(2)**(8 * k * lam) * n**k, proof=False) # prime modulus sigma = int(sqrt(lam * n)) sigma_prime = lam * int(n**(1.5)) return (n, q, sigma, sigma_prime, k)
def _derivative_(self, z, m, diff_param): """ EXAMPLES:: sage: x,m = var('x,m') sage: elliptic_f(x,m).diff(x) 1/sqrt(-m*sin(x)^2 + 1) sage: elliptic_f(x,m).diff(m) -1/2*elliptic_f(x, m)/m + 1/4*sin(2*x)/(sqrt(-m*sin(x)^2 + 1)*(m - 1)) - 1/2*elliptic_e(x, m)/((m - 1)*m) """ if diff_param == 0: return Integer(1) / sqrt(Integer(1) - m * sin(z) ** Integer(2)) elif diff_param == 1: return (elliptic_e(z, m) / (Integer(2) * (Integer(1) - m) * m) - elliptic_f(z, m) / (Integer(2) * m) - (sin(Integer(2) * z) / (Integer(4) * (Integer(1) - m) * sqrt(Integer(1) - m * sin(z) ** Integer(2)))))
def _derivative_(self, z, m, diff_param): """ EXAMPLES:: sage: x,m = var('x,m') sage: elliptic_f(x,m).diff(x) 1/sqrt(-m*sin(x)^2 + 1) sage: elliptic_f(x,m).diff(m) -1/2*elliptic_f(x, m)/m + 1/4*sin(2*x)/(sqrt(-m*sin(x)^2 + 1)*(m - 1)) - 1/2*elliptic_e(x, m)/((m - 1)*m) """ if diff_param == 0: return Integer(1) / sqrt(Integer(1) - m * sin(z)**Integer(2)) elif diff_param == 1: return (elliptic_e(z, m) / (Integer(2) * (Integer(1) - m) * m) - elliptic_f(z, m) / (Integer(2) * m) - (sin(Integer(2) * z) / (Integer(4) * (Integer(1) - m) * sqrt(Integer(1) - m * sin(z)**Integer(2)))))
def _derivative_(self, x, diff_param=None): """ Derivative of erfi function. EXAMPLES:: sage: erfi(x).diff(x) 2*e^(x^2)/sqrt(pi) """ return 2 * exp(x**2) / sqrt(pi)
def elias_bound_asymp(delta,q): """ Computes the asymptotic Elias bound for the information rate, provided `0 < \delta 1-1/q`. EXAMPLES:: sage: elias_bound_asymp(1/4,2) 0.39912396330... """ r = 1-1/q return RDF((1-entropy(r-sqrt(r*(r-delta)), q)))
def elias_bound_asymp(delta, q): """ Computes the asymptotic Elias bound for the information rate, provided `0 < \delta < 1-1/q`. EXAMPLES:: sage: codes.bounds.elias_bound_asymp(1/4,2) 0.39912396330... """ r = 1 - 1 / q return RDF((1 - entropy(r - sqrt(r * (r - delta)), q)))
def mrrw1_bound_asymp(delta,q): """ The first asymptotic McEliese-Rumsey-Rodemich-Welsh bound. This only makes sense when `0 < \delta < 1-1/q`. EXAMPLES:: sage: codes.bounds.mrrw1_bound_asymp(1/4,2) # abs tol 4e-16 0.3545789026652697 """ return RDF(entropy((q-1-delta*(q-2)-2*sqrt((q-1)*delta*(1-delta)))/q,q))
def plot_slope_field(f, xrange, yrange, **kwds): r""" ``plot_slope_field`` takes a function of two variables xvar and yvar (for instance, if the variables are `x` and `y`, take `f(x,y)`), and at representative points `(x_i,y_i)` between xmin, xmax, and ymin, ymax respectively, plots a line with slope `f(x_i,y_i)` (see below). ``plot_slope_field(f, (xvar, xmin, xmax), (yvar, ymin, ymax))`` EXAMPLES: A logistic function modeling population growth:: sage: x,y = var('x y') sage: capacity = 3 # thousand sage: growth_rate = 0.7 # population increases by 70% per unit of time sage: plot_slope_field(growth_rate*(1-y/capacity)*y, (x,0,5), (y,0,capacity*2)) Plot a slope field involving sin and cos:: sage: x,y = var('x y') sage: plot_slope_field(sin(x+y)+cos(x+y), (x,-3,3), (y,-3,3)) Plot a slope field using a lambda function:: sage: plot_slope_field(lambda x,y: x+y, (-2,2), (-2,2)) """ slope_options = {'headaxislength': 0, 'headlength': 0, 'pivot': 'middle'} slope_options.update(kwds) from sage.functions.all import sqrt from inspect import isfunction if isfunction(f): norm_inverse = lambda x, y: 1 / sqrt(f(x, y)**2 + 1) f_normalized = lambda x, y: f(x, y) * norm_inverse(x, y) else: norm_inverse = 1 / sqrt((f**2 + 1)) f_normalized = f * norm_inverse return plot_vector_field((norm_inverse, f_normalized), xrange, yrange, **slope_options)
def __init__(self, params, asym=False): (self.n, self.q, sigma, self.sigma_prime, self.k) = params S, x = PolynomialRing(ZZ, 'x').objgen() self.R = S.quotient_ring(S.ideal(x**self.n + 1)) Sq = PolynomialRing(Zmod(self.q), 'x') self.Rq = Sq.quotient_ring(Sq.ideal(x**self.n + 1)) # draw z_is uniformly from Rq and compute its inverse in Rq if asym: z = [self.Rq.random_element() for i in range(self.k)] self.zinv = [z_i**(-1) for z_i in z] else: # or do symmetric version z = self.Rq.random_element() zinv = z**(-1) z, self.zinv = zip(*[(z, zinv) for i in range(self.k)]) # set up some discrete Gaussians DGSL_sigma = DGSL(ZZ**self.n, sigma) self.D_sigma = lambda: self.Rq(list(DGSL_sigma())) # discrete Gaussian in ZZ^n with stddev sigma_prime, yields random level-0 encodings DGSL_sigmap_ZZ = DGSL(ZZ**self.n, self.sigma_prime) self.D_sigmap_ZZ = lambda: self.Rq(list(DGSL_sigmap_ZZ())) # draw g repeatedly from a Gaussian distribution of Z^n (with param sigma) # until g^(-1) in QQ[x]/<x^n + 1> is small (< n^2) Sk = PolynomialRing(QQ, 'x') K = Sk.quotient_ring(Sk.ideal(x**self.n + 1)) while True: l = self.D_sigma() ginv_K = K(mod_near_poly(l, self.q))**(-1) ginv_size = vector(ginv_K).norm() if ginv_size < self.n**2: g = self.Rq(l) self.ginv = g**(-1) break # discrete Gaussian in I = <g>, yields random encodings of 0 short_g = vector(ZZ, mod_near_poly(g, self.q)) DGSL_sigmap_I = DGSL(short_g, self.sigma_prime) self.D_sigmap_I = lambda: self.Rq(list(DGSL_sigmap_I())) # compute zero-testing parameter p_zt # randomly draw h (in Rq) from a discrete Gaussian with param q^(1/2) self.h = self.Rq(list(DGSL(ZZ**self.n, round(sqrt(self.q)))())) # create p_zt self.p_zt = self.ginv * self.h * prod(z)
def __init__(self, params, asym=False): (self.n, self.q, sigma, self.sigma_prime, self.k) = params S, x = PolynomialRing(ZZ, 'x').objgen() self.R = S.quotient_ring(S.ideal(x**self.n + 1)) Sq = PolynomialRing(Zmod(self.q), 'x') self.Rq = Sq.quotient_ring(Sq.ideal(x**self.n + 1)) # draw z_is uniformly from Rq and compute its inverse in Rq if asym: z = [self.Rq.random_element() for i in range(self.k)] self.zinv = [z_i**(-1) for z_i in z] else: # or do symmetric version z = self.Rq.random_element() zinv = z**(-1) z, self.zinv = zip(*[(z,zinv) for i in range(self.k)]) # set up some discrete Gaussians DGSL_sigma = DGSL(ZZ**self.n, sigma) self.D_sigma = lambda: self.Rq(list(DGSL_sigma())) # discrete Gaussian in ZZ^n with stddev sigma_prime, yields random level-0 encodings DGSL_sigmap_ZZ = DGSL(ZZ**self.n, self.sigma_prime) self.D_sigmap_ZZ = lambda: self.Rq(list(DGSL_sigmap_ZZ())) # draw g repeatedly from a Gaussian distribution of Z^n (with param sigma) # until g^(-1) in QQ[x]/<x^n + 1> is small (< n^2) Sk = PolynomialRing(QQ, 'x') K = Sk.quotient_ring(Sk.ideal(x**self.n + 1)) while True: l = self.D_sigma() ginv_K = K(mod_near_poly(l, self.q))**(-1) ginv_size = vector(ginv_K).norm() if ginv_size < self.n**2: g = self.Rq(l) self.ginv = g**(-1) break # discrete Gaussian in I = <g>, yields random encodings of 0 short_g = vector(ZZ, mod_near_poly(g,self.q)) DGSL_sigmap_I = DGSL(short_g, self.sigma_prime) self.D_sigmap_I = lambda: self.Rq(list(DGSL_sigmap_I())) # compute zero-testing parameter p_zt # randomly draw h (in Rq) from a discrete Gaussian with param q^(1/2) self.h = self.Rq(list(DGSL(ZZ**self.n, round(sqrt(self.q)))())) # create p_zt self.p_zt = self.ginv * self.h * prod(z)
def elias_bound_asymp(delta,q): """ The asymptotic Elias bound for the information rate. This only makes sense when `0 < \delta < 1-1/q`. EXAMPLES:: sage: codes.bounds.elias_bound_asymp(1/4,2) 0.39912396330... """ r = 1-1/q return RDF((1-entropy(r-sqrt(r*(r-delta)), q)))
def _quotient_of_periods_to_twist(self, D): r""" For a fundamental discriminant `D` of a quadratic number field this computes the constant `\eta` such that `\sqrt{D}\cdot\Omega_{E_D}^{+} =\eta\cdot \Omega_E^{sign(D)}`. As in [MTT]_ page 40. This is either 1 or 2 unless the condition on the twist is not satisfied, e.g. if we are 'twisting back' to a semi-stable curve. REFERENCES: - [MTT] B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic analogues of the conjectures of Birch and Swinnerton-Dyer, Invertiones mathematicae 84, (1986), 1-48. .. note: No check on precision is made, so this may fail for huge `D`. EXAMPLES:: """ from sage.functions.all import sqrt # This function does not depend on p and could be moved out of this file but it is needed only here # Note that the number of real components does not change by twisting. if D == 1: return 1 if D > 1: Et = self._E.quadratic_twist(D) qt = Et.period_lattice().basis()[0] / self._E.period_lattice( ).basis()[0] qt *= sqrt(qt.parent()(D)) else: Et = self._E.quadratic_twist(D) qt = Et.period_lattice().basis()[0] / self._E.period_lattice( ).basis()[1].imag() qt *= sqrt(qt.parent()(-D)) verbose('the real approximation is %s' % qt) # we know from MTT that the result has a denominator 1 return QQ(int(round(8 * qt))) / 8
def plot_slope_field(f, xrange, yrange, **kwds): r""" ``plot_slope_field`` takes a function of two variables xvar and yvar (for instance, if the variables are `x` and `y`, take `f(x,y)`), and at representative points `(x_i,y_i)` between xmin, xmax, and ymin, ymax respectively, plots a line with slope `f(x_i,y_i)` (see below). ``plot_slope_field(f, (xvar, xmin, xmax), (yvar, ymin, ymax))`` EXAMPLES: A logistic function modeling population growth:: sage: x,y = var('x y') sage: capacity = 3 # thousand sage: growth_rate = 0.7 # population increases by 70% per unit of time sage: plot_slope_field(growth_rate*(1-y/capacity)*y, (x,0,5), (y,0,capacity*2)) Plot a slope field involving sin and cos:: sage: x,y = var('x y') sage: plot_slope_field(sin(x+y)+cos(x+y), (x,-3,3), (y,-3,3)) Plot a slope field using a lambda function:: sage: plot_slope_field(lambda x,y: x+y, (-2,2), (-2,2)) """ slope_options = {'headaxislength': 0, 'headlength': 0, 'pivot': 'middle'} slope_options.update(kwds) from sage.functions.all import sqrt from inspect import isfunction if isfunction(f): norm_inverse=lambda x,y: 1/sqrt(f(x,y)**2+1) f_normalized=lambda x,y: f(x,y)*norm_inverse(x,y) else: norm_inverse = 1/sqrt((f**2+1)) f_normalized=f*norm_inverse return plot_vector_field((norm_inverse, f_normalized), xrange, yrange, **slope_options)
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 _derivative_(self, z, m, diff_param): """ EXAMPLES:: sage: x,z = var('x,z') sage: elliptic_e(z, x).diff(z, 1) sqrt(-x*sin(z)^2 + 1) sage: elliptic_e(z, x).diff(x, 1) 1/2*(elliptic_e(z, x) - elliptic_f(z, x))/x """ if diff_param == 0: return sqrt(Integer(1) - m * sin(z)**Integer(2)) elif diff_param == 1: return (elliptic_e(z, m) - elliptic_f(z, m)) / (Integer(2) * m)
def standard_deviation(self): r""" The standard deviation of the discrete random variable. Let `S` be the probability space of `X` = self, with probability function `p`, and `E(X)` be the expectation of `X`. Then the standard deviation of `X` is defined to be .. MATH:: \sigma(X) = \sqrt{ \sum_{x \in S} p(x) (X(x) - E(x))^2} """ return sqrt(self.variance())
def _derivative_(self, z, m, diff_param): """ EXAMPLES:: sage: x,z = var('x,z') sage: elliptic_e(z, x).diff(z, 1) sqrt(-x*sin(z)^2 + 1) sage: elliptic_e(z, x).diff(x, 1) 1/2*(elliptic_e(z, x) - elliptic_f(z, x))/x """ if diff_param == 0: return sqrt(Integer(1) - m * sin(z) ** Integer(2)) elif diff_param == 1: return (elliptic_e(z, m) - elliptic_f(z, m)) / (Integer(2) * m)
def _quotient_of_periods_to_twist(self,D): r""" For a fundamental discriminant `D` of a quadratic number field this computes the constant `\eta` such that `\sqrt{D}\cdot\Omega_{E_D}^{+} =\eta\cdot \Omega_E^{sign(D)}`. As in [MTT]_ page 40. This is either 1 or 2 unless the condition on the twist is not satisfied, e.g. if we are 'twisting back' to a semi-stable curve. REFERENCES: - [MTT] B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic analogues of the conjectures of Birch and Swinnerton-Dyer, Invertiones mathematicae 84, (1986), 1-48. .. note: No check on precision is made, so this may fail for huge `D`. EXAMPLES:: """ from sage.functions.all import sqrt # This funciton does not depend on p and could be moved out of this file but it is needed only here # Note that the number of real components does not change by twisting. if D == 1: return 1 if D > 1: Et = self._E.quadratic_twist(D) qt = Et.period_lattice().basis()[0]/self._E.period_lattice().basis()[0] qt *= sqrt(qt.parent()(D)) else: Et = self._E.quadratic_twist(D) qt = Et.period_lattice().basis()[0]/self._E.period_lattice().basis()[1].imag() qt *= sqrt(qt.parent()(-D)) verbose('the real approximation is %s'%qt) # we know from MTT that the result has a denominator 1 return QQ(int(round(8*qt)))/8
def translation_standard_deviation(self, map): r""" The standard deviation of the translated discrete random variable `X \circ e`, where `X` = self and `e` = map. Let `S` be the probability space of `X` = self, with probability function `p`, and `E(X)` be the expectation of `X`. Then the standard deviation of `X` is defined to be .. MATH:: \sigma(X) = \sqrt{ \sum_{x \in S} p(x) (X(x) - E(x))^2} """ return sqrt(self.translation_variance(map))
def _qr(mat): r""" Compute the R matrix in QR decomposition using Housholder reflections. This is an adoption of the implementation in mpmath by Andreas Strombergson. """ CC = mat.base_ring() mat = copy(mat) m = mat.nrows() n = mat.ncols() cur_row = 0 for j in range(0, n): if all(mat[i, j].contains_zero() for i in xrange(cur_row + 1, m)): if not mat[cur_row, j].contains_zero(): cur_row += 1 continue s = sum((abs(mat[i, j]))**2 for i in xrange(cur_row, m)) if s.contains_zero(): raise RuntimeError( "Cannot handle imprecise sums of elements that are too precise" ) p = sqrt(s) if (s - p * mat[cur_row, j]).contains_zero(): raise RuntimeError( "Cannot handle imprecise sums of elements that are too precise" ) kappa = 1 / (s - p * mat[cur_row, j]) mat[cur_row, j] -= p for k in range(j + 1, n): y = sum(mat[i, j].conjugate() * mat[i, k] for i in xrange(cur_row, m)) * kappa for i in range(cur_row, m): mat[i, k] -= mat[i, j] * y mat[cur_row, j] = p for i in range(cur_row + 1, m): mat[i, j] = CC(0) cur_row += 1 return mat
def _derivative_(self, n, m, theta, phi, diff_param): r""" TESTS:: sage: n, m, theta, phi = var('n m theta phi') sage: spherical_harmonic(n, m, theta, phi).diff(theta) m*cot(theta)*spherical_harmonic(n, m, theta, phi) + sqrt(-(m + n + 1)*(m - n))*e^(-I*phi)*spherical_harmonic(n, m + 1, theta, phi) sage: spherical_harmonic(n, m, theta, phi).diff(phi) I*m*spherical_harmonic(n, m, theta, phi) """ if diff_param == 2: return m * cot(theta) * spherical_harmonic(n, m, theta, phi) + sqrt((n - m) * (n + m + 1)) * exp( -I * phi ) * spherical_harmonic(n, m + 1, theta, phi) if diff_param == 3: return I * m * spherical_harmonic(n, m, theta, phi) raise ValueError("only derivative with respect to theta or phi" " supported")
def _derivative_(self, n, m, theta, phi, diff_param): r""" TESTS:: sage: n, m, theta, phi = var('n m theta phi') sage: spherical_harmonic(n, m, theta, phi).diff(theta) m*cot(theta)*spherical_harmonic(n, m, theta, phi) + sqrt(-(m + n + 1)*(m - n))*e^(-I*phi)*spherical_harmonic(n, m + 1, theta, phi) sage: spherical_harmonic(n, m, theta, phi).diff(phi) I*m*spherical_harmonic(n, m, theta, phi) """ if diff_param == 2: return (m * cot(theta) * spherical_harmonic(n, m, theta, phi) + sqrt((n - m) * (n + m + 1)) * exp(-I * phi) * spherical_harmonic(n, m + 1, theta, phi)) if diff_param == 3: return I * m * spherical_harmonic(n, m, theta, phi) raise ValueError('only derivative with respect to theta or phi' ' supported')
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 _derivative_(self, x, diff_param=None): """ Derivative of erf function. EXAMPLES:: sage: erf(x).diff(x) 2*e^(-x^2)/sqrt(pi) TESTS: Check if :trac:`8568` is fixed:: sage: var('c,x') (c, x) sage: derivative(erf(c*x),x) 2*c*e^(-c^2*x^2)/sqrt(pi) sage: erf(c*x).diff(x)._maxima_init_() '((%pi)^(-1/2))*(_SAGE_VAR_c)*(exp(((_SAGE_VAR_c)^(2))*((_SAGE_VAR_x)^(2))*(-1)))*(2)' """ return 2 * exp(-x**2) / sqrt(pi)
def _derivative_(self, x, diff_param=None): """ Derivative of erf function. EXAMPLES:: sage: erf(x).diff(x) 2*e^(-x^2)/sqrt(pi) TESTS: Check if :trac:`8568` is fixed:: sage: var('c,x') (c, x) sage: derivative(erf(c*x),x) 2*c*e^(-c^2*x^2)/sqrt(pi) sage: erf(c*x).diff(x)._maxima_init_() '((%pi)^(-1/2))*(_SAGE_VAR_c)*(exp(((_SAGE_VAR_c)^(2))*((_SAGE_VAR_x)^(2))*(-1)))*(2)' """ return 2*exp(-x**2)/sqrt(pi)
def _qr(mat) : r""" Compute the R matrix in QR decomposition using Housholder reflections. This is an adoption of the implementation in mpmath by Andreas Strombergson. """ CC = mat.base_ring() mat = copy(mat) m = mat.nrows() n = mat.ncols() cur_row = 0 for j in range(0, n) : if all( mat[i,j].contains_zero() for i in xrange(cur_row + 1, m) ) : if not mat[cur_row,j].contains_zero() : cur_row += 1 continue s = sum( (abs(mat[i,j]))**2 for i in xrange(cur_row, m) ) if s.contains_zero() : raise RuntimeError( "Cannot handle imprecise sums of elements that are too precise" ) p = sqrt(s) if (s - p * mat[cur_row,j]).contains_zero() : raise RuntimeError( "Cannot handle imprecise sums of elements that are too precise" ) kappa = 1 / (s - p * mat[cur_row,j]) mat[cur_row,j] -= p for k in range(j + 1, n) : y = sum(mat[i,j].conjugate() * mat[i,k] for i in xrange(cur_row, m)) * kappa for i in range(cur_row, m): mat[i,k] -= mat[i,j] * y mat[cur_row,j] = p for i in range(cur_row + 1, m) : mat[i,j] = CC(0) cur_row += 1 return mat
def siegel_product(self, u): """ Computes the infinite product of local densities of the quadratic form for the number `u`. EXAMPLES:: sage: Q = DiagonalQuadraticForm(ZZ, [1,1,1,1]) sage: Q.theta_series(11) 1 + 8*q + 24*q^2 + 32*q^3 + 24*q^4 + 48*q^5 + 96*q^6 + 64*q^7 + 24*q^8 + 104*q^9 + 144*q^10 + O(q^11) sage: Q.siegel_product(1) 8 sage: Q.siegel_product(2) ## This one is wrong -- expect 24, and the higher powers of 2 don't work... =( 24 sage: Q.siegel_product(3) 32 sage: Q.siegel_product(5) 48 sage: Q.siegel_product(6) 96 sage: Q.siegel_product(7) 64 sage: Q.siegel_product(9) 104 sage: Q.local_density(2,1) 1 sage: M = 4; len([v for v in mrange([M,M,M,M]) if Q(v) % M == 1]) / M^3 1 sage: M = 16; len([v for v in mrange([M,M,M,M]) if Q(v) % M == 1]) / M^3 # long time (41s on sage.math, 2011) 1 sage: Q.local_density(2,2) 3/2 sage: M = 4; len([v for v in mrange([M,M,M,M]) if Q(v) % M == 2]) / M^3 3/2 sage: M = 16; len([v for v in mrange([M,M,M,M]) if Q(v) % M == 2]) / M^3 # long time (41s on sage.math, 2011) 3/2 TESTS:: sage: [1] + [Q.siegel_product(ZZ(a)) for a in range(1,11)] == Q.theta_series(11).list() True """ ## Protect u (since it fails often if it's an just an int!) u = ZZ(u) n = self.dim() d = self.det() ## ??? Warning: This is a factor of 2^n larger than it should be! ## DIAGNOSTIC verbose("n = " + str(n)) verbose("d = " + str(d)) verbose("In siegel_product: d = ", d, "\n"); ## Product of "bad" places to omit S = 2 * d * u ## DIAGNOSTIC verbose("siegel_product Break 1. \n") verbose(" u = ", u, "\n") ## Make the odd generic factors if ((n % 2) == 1): m = (n-1) / 2 d1 = fundamental_discriminant(((-1)**m) * 2*d * u) ## Replaced d by 2d here to compensate for the determinant f = abs(d1) ## gaining an odd power of 2 by using the matrix of 2Q instead ## of the matrix of Q. ## --> Old d1 = CoreDiscriminant((mpz_class(-1)^m) * d * u); ## Make the ratio of factorials factor: [(2m)! / m!] * prod_{i=1}^m (2*i-1) factor1 = 1 for i in range(1, m+1): factor1 *= 2*i - 1 for i in range(m+1, 2*m + 1): factor1 *= i genericfactor = factor1 * ((u / f) ** m) \ * QQ(sqrt((2 ** n) * f) / (u * d)) \ * abs(QuadraticBernoulliNumber(m, d1) / bernoulli(2*m)) ## DIAGNOSTIC verbose("siegel_product Break 2. \n") ## Make the even generic factor if ((n % 2) == 0): m = n / 2 d1 = fundamental_discriminant(((-1)**m) * d) f = abs(d1) ## DIAGNOSTIC #cout << " mpz_class(-1)^m = " << (mpz_class(-1)^m) << " and d = " << d << endl; #cout << " f = " << f << " and d1 = " << d1 << endl; genericfactor = m / QQ(sqrt(f*d)) \ * ((u/2) ** (m-1)) * (f ** m) \ / abs(QuadraticBernoulliNumber(m, d1)) \ * (2 ** m) ## This last factor compensates for using the matrix of 2*Q ##return genericfactor ## Omit the generic factors in S and compute them separately omit = 1 include = 1 S_divisors = prime_divisors(S) ## DIAGNOSTIC #cout << "\n S is " << S << endl; #cout << " The Prime divisors of S are :"; #PrintV(S_divisors); for p in S_divisors: Q_normal = self.local_normal_form(p) ## DIAGNOSTIC verbose(" p = " + str(p) + " and its Kronecker symbol (d1/p) = (" + str(d1) + "/" + str(p) + ") is " + str(kronecker_symbol(d1, p)) + "\n") omit *= 1 / (1 - (kronecker_symbol(d1, p) / (p**m))) ## DIAGNOSTIC verbose(" omit = " + str(omit) + "\n") verbose(" Q_normal is \n" + str(Q_normal) + "\n") verbose(" Q_normal = \n" + str(Q_normal)) verbose(" p = " + str(p) + "\n") verbose(" u = " +str(u) + "\n") verbose(" include = " + str(include) + "\n") include *= Q_normal.local_density(p, u) ## DIAGNOSTIC #cout << " Including the p = " << p << " factor: " << local_density(Q_normal, p, u) << endl; ## DIAGNSOTIC verbose(" --- Exiting loop \n") #// **************** Important ******************* #// Additional fix (only included for n=4) to deal #// with the power of 2 introduced at the real place #// by working with Q instead of 2*Q. This needs to #// be done for all other n as well... #/* #if (n==4) # genericfactor = 4 * genericfactor; #*/ ## DIAGNSOTIC #cout << endl; #cout << " generic factor = " << genericfactor << endl; #cout << " omit = " << omit << endl; #cout << " include = " << include << endl; #cout << endl; ## DIAGNSOTIC #// cout << "siegel_product Break 3. " << endl; ## Return the final factor (and divide by 2 if n=2) if (n == 2): return (genericfactor * omit * include / 2) else: return (genericfactor * omit * include)
def theta_series_degree_2(Q, prec): r""" Compute the theta series of degree 2 for the quadratic form Q. INPUT: - ``prec`` -- an integer. OUTPUT: dictionary, where: - keys are `{\rm GL}_2(\ZZ)`-reduced binary quadratic forms (given as triples of coefficients) - values are coefficients EXAMPLES:: sage: Q2 = QuadraticForm(ZZ, 4, [1,1,1,1, 1,0,0, 1,0, 1]) sage: S = Q2.theta_series_degree_2(10) sage: S[(0,0,2)] 24 sage: S[(1,0,1)] 144 sage: S[(1,1,1)] 192 AUTHORS: - Gonzalo Tornaria (2010-03-23) REFERENCE: - Raum, Ryan, Skoruppa, Tornaria, 'On Formal Siegel Modular Forms' (preprint) """ if Q.base_ring() != ZZ: raise TypeError("The quadratic form must be integral") if not Q.is_positive_definite(): raise ValueError("The quadratic form must be positive definite") try: X = ZZ(prec-1) # maximum discriminant except TypeError: raise TypeError("prec is not an integer") if X < -1: raise ValueError("prec must be >= 0") if X == -1: return {} V = ZZ ** Q.dim() H = Q.Hessian_matrix() t = cputime() max = int(floor((X+1)/4)) v_list = (Q.vectors_by_length(max)) # assume a>0 v_list = [[V(_) for _ in vs] for vs in v_list] # coerce vectors into V verbose("Computed vectors_by_length" , t) # Deal with the singular part coeffs = {(0,0,0):ZZ(1)} for i in range(1,max+1): coeffs[(0,0,i)] = ZZ(2) * len(v_list[i]) # Now deal with the non-singular part a_max = int(floor(sqrt(X/3))) for a in range(1, a_max + 1): t = cputime() c_max = int(floor((a*a + X)/(4*a))) for c in range(a, c_max + 1): for v1 in v_list[a]: v1_H = v1 * H def B_v1(v): return v1_H * v2 for v2 in v_list[c]: b = abs(B_v1(v2)) if b <= a and 4*a*c-b*b <= X: qf = (a,b,c) count = ZZ(4) if b == 0 else ZZ(2) coeffs[qf] = coeffs.get(qf, ZZ(0)) + count verbose("done a = %d" % a, t) return coeffs