def _eval_(self, n, x): """ EXAMPLES:: sage: y=var('y') sage: bessel_I(y,x) bessel_I(y, x) sage: bessel_I(0.0, 1.0) 1.26606587775201 sage: bessel_I(1/2, 1) sqrt(2)*sinh(1)/sqrt(pi) sage: bessel_I(-1/2, pi) sqrt(2)*cosh(pi)/pi """ if (not isinstance(n, Expression) and not isinstance(x, Expression) and (is_inexact(n) or is_inexact(x))): coercion_model = get_coercion_model() n, x = coercion_model.canonical_coercion(n, x) return self._evalf_(n, x, parent(n)) # special identities if n == Integer(1) / Integer(2): return sqrt(2 / (pi * x)) * sinh(x) elif n == -Integer(1) / Integer(2): return sqrt(2 / (pi * x)) * cosh(x) return None # leaves the expression unevaluated
def _eval_(self, a, z): """ EXAMPLES:: sage: struve_H(0,0) 0 sage: struve_H(pi,0) 0 sage: struve_H(-1/2,x) sqrt(2)*sqrt(1/(pi*x))*sin(x) sage: struve_H(1/2,-1) -sqrt(2)*sqrt(-1/pi)*(cos(1) - 1) sage: struve_H(1/2,pi) 2*sqrt(2)/pi sage: struve_H(2,x) struve_H(2, x) sage: struve_H(-3/2,x) -bessel_J(3/2, x) """ from sage.symbolic.ring import SR if z.is_zero() \ and (SR(a).is_numeric() or SR(a).is_constant()) \ and a.real() >= -1: return ZZ(0) if a == -Integer(1)/2: from sage.functions.trig import sin return sqrt(2/(pi*z)) * sin(z) if a == Integer(1)/2: from sage.functions.trig import cos return sqrt(2/(pi*z)) * (1-cos(z)) if a < 0 and not SR(a).is_integer() and SR(2*a).is_integer(): from sage.rings.rational_field import QQ n = (a*(-2) - 1)/2 return Integer(-1)**n * bessel_J(n+QQ(1)/2, z)
def platonic_dodecahedron(): r"""Produce a triple consisting of a polyhedral version of the platonic dodecahedron, the associated cone surface, and a ConeSurfaceToPolyhedronMap from the surface to the polyhedron. EXAMPLES:: sage: from flatsurf.geometry.polyhedra import platonic_dodecahedron sage: polyhedron,surface,surface_to_polyhedron = platonic_dodecahedron() sage: TestSuite(surface).run() r""" vertices=[] phi=AA(1+sqrt(5))/2 F=NumberField(phi.minpoly(),"phi",embedding=phi) phi=F.gen() for x in xrange(-1,3,2): for y in xrange(-1,3,2): for z in xrange(-1,3,2): vertices.append(vector(F,(x,y,z))) for x in xrange(-1,3,2): for y in xrange(-1,3,2): vertices.append(vector(F,(0,x*phi,y/phi))) vertices.append(vector(F,(y/phi,0,x*phi))) vertices.append(vector(F,(x*phi,y/phi,0))) scale=AA(2/sqrt(1+(phi-1)**2+(1/phi-1)**2)) p=Polyhedron(vertices=vertices) s,m = polyhedron_to_cone_surface(p,scaling_factor=scale) return p,s,m
def _eval_(self, a, z): """ EXAMPLES:: sage: struve_L(-2,0) struve_L(-2, 0) sage: struve_L(-1,0) 0 sage: struve_L(pi,0) 0 sage: struve_L(-1/2,x) sqrt(2)*sqrt(1/(pi*x))*sinh(x) sage: struve_L(1/2,1) sqrt(2)*(cosh(1) - 1)/sqrt(pi) sage: struve_L(2,x) struve_L(2, x) sage: struve_L(-3/2,x) -bessel_I(3/2, x) """ from sage.symbolic.ring import SR if z.is_zero() \ and (SR(a).is_numeric() or SR(a).is_constant()) \ and a.real() >= -1: return ZZ(0) if a == -Integer(1)/2: from sage.functions.hyperbolic import sinh return sqrt(2/(pi*z)) * sinh(z) if a == Integer(1)/2: from sage.functions.hyperbolic import cosh return sqrt(2/(pi*z)) * (cosh(z)-1) if a < 0 and not SR(a).is_integer() and SR(2*a).is_integer(): from sage.rings.rational_field import QQ n = (a*(-2) - 1)/2 return Integer(-1)**n * bessel_I(n+QQ(1)/2, z)
def get_s(self): """Returns a single value of s as required for the Elligator map while there may even be two of them, in which case the returned values is the smaller of the two """ try: return self._s except AttributeError: pass s = [] d = self.__E.get_d() if is_square(-d): c = ( 2*(d-1) + 4*sqrt(-d) ) / ( 2*(d+1) ) s_2 = 2/c if is_square(s_2): s.append(sqrt(s_2)) c = ( 2*(d-1) - 4*sqrt(-d) ) / ( 2*(d+1) ) s_2 = 2/c if is_square(s_2): s.append(sqrt(s_2)) if len(s) == 0: return None elif len(s) == 1: return s[0] else: if s[0] < s[1]: return s[0] else: return s[1]
def __eq__(self, other): r""" Return ``True`` if the isometries are the same and ``False`` otherwise. EXAMPLES:: sage: UHP = HyperbolicPlane().UHP() sage: A = UHP.get_isometry(identity_matrix(2)) sage: B = UHP.get_isometry(-identity_matrix(2)) sage: A == B True sage: HM = HyperbolicPlane().HM() sage: A = HM.random_isometry() sage: A == A True """ if not isinstance(other, HyperbolicIsometry): return False test_matrix = bool((self.matrix() - other.matrix()).norm() < EPSILON) if self.domain().is_isometry_group_projective(): A,B = self.matrix(), other.matrix() # Rename for simplicity m = self.matrix().ncols() A = A / sqrt(A.det(), m) # Normalized to have determinant 1 B = B / sqrt(B.det(), m) test_matrix = ((A - B).norm() < EPSILON or (A + B).norm() < EPSILON) return self.domain() is other.domain() and test_matrix
def _0f1(b, z): F12 = cosh(2 * sqrt(z)) F32 = sinh(2 * sqrt(z)) / (2 * sqrt(z)) if 2 * b == 1: return F12 if 2 * b == 3: return F32 if 2 * b > 3: return ((b - 2) * (b - 1) / z * (_0f1(b - 2, z) - _0f1(b - 1, z))) if 2 * b < 1: return (_0f1(b + 1, z) + z / (b * (b + 1)) * _0f1(b + 2, z)) raise ValueError
def SO21_to_SL2R(M): r""" A homomorphism from `SO(2, 1)` to `SL(2, \RR)`. Note that this is not the only homomorphism, but it is the only one that works in the context of the implemented 2D hyperbolic geometry models. EXAMPLES:: sage: from sage.geometry.hyperbolic_space.hyperbolic_coercion import SO21_to_SL2R sage: (SO21_to_SL2R(identity_matrix(3)) - identity_matrix(2)).norm() < 10**-4 True """ #################################################################### # SL(2,R) is the double cover of SO (2,1)^+, so we need to choose # # a lift. I have formulas for the absolute values of each entry # # a,b ,c,d of the lift matrix(2,[a,b,c,d]), but we need to choose # # one entry to be positive. I choose d for no particular reason, # # unless d = 0, then we choose c > 0. The basic strategy for this # # function is to find the linear map induced by the SO(2,1) # # element on the Lie algebra sl(2, R). This corresponds to the # # Adjoint action by a matrix A or -A in SL(2,R). To find which # # matrix let X,Y,Z be a basis for sl(2,R) and look at the images # # of X,Y,Z as well as the second and third standard basis vectors # # for 2x2 matrices (these are traceless, so are in the Lie # # algebra). These corresponds to AXA^-1 etc and give formulas # # for the entries of A. # #################################################################### (m_1,m_2,m_3,m_4,m_5,m_6,m_7,m_8,m_9) = M.list() d = sqrt(Integer(1)/Integer(2)*m_5 - Integer(1)/Integer(2)*m_6 - Integer(1)/Integer(2)*m_8 + Integer(1)/Integer(2)*m_9) if M.det() > 0: # EPSILON? det_sign = 1 elif M.det() < 0: # EPSILON? det_sign = -1 if d > 0: # EPSILON? c = (-Integer(1)/Integer(2)*m_4 + Integer(1)/Integer(2)*m_7)/d b = (-Integer(1)/Integer(2)*m_2 + Integer(1)/Integer(2)*m_3)/d ad = det_sign*1 + b*c # ad - bc = pm 1 a = ad/d else: # d is 0, so we make c > 0 c = sqrt(-Integer(1)/Integer(2)*m_5 - Integer(1)/Integer(2)*m_6 + Integer(1)/Integer(2)*m_8 + Integer(1)/Integer(2)*m_9) d = (-Integer(1)/Integer(2)*m_4 + Integer(1)/Integer(2)*m_7)/c # d = 0, so ad - bc = -bc = pm 1. b = - (det_sign*1)/c a = (Integer(1)/Integer(2)*m_4 + Integer(1)/Integer(2)*m_7)/b A = matrix(2, [a, b, c, d]) return A
def RankingScale_USAU_2013(): r""" EXAMPLES:: sage: from slabbe.ranking_scale import RankingScale_USAU_2013 sage: R = RankingScale_USAU_2013() sage: R.table() Position Serie 1500 Serie 1000 Serie 500 Serie 250 1 1500 1000 500 250 2 1366 911 455 228 3 1252 835 417 209 4 1152 768 384 192 5 1061 708 354 177 6 979 653 326 163 7 903 602 301 151 8 832 555 278 139 9 767 511 256 128 10 706 471 236 118 11 648 432 217 109 12 595 397 199 100 13 544 363 182 91 14 497 332 166 83 15 452 302 151 76 16 410 274 137 69 17 371 248 124 62 18 334 223 112 56 19 299 199 100 50 20 266 177 89 45 21 235 157 79 40 22 206 137 69 35 23 178 119 60 30 24 152 102 51 26 25 128 86 43 22 26 106 71 36 18 27 85 57 29 15 28 66 44 22 12 29 47 32 16 9 30 31 21 11 6 31 15 10 6 3 32 1 1 1 1 """ L1500 = [0] + discrete_curve(32, 1500, K=1, R=sqrt(2), base=e) L1000 = [0] + discrete_curve(32, 1000, K=1, R=sqrt(2), base=e) L500 = [0] + discrete_curve(32, 500, K=1, R=sqrt(2), base=e) L250 = [0] + discrete_curve(32, 250, K=1, R=sqrt(2), base=e) scales = L1500, L1000, L500, L250 names = ['Serie 1500', 'Serie 1000', 'Serie 500', 'Serie 250'] return RankingScale(names, scales)
def show(self, show_hyperboloid=True, **graphics_options): r""" Plot ``self``. EXAMPLES:: sage: from sage.geometry.hyperbolic_space.hyperbolic_geodesic import * sage: g = HyperbolicPlane().HM().random_geodesic() sage: g.show() Graphics3d Object """ x = SR.var('x') opts = self.graphics_options() opts.update(graphics_options) v1, u2 = [vector(k.coordinates()) for k in self.endpoints()] # Lorentzian Gram Shmidt. The original vectors will be # u1, u2 and the orthogonal ones will be v1, v2. Except # v1 = u1, and I don't want to declare another variable, # hence the odd naming convention above. # We need the Lorentz dot product of v1 and u2. v1_ldot_u2 = u2[0]*v1[0] + u2[1]*v1[1] - u2[2]*v1[2] v2 = u2 + v1_ldot_u2 * v1 v2_norm = sqrt(v2[0]**2 + v2[1]**2 - v2[2]**2) v2 = v2 / v2_norm v2_ldot_u2 = u2[0]*v2[0] + u2[1]*v2[1] - u2[2]*v2[2] # Now v1 and v2 are Lorentz orthogonal, and |v1| = -1, |v2|=1 # That is, v1 is unit timelike and v2 is unit spacelike. # This means that cosh(x)*v1 + sinh(x)*v2 is unit timelike. hyperbola = cosh(x)*v1 + sinh(x)*v2 endtime = arcsinh(v2_ldot_u2) from sage.plot.plot3d.all import parametric_plot3d pic = parametric_plot3d(hyperbola, (x, 0, endtime), **graphics_options) if show_hyperboloid: pic += self._model.get_background_graphic() return pic
def cmp_ir(self,z): """ returns -1 for left, 0 for in, and 1 for right from initial region cut line is on the north ray from pfp. Works only for real x0. """ pfp = self.pfp x0 = self.x0 if x0 > 0.5: print z,abs(z) if real(z) >= real(pfp) and abs(z) < abs(pfp): return 0 if real(z) < real(pfp): return -1 if real(z) > real(pfp): return 1 else: if imag(z) > imag(pfp): if real(z) > real(pfp): return 1 if real(z) < real(pfp): return -1 if real(z) < real(pfp) and real(z) > log(real(pfp)) + log(sqrt(1+tan(imag(z))**2)): return 0 if real(z) > real(pfp): return 1 if real(z) < real(pfp): return -1
def perpendicular_bisector(self): #UHP r""" Return the perpendicular bisector of the hyperbolic geodesic ``self`` if that geodesic has finite length. EXAMPLES:: sage: UHP = HyperbolicPlane().UHP() sage: g = UHP.random_geodesic() sage: h = g.perpendicular_bisector() sage: c = lambda x: x.coordinates() sage: bool(c(g.intersection(h)[0]) - c(g.midpoint()) < 10**-9) True Infinite geodesics cannot be bisected:: sage: UHP.get_geodesic(0, 1).perpendicular_bisector() Traceback (most recent call last): ... ValueError: the length must be finite """ if self.length() == infinity: raise ValueError("the length must be finite") start = self._start.coordinates() d = self._model._dist_points(start, self._end.coordinates()) / 2 S = self.complete()._to_std_geod(start) T1 = matrix([[exp(d/2), 0], [0, exp(-d/2)]]) s2 = sqrt(2) * 0.5 T2 = matrix([[s2, -s2], [s2, s2]]) isom_mtrx = S.inverse() * (T1 * T2) * S # We need to clean this matrix up. if (isom_mtrx - isom_mtrx.conjugate()).norm() < 5*EPSILON: # Imaginary part is small. isom_mtrx = (isom_mtrx + isom_mtrx.conjugate()) / 2 # Set it to its real part. H = self._model.get_isometry(isom_mtrx) return self._model.get_geodesic(H(self._start), H(self._end))
def solve_degree2_to_integer_range(a,b,c): r""" Returns the greatest integer range `[i_1, i_2]` such that `i_1 > x_1` and `i_2 < x_2` where `x_1, x_2` are the two zeroes of the equation in `x`: `ax^2+bx+c=0`. If there is no real solution to the equation, it returns an empty range with negative coefficients. INPUT: - ``a``, ``b`` and ``c`` -- coefficients of a second degree equation, ``a`` being the coefficient of the higher degree term. EXAMPLES:: sage: from sage.coding.guruswami_sudan.utils import solve_degree2_to_integer_range sage: solve_degree2_to_integer_range(1, -5, 1) (1, 4) If there is no real solution:: sage: solve_degree2_to_integer_range(50, 5, 42) (-2, -1) """ D = b**2 - 4*a*c if D < 0: return (-2,-1) sD = float(sqrt(D)) minx, maxx = (-b-sD)/2.0/a , (-b+sD)/2.0/a mini, maxi = (ligt(minx), gilt(maxx)) if mini > maxi: return (-2,-1) else: return (mini,maxi)
def platonic_icosahedron(): r"""Produce a triple consisting of a polyhedral version of the platonic icosahedron, the associated cone surface, and a ConeSurfaceToPolyhedronMap from the surface to the polyhedron. EXAMPLES:: sage: from flatsurf.geometry.polyhedra import platonic_icosahedron sage: polyhedron,surface,surface_to_polyhedron = platonic_icosahedron() sage: TestSuite(surface).run() r""" vertices=[] phi=AA(1+sqrt(5))/2 F=NumberField(phi.minpoly(),"phi",embedding=phi) phi=F.gen() for i in xrange(3): for s1 in xrange(-1,3,2): for s2 in xrange(-1,3,2): p=3*[None] p[i]=s1*phi p[(i+1)%3]=s2 p[(i+2)%3]=0 vertices.append(vector(F,p)) p=Polyhedron(vertices=vertices) s,m = polyhedron_to_cone_surface(p) return p,s,m
def _test_representation(self, **options): """ Check (on some elements) that ``self`` is a representation of the given semigroup. EXAMPLES:: sage: G = groups.permutation.Dihedral(4) sage: R = G.regular_representation() sage: R._test_representation() sage: G = CoxeterGroup(['A',4,1], base_ring=ZZ) sage: M = CombinatorialFreeModule(QQ, ['v']) sage: from sage.modules.with_basis.representation import Representation sage: on_basis = lambda g,m: M.term(m, (-1)**g.length()) sage: R = Representation(G, M, on_basis, side="right") sage: R._test_representation(max_runs=500) """ from sage.functions.other import sqrt tester = self._tester(**options) S = tester.some_elements() L = [] max_len = int(sqrt(tester._max_runs)) + 1 for i,x in enumerate(self._semigroup): L.append(x) if i >= max_len: break for x in L: for y in L: for elt in S: if self._left_repr: tester.assertEqual(x*(y*elt), (x*y)*elt) else: tester.assertEqual((elt*y)*x, elt*(y*x))
def random_point(self): while(1): x = self.base_ring().random_element() test = (x**2 - 1)/(self._d*(x**2) - 1) if is_square(test): y = sqrt(test) return self([x,y,1])
def iter_positive_forms_with_content(self) : if self.__disc is infinity : raise ValueError, "infinity is not a true filter index" if self.__reduced : for a in xrange(1,isqrt(self.__disc // 3) + 1) : for b in xrange(a+1) : g = gcd(a, b) for c in xrange(a, (b**2 + (self.__disc - 1))//(4*a) + 1) : yield (a,b,c), gcd(g,c) else : maxtrace = floor(5*self.__disc / 15 + sqrt(self.__disc)/2) for a in xrange(1, maxtrace + 1) : for c in xrange(1, maxtrace - a + 1) : g = gcd(a,c) Bu = isqrt(4*a*c - 1) di = 4*a*c - self.__disc if di >= 0 : Bl = isqrt(di) + 1 else : Bl = 0 for b in xrange(-Bu, -Bl + 1) : yield (a,b,c), gcd(g,b) for b in xrange(Bl, Bu + 1) : yield (a,b,c), gcd(g,b) #! if self.__reduced raise StopIteration
def cmp_ir(self,z): """ returns -1 for left, 0 for in, and 1 for right from initial region cut line is on the north ray from L. """ L = self.L x0 = self.x0 if x0 > 0.5: if real(z) > real(L) and abs(z) < abs(L): return 0 if real(z) < real(L): return -1 if real(z) > real(L): return 1 else: if imag(z) > imag(L): if real(z) > real(L): return 1 if real(z) < real(L): return -1 if real(z) < real(L) and real(z) > log(real(L)) + log(sqrt(1+tan(imag(z))**2)): return 0 if real(z) > real(L): return 1 if real(z) < real(L): return -1
def RankingScale_CQU4_2011(): r""" EXEMPLES:: sage: from slabbe.ranking_scale import RankingScale_CQU4_2011 sage: R = RankingScale_CQU4_2011() sage: R.table() Position Grand Chelem Mars Attaque La Flotte Petit Chelem 1 1000 1000 800 400 2 938 938 728 355 3 884 884 668 317 4 835 835 614 285 5 791 791 566 256 6 750 750 522 230 7 711 711 482 206 8 675 675 444 184 9 641 641 409 164 10 609 609 377 146 ... 95 0 11 0 0 96 0 10 0 0 97 0 9 0 0 98 0 8 0 0 99 0 7 0 0 100 0 6 0 0 101 0 4 0 0 102 0 3 0 0 103 0 2 0 0 104 0 1 0 0 """ from sage.rings.integer_ring import ZZ serieA = [0] + discrete_curve(50, 1000, K=1, R=sqrt(2), base=e) #Movember, Bye Bye, Cdf, MA la_flotte = [0] + discrete_curve(32, 800, K=1, R=sqrt(2), base=e) # la flotte serieB = [0] + discrete_curve(24, 400, K=1, R=sqrt(2), base=e) # october fest, funenuf, la viree nb_ma = 104 pivot_x = 40 pivot_y = serieA[pivot_x] slope = (1-pivot_y) / (nb_ma-pivot_x) L = [pivot_y + slope * (p-pivot_x) for p in range(pivot_x, nb_ma+1)] L = [ZZ(round(_)) for _ in L] mars_attaque = serieA[:pivot_x] + L scales = serieA, mars_attaque, la_flotte, serieB names = ["Grand Chelem", "Mars Attaque", "La Flotte", "Petit Chelem"] return RankingScale(names, scales)
def _2f1(a, b, c, z): """ Evaluation of 2F1(a, b; c; z), assuming a, b, c positive integers or half-integers """ if b == c: return (1 - z) ** (-a) if a == c: return (1 - z) ** (-b) if a == 0 or b == 0: return Integer(1) if a > b: a, b = b, a if b >= 2: F1 = _2f1(a, b - 1, c, z) F2 = _2f1(a, b - 2, c, z) q = (b - 1) * (z - 1) return (((c - 2 * b + 2 + (b - a - 1) * z) * F1 + (b - c - 1) * F2) / q) if c > 2: # how to handle this case? if a - c + 1 == 0 or b - c + 1 == 0: raise NotImplementedError F1 = _2f1(a, b, c - 1, z) F2 = _2f1(a, b, c - 2, z) r1 = (c - 1) * (2 - c - (a + b - 2 * c + 3) * z) r2 = (c - 1) * (c - 2) * (1 - z) q = (a - c + 1) * (b - c + 1) * z return (r1 * F1 + r2 * F2) / q if (a, b, c) == (R12, 1, 2): return (2 - 2 * sqrt(1 - z)) / z if (a, b, c) == (1, 1, 2): return -log(1 - z) / z if (a, b, c) == (1, R32, R12): return (1 + z) / (1 - z) ** 2 if (a, b, c) == (1, R32, 2): return 2 * (1 / sqrt(1 - z) - 1) / z if (a, b, c) == (R32, 2, R12): return (1 + 3 * z) / (1 - z) ** 3 if (a, b, c) == (R32, 2, 1): return (2 + z) / (2 * (sqrt(1 - z) * (1 - z) ** 2)) if (a, b, c) == (2, 2, 1): return (1 + z) / (1 - z) ** 3 raise NotImplementedError
def _eval_(self, n, x): """ EXAMPLES:: sage: y=var('y') sage: bessel_I(y,x) bessel_I(y, x) sage: bessel_I(0.0, 1.0) 1.26606587775201 sage: bessel_I(1/2, 1) sqrt(2)*sinh(1)/sqrt(pi) sage: bessel_I(-1/2, pi) sqrt(2)*cosh(pi)/pi """ # special identities if n == Integer(1) / Integer(2): return sqrt(2 / (pi * x)) * sinh(x) elif n == -Integer(1) / Integer(2): return sqrt(2 / (pi * x)) * cosh(x)
def n_random_points(self,n): v = [] while(len(v) < n): x = self.base_ring().random_element() test = (x**2 - 1)/(self._d*(x**2) - 1) if is_square(test): y = sqrt(test) v.append(self([x,y,1])) v.sort() return v
def __init__(self, n, instance='key', m=None): """ Construct LWE instance parameterised by security parameter ``n`` where all other parameters are chosen as in [CGW2013]_. INPUT: - ``n`` - security parameter (integer >= 89) - ``instance`` - one of - "key" - the LWE-instance that hides the secret key is generated - "encrypt" - the LWE-instance that hides the message is generated (default: ``key``) - ``m`` - number of allowed samples or ``None`` in which case ``m`` is chosen as in [CGW2013]_. (default: ``None``) EXAMPLES:: sage: from sage.crypto.lwe import UniformNoiseLWE sage: UniformNoiseLWE(89) LWE(89, 154262477, UniformSampler(0, 351), 'noise', 131) sage: UniformNoiseLWE(89, instance='encrypt') LWE(131, 154262477, UniformSampler(0, 497), 'noise', 181) """ if n<89: raise TypeError("Parameter too small") n2 = n C = 4/sqrt(2*pi) kk = floor((n2-2*log(n2, 2)**2)/5) n1 = floor((3*n2-5*kk)/2) ke = floor((n1-2*log(n1, 2)**2)/5) l = floor((3*n1-5*ke)/2)-n2 sk = ceil((C*(n1+n2))**(3/2)) se = ceil((C*(n1+n2+l))**(3/2)) q = next_prime(max(ceil((4*sk)**((n1+n2)/n1)), ceil((4*se)**((n1+n2+l)/(n2+l))), ceil(4*(n1+n2)*se*sk+4*se+1))) if kk<=0: raise TypeError("Parameter too small") if instance == 'key': D = UniformSampler(0, sk-1) if m is None: m = n1 LWE.__init__(self, n=n2, q=q, D=D, secret_dist='noise', m=m) elif instance == 'encrypt': D = UniformSampler(0, se-1) if m is None: m = n2+l LWE.__init__(self, n=n1, q=q, D=D, secret_dist='noise', m=m) else: raise TypeError("Parameter instance=%s not understood."%(instance))
def image_coordinates(self, x): """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``. EXAMPLES:: sage: KM = HyperbolicPlane().KM() sage: UHP = HyperbolicPlane().UHP() sage: phi = UHP.coerce_map_from(KM) sage: phi.image_coordinates((0, 0)) I sage: phi.image_coordinates((0, 1)) +Infinity """ if tuple(x) == (0, 1): return infinity return (-x[0]/(x[1] - 1) + I*(-(sqrt(-x[0]**2 - x[1]**2 + 1) - x[0]**2 - x[1]**2 + 1) / ((x[1] - 1)*sqrt(-x[0]**2 - x[1]**2 + 1) + x[1] - 1)))
def __init__(self, n, delta=0.01, m=None): """ Construct LWE instance parameterised by security parameter ``n`` where the modulus ``q`` and the ``stddev`` of the noise is chosen as in [LP2011]_. INPUT: - ``n`` - security parameter (integer > 0) - ``delta`` - error probability per symbol (default: 0.01) - ``m`` - number of allowed samples or ``None`` in which case ``m=2*n + 128`` as in [LP2011]_ (default: ``None``) EXAMPLES:: sage: from sage.crypto.lwe import LindnerPeikert sage: LindnerPeikert(n=20) LWE(20, 2053, Discrete Gaussian sampler over the Integers with sigma = 3.600954 and c = 0, 'noise', 168) """ if m is None: m = 2*n + 128 # Find c>=1 such that c*exp((1-c**2)/2))**(2*n) == 2**-40 # (c*exp((1-c**2)/2))**(2*n) == 2**-40 # log((c*exp((1-c**2)/2))**(2*n)) == -40*log(2) # (2*n)*log(c*exp((1-c**2)/2)) == -40*log(2) # 2*n*(log(c)+log(exp((1-c**2)/2))) == -40*log(2) # 2*n*(log(c)+(1-c**2)/2) == -40*log(2) # 2*n*log(c)+n*(1-c**2) == -40*log(2) # 2*n*log(c)+n*(1-c**2) + 40*log(2) == 0 c = SR.var('c') c = find_root(2*n*log(c)+n*(1-c**2) + 40*log(2) == 0, 1, 10) # Upper bound on s**2/t s_t_bound = (sqrt(2) * pi / c / sqrt(2*n*log(2/delta))).n() # Interpretation of "choose q just large enough to allow for a Gaussian parameter s>=8" in [LP2011]_ q = next_prime(floor(2**round(log(256 / s_t_bound, 2)))) # Gaussian parameter as defined in [LP2011]_ s = sqrt(s_t_bound*floor(q/4)) # Transform s into stddev stddev = s/sqrt(2*pi.n()) D = DiscreteGaussianDistributionIntegerSampler(stddev) LWE.__init__(self, n=n, q=q, D=D, secret_dist='noise', m=m)
def _derivative_(self, a, z, diff_param=None): """ EXAMPLES:: sage: diff(struve_H(3/2,x),x) -1/2*sqrt(2)*sqrt(1/(pi*x))*(cos(x) - 1) + 1/16*sqrt(2)*x^(3/2)/sqrt(pi) - 1/2*struve_H(5/2, x) """ if diff_param == 0: raise ValueError("cannot differentiate struve_H in the first parameter") from sage.functions.other import sqrt, gamma return (z**a/(sqrt(pi)*2**a*gamma(a+Integer(3)/Integer(2)))-struve_H(a+1,z)+struve_H(a-1,z))/2
def compute_kappa_lambda_Q_from_mu_nu(self): """ Computes some kappa, lambda and Q from mu, nu, which might not be optimal for computational purposes """ try: from sage.functions.other import sqrt from sage.rings.all import Integer from math import pi self.Q_fe = float(sqrt(Integer(self.level))/2.**len(self.nu_fe)/pi**(len(self.mu_fe)/2.+len(self.nu_fe))) self.kappa_fe = [.5 for m in self.mu_fe] + [1. for n in self.nu_fe] self.lambda_fe = [m/2. for m in self.mu_fe] + [n for n in self.nu_fe] except Exception as e: raise Exception("Expecting a mu and a nu to be defined"+str(e))
def __init__(self,dic,repr=None): self._reduction_dic = dic for key in dic.keys(): self[key] = copy(dic[key]) self._dim = int(sqrt(len(self.keys()))) self._repr = repr if self._repr is None: self._repr = "This is a matrix reduction object: description missing" elif type(self._repr)!=str: raise ValueError, "Fifth input must be descriptive string or empty argument." else: self._repr = "This is a matrix reduction object: " + str(self._repr)
def _derivative_(self, a, z, diff_param=None): """ EXAMPLES:: sage: diff(struve_L(1,x),x) 1/3*x/pi - 1/2*struve_L(2, x) + 1/2*struve_L(0, x) """ if diff_param == 0: raise ValueError("cannot differentiate struve_L in the first parameter") from sage.functions.other import sqrt, gamma return (z**a/(sqrt(pi)*2**a*gamma(a+Integer(3)/Integer(2)))-struve_L(a+1,z)+struve_L(a-1,z))/2
def is_squareSum(x): """ Determine whether an integer is a sum of two squares. """ if x.is_prime(): return x == 2 or x % 4 == 1 i, j, y = -1, 0, x while j <= y: if sqrt(y).is_integer(): return True i += 2 j += i y -= i return False
def _eval_(self, n, x): """ EXAMPLES:: sage: bessel_K(1,0) bessel_K(1, 0) sage: bessel_K(1.0, 0.0) +infinity sage: bessel_K(-1, 1).n(128) 0.60190723019723457473754000153561733926 """ # special identity if n == Integer(1) / Integer(2) and x > 0: return sqrt(pi / 2) * exp(-x) * x**(-Integer(1) / Integer(2))
def _eval_(self, n, x): """ EXAMPLES:: sage: bessel_K(1,0) bessel_K(1, 0) sage: bessel_K(1.0, 0.0) +infinity sage: bessel_K(-1, 1).n(128) 0.60190723019723457473754000153561733926 """ # special identity if n == Integer(1) / Integer(2) and x > 0: return sqrt(pi / 2) * exp(-x) * x ** (-Integer(1) / Integer(2))
def gghlite_attacks(params, rerand=False): """ Given parameters for a GGHLite-like problem instance estimate how long two lattice attacks would take. The two attacks are: - finding a short multiple of ‘g‘. - finding short ‘b_0/b_1‘ from ‘x_0/x_1‘ :param params: parameters for a GGHLite-like graded encoding scheme :returns: cost estimate for lattice attacks """ n = params["n"] q = params["q"] sigma = params[u"σ"] sigma_p = params[u"σ’"] # NTRU attack nt = OrderedDict() nt["n"] = n nt[u"τ"] = RR(_sage_const_0p3) base = (sqrt(q) / (sqrt(_sage_const_2) * sqrt(n) * sigma_p * nt[u"τ"])) if rerand: base = base / sigma nt[u"δ_0"] = RR(base**(_sage_const_1 / (_sage_const_2 * n))) nt = complete_lattice_attack(nt) return nt
def translation_length(self): #UHP r""" For hyperbolic elements, return the translation length; otherwise, raise a ``ValueError``. EXAMPLES:: sage: UHP = HyperbolicPlane().UHP() sage: UHP.get_isometry(matrix(2,[2,0,0,1/2])).translation_length() 2*arccosh(5/4) :: sage: H = UHP.isometry_from_fixed_points(-1,1) sage: p = UHP.get_point(exp(i*7*pi/8)) sage: Hp = H(p) sage: bool((UHP.dist(p, Hp) - H.translation_length()) < 10**-9) True """ d = sqrt(self._matrix.det()**2) tau = sqrt((self._matrix / sqrt(d)).trace()**2) if self.classification() in ['hyperbolic', 'oriention-reversing hyperbolic']: return 2 * arccosh(tau/2) raise TypeError("translation length is only defined for hyperbolic transformations")
def __init__(self, N, delta=0.01, m=None): """ Construct a Ring-LWE oracle in dimension ``n=phi(N)`` where the modulus ``q`` and the ``stddev`` of the noise is chosen as in [LP11]_. INPUT: - ``N`` - index of cyclotomic polynomial (integer > 0, must be power of 2) - ``delta`` - error probability per symbol (default: 0.01) - ``m`` - number of allowed samples or ``None`` in which case ``3*n`` is used (default: ``None``) EXAMPLES:: sage: from sage.crypto.lwe import RingLindnerPeikert sage: RingLindnerPeikert(N=16) RingLWE(16, 1031, Discrete Gaussian sampler for polynomials of degree < 8 with σ=2.803372 in each component, x^8 + 1, 'noise', 24) """ n = euler_phi(N) if m is None: m = 3*n # Find c>=1 such that c*exp((1-c**2)/2))**(2*n) == 2**-40 # i.e c>=1 such that 2*n*log(c)+n*(1-c**2) + 40*log(2) == 0 c = SR.var('c') c = find_root(2*n*log(c)+n*(1-c**2) + 40*log(2) == 0, 1, 10) # Upper bound on s**2/t s_t_bound = (sqrt(2) * pi / c / sqrt(2*n*log(2/delta))).n() # Interpretation of "choose q just large enough to allow for a Gaussian parameter s>=8" in [LP11]_ q = next_prime(floor(2**round(log(256 / s_t_bound, 2)))) # Gaussian parameter as defined in [LP11]_ s = sqrt(s_t_bound*floor(q/4)) # Transform s into stddev stddev = s/sqrt(2*pi.n()) D = DiscreteGaussianDistributionPolynomialSampler(ZZ['x'], n, stddev) RingLWE.__init__(self, N=N, q=q, D=D, poly=None, secret_dist='noise', m=m)
def compute_kappa_lambda_Q_from_mu_nu(self): """ Computes some kappa, lambda and Q from mu, nu, which might not be optimal for computational purposes """ try: from sage.functions.other import sqrt from sage.rings.all import Integer from math import pi self.Q_fe = float( sqrt(Integer(self.level)) / 2.**len(self.nu_fe) / pi**(len(self.mu_fe) / 2. + len(self.nu_fe))) self.kappa_fe = [.5 for m in self.mu_fe] + [1. for n in self.nu_fe] self.lambda_fe = [m / 2. for m in self.mu_fe] + [n for n in self.nu_fe] except Exception as e: raise Exception("Expecting a mu and a nu to be defined" + str(e))
def is_quasigeometric(self): """ Decide whether the binary recurrence sequence is degenerate and similar to a geometric sequence, i.e. the union of multiple geometric sequences, or geometric after term ``u0``. If `\\alpha/\\beta` is a `k` th root of unity, where `k>1`, then necessarily `k = 2, 3, 4, 6`. Then `F = [[0,1],[c,b]` is diagonalizable, and `F^k = [[\\alpha^k, 0], [0,\\beta^k]]` is scaler matrix. Thus for all values of `j` mod `k`, the `j` mod `k` terms of `u_n` form a geometric series. If `\\alpha` or `\\beta` is zero, this implies that `c=0`. This is the case when `F` is singular. In this case, `u_1, u_2, u_3, ...` is geometric. EXAMPLES:: sage: S = BinaryRecurrenceSequence(0,1) sage: [S(i) for i in range(10)] [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] sage: S.is_quasigeometric() True sage: R = BinaryRecurrenceSequence(3,0) sage: [R(i) for i in range(10)] [0, 1, 3, 9, 27, 81, 243, 729, 2187, 6561] sage: R.is_quasigeometric() True """ #First test if F is singular... i.e. beta = 0 if self.c == 0: return True #Otherwise test if alpha/beta is a root of unity that is not 1 else: if (self.b**2 + 4 * self.c) != 0: #thus alpha/beta != 1 if (self.b**2 + 4 * self.c).is_square(): A = sqrt((self.b**2 + 4 * self.c)) else: K = QuadraticField((self.b**2 + 4 * self.c), 'x') A = K.gen() if ((self.b + A) / (self.b - A))**(6) == 1: return True return False
def weight_class(length, weight): r""" Return the weight class corresponding to a given length and weight. The length is the length of the truth table of a Boolean function. The weight is the Hamming weight of the Boolean function. INPUT: - ``length`` -- positive integer: - ``weight`` -- positive integer: the given Hamming weight. OUTPUT: An integer representing the weight class corresponding to ``length`` and ``weight``. EXAMPLES: :: sage: from boolean_cayley_graphs.weight_class import weight_class sage: weight_class(4,1) 0 sage: weight_class(16,10) 1 sage: weight_class(16,6) 0 sage: weight_class(64,36) 1 sage: weight_class(63,37) 1 sage: weight_class(65,35) 0 .. NOTE:: The weight class really only makes sense for bent functions, for which the weight class is either 0 or 1 [Leo2017]_. REFERENCES: Leopardi [Leo2017]_ Section 2.2. """ sqrtlength = sqrt(length) return int(((weight*2)/sqrtlength - sqrtlength + 1) / 2)
def johnson_radius(n, d): r""" Returns the Johnson-radius for the code length `n` and the minimum distance `d`. The Johnson radius is defined as `n - \sqrt(n(n-d))`. INPUT: - ``n`` -- an integer, the length of the code - ``d`` -- an integer, the minimum distance of the code EXAMPLES:: sage: sage.coding.guruswami_sudan.utils.johnson_radius(250, 181) -5*sqrt(690) + 250 """ return n - sqrt(n * (n - d))
def lift(self, x): """ INPUT: - ``x`` -- an element of ``self`` Lifts ``x`` to the ambient space for ``self``, as per :meth:`Sets.Subquotients.ParentMethods.lift() <sage.categories.sets_cat.Sets.Subquotients.ParentMethods.lift>`. EXAMPLES:: sage: C = FiniteEnumeratedSets().IsomorphicObjects().example(); C The image by some isomorphism of An example of a finite enumerated set: {1,2,3} sage: C.lift(9) 3 """ return sqrt(x)
def platonic_tetrahedron(): r"""Produce a triple consisting of a polyhedral version of the platonic tetrahedron, the associated cone surface, and a ConeSurfaceToPolyhedronMap from the surface to the polyhedron. EXAMPLES:: sage: from flatsurf.geometry.polyhedra import platonic_tetrahedron sage: polyhedron,surface,surface_to_polyhedron = platonic_tetrahedron() sage: TestSuite(surface).run() r""" vertices = [] for x in range(-1, 3, 2): for y in range(-1, 3, 2): vertices.append(vector(QQ, (x, y, x * y))) p = Polyhedron(vertices=vertices) s, m = polyhedron_to_cone_surface(p, scaling_factor=AA(1 / sqrt(2))) return p, s, m
def normalize_cusps(self, areas=None): """ Scale cusp so that they have the given target area. Without argument, each cusp is scaled to have area 1. If the argument is a number, scale each cusp to have that area. If the argument is an array, scale each cusp by the respective entry in the array. """ current_areas = self.cusp_areas() if not areas: areas = [1 for area in current_areas] elif not isinstance(areas, list): areas = [areas for area in current_areas] scales = [ sqrt(area / current_area) for area, current_area in zip(areas, current_areas) ] self.scale_cusps(scales)
def evaluate_mu(self, affine_parameter, solution_key=None): r""" Compute the mass parameter `\mu` at a given value of the affine parameter `\lambda`. INPUT: - ``affine_parameter`` -- value of the affine parameter `\lambda` - ``solution_key`` -- (default: ``None``) string denoting the numerical solution to use for the evaluation; if ``None``, the latest solution computed by :meth:`integrate` is used. OUTPUT: - value of `\mu` """ return sqrt( self.evaluate_mu2(affine_parameter, solution_key=solution_key))
def _an_element_3d(self, x=0, y=0): r""" Returns an element in self. EXAMPLES:: sage: from slabbe import DiscreteHyperplane sage: p = DiscreteHyperplane([1,pi,7], 1+pi+7, mu=10) sage: p._an_element_3d() (0, 0, 0) """ a, b, c = self._v x_sqrt3 = ceil(x / sqrt(3)) left = ((a + b) * y + (a - b) * x_sqrt3 - self._mu) / (a + b + c) right = ((a + b) * y + (a - b) * x_sqrt3 - self._mu + self._omega) / (a + b + c) #print "left, right = ", left, right #print "left, right = ", ceil(left), ceil(right)-1 # left <= z <= right znew = ceil(left) xnew = znew - y - x_sqrt3 ynew = znew - y + x_sqrt3 znew = ceil(right) - 1 #print xnew, ynew, znew #print vector((xnew, ynew, znew)) in self #print vector((x,y,ceil(right)-1)) in self v = vector((xnew, ynew, znew)) if v in self: v.set_immutable() return v else: print "%s not in the plane" % v print "trying similar points" v = vector((xnew, ynew, znew - 1)) if v in self: v.set_immutable() return v v = vector((xnew, ynew, znew + 1)) if v in self: v.set_immutable() return v raise ValueError("%s not in the plane" % v)
def get_background_graphic(self, **bdry_options): r""" Return a graphic object that makes the model easier to visualize. For the hyperboloid model, the background object is the hyperboloid itself. EXAMPLES:: sage: H = HyperbolicPlane().HM().get_background_graphic() """ from sage.plot.plot3d.all import plot3d from sage.all import SR hyperboloid_opacity = bdry_options.get('hyperboloid_opacity', .1) z_height = bdry_options.get('z_height', 7.0) x_max = sqrt((z_height ** 2 - 1) / 2.0) x = SR.var('x') y = SR.var('y') return plot3d((1 + x ** 2 + y ** 2).sqrt(), (x, -x_max, x_max), (y,-x_max, x_max), opacity=hyperboloid_opacity, **bdry_options)
def platonic_octahedron(): r"""Produce a triple consisting of a polyhedral version of the platonic octahedron, the associated cone surface, and a ConeSurfaceToPolyhedronMap from the surface to the polyhedron. EXAMPLES:: sage: from flatsurf.geometry.polyhedra import platonic_octahedron sage: polyhedron,surface,surface_to_polyhedron = platonic_octahedron() sage: TestSuite(surface).run() r""" vertices = [] for i in range(3): temp = vector(QQ, [1 if k == i else 0 for k in range(3)]) for j in range(-1, 3, 2): vertices.append(j * temp) octahedron = Polyhedron(vertices=vertices) surface,surface_to_octahedron = \ polyhedron_to_cone_surface(octahedron,scaling_factor=AA(sqrt(2))) return octahedron, surface, surface_to_octahedron
def change_iso_curve(self, a): """ INPUT: * a the montgomery a coefficient of the target curve OUTPUT: * the point P seen in the new curve """ a1 = self.curve.Fp2(self.curve.a) if (a**2 - 4) * (a1**2 - 3)**3 != (a1**2 - 4) * (a**2 - 3)**3: # i.e if 256*(a1**2 - 3)**3/(a1**2 - 4) != 256*(a**2 - 3)**3/(a**2 - 4) raise RuntimeError('the curves are not isomorphic.') E_a1 = EllipticCurve(self.curve.Fp2, [0, a1, 0, 1, 0]) E_a = EllipticCurve(self.curve.Fp2, [0, a, 0, 1, 0]) xP = self.x / self.z yP = sqrt(xP**3 + a1 * xP**2 + xP) P_ws = E_a1(xP, yP) iso = E_a1.isomorphism_to(E_a) curve_target = copy(self.curve) curve_target.a = a return Point(iso(P_ws)[0], 1, curve_target)
def _eval_(self, n, x): """ EXAMPLES:: sage: bessel_K(1,0) bessel_K(1, 0) sage: bessel_K(1.0, 0.0) +infinity sage: bessel_K(-1, 1).n(128) 0.60190723019723457473754000153561733926 """ if (not isinstance(n, Expression) and not isinstance(x, Expression) and (is_inexact(n) or is_inexact(x))): coercion_model = get_coercion_model() n, x = coercion_model.canonical_coercion(n, x) return self._evalf_(n, x, parent(n)) # special identity if n == Integer(1) / Integer(2) and x > 0: return sqrt(pi / 2) * exp(-x) * x**(-Integer(1) / Integer(2)) return None # leaves the expression unevaluated
def inner_horizon_radius(self): r""" Return the value of the Boyer-Lindquist coordinate `r` at the inner horizon (Cauchy horizon). EXAMPLES:: sage: from kerrgeodesic_gw import KerrBH sage: a, m = var('a m') sage: BH = KerrBH(a, m) sage: BH.inner_horizon_radius() m - sqrt(-a^2 + m^2) An alias is ``cauchy_horizon_radius()``:: sage: BH.cauchy_horizon_radius() m - sqrt(-a^2 + m^2) """ m = self._m a = self._a return m - sqrt(m**2 - a**2)
def __iter__(self): if self.__disc is infinity: raise ValueError("infinity is not a true filter index") if self.__reduced: for c in range(0, self._indefinite_content_bound()): yield (0, 0, c) for a in range(1, isqrt(self.__disc // 3) + 1): for b in range(a + 1): for c in range(a, (b**2 + (self.__disc - 1)) // (4 * a) + 1): yield (a, b, c) else: ##FIXME: These are not all matrices for a in range(0, self._indefinite_content_bound()): yield (a, 0, 0) for c in range(1, self._indefinite_content_bound()): yield (0, 0, c) maxtrace = floor(5 * self.__disc / 15 + sqrt(self.__disc) / 2) for a in range(1, maxtrace + 1): for c in range(1, maxtrace - a + 1): Bu = isqrt(4 * a * c - 1) di = 4 * a * c - self.__disc if di >= 0: Bl = isqrt(di) + 1 else: Bl = 0 for b in range(-Bu, -Bl + 1): yield (a, b, c) for b in range(Bl, Bu + 1): yield (a, b, c) #! if self.__reduced raise StopIteration
def ideal_endpoints(self): r""" Determine the ideal (boundary) endpoints of the complete hyperbolic geodesic corresponding to ``self``. OUTPUT: - a list of 2 boundary points EXAMPLES:: sage: UHP = HyperbolicPlane().UHP() sage: UHP.get_geodesic(I, 2*I).ideal_endpoints() [Boundary point in UHP 0, Boundary point in UHP +Infinity] sage: UHP.get_geodesic(1 + I, 2 + 4*I).ideal_endpoints() [Boundary point in UHP -sqrt(65) + 9, Boundary point in UHP sqrt(65) + 9] """ start = self._start.coordinates() end = self._end.coordinates() [x1, x2] = [real(k) for k in [start, end]] [y1, y2] = [imag(k) for k in [start, end]] M = self._model # infinity is the first endpoint, so the other ideal endpoint # is just the real part of the second coordinate if start == infinity: return [M.get_point(start), M.get_point(x2)] # Same idea as above if end == infinity: return [M.get_point(x1), M.get_point(end)] # We could also have a vertical line with two interior points if x1 == x2: return [M.get_point(x1), M.get_point(infinity)] # Otherwise, we have a semicircular arc in the UHP c = ((x1 + x2) * (x2 - x1) + (y1 + y2) * (y2 - y1)) / (2 * (x2 - x1)) r = sqrt((c - x1)**2 + y1**2) return [M.get_point(c - r), M.get_point(c + r)]
def evaluate_mu(self, affine_parameter, solution_key=None): r""" Compute the mass parameter `\mu` at a given value of the affine parameter `\lambda`. INPUT: - ``affine_parameter`` -- value of the affine parameter `\lambda` - ``solution_key`` -- (default: ``None``) string denoting the numerical solution to use for the evaluation; if ``None``, the latest solution computed by :meth:`integrate` is used. OUTPUT: - value of `\mu` """ p = self.evaluate_tangent_vector(affine_parameter, solution_key=solution_key) point = p.parent().base_point() g = self._spacetime.metric().at(point) mu = sqrt(-g(p, p)) return mu.substitute(self._numerical_substitutions())
def __init__(self, n, secret_dist='uniform', m=None): """ Construct LWE instance parameterised by security paramter ``n`` where the modulus ``q`` and the ``stddev`` of the noise are chosen as in [Reg09]_. INPUT: - ``n`` - security paramter (integer > 0) - ``secret_dist`` - distribution of the secret. See documentation of :class:`LWE` for details (default='uniform') - ``m`` - number of allowed samples or ``None`` if no such limit exists (default: ``None``) EXAMPLES:: sage: Regev(n=20) LWE(20, 401, DiscreteGaussianSamplerRejection(1.915069, 401, 4), 'uniform', None) """ q = ZZ(next_prime(n**2)) s = RR(1 / (RR(n).sqrt() * log(n, 2)**2) * q) D = DiscreteGaussianSampler(s / sqrt(2 * pi.n()), q) LWE.__init__(self, n=n, q=q, D=D, secret_dist=secret_dist, m=m)
def mu(self, epsilon=1e-12): """ Returns rescaling factor associated to the couple with precision epsilon in the search of the root of the contact function. """ eta = var('eta') Y = (eta * self.ellipsoid2.red_belonging_matrix().inverse() + (1 - eta) * self.ellipsoid1.red_belonging_matrix().inverse()) p = (eta * (1 - eta) * ((self.ellipsoid2.pos - self.ellipsoid1.pos).transpose()) * (Y.adjugate()) * (self.ellipsoid2.pos - self.ellipsoid1.pos)) q = Y.determinant() h = expand(p.derivative(eta) * q - p * q.derivative(eta))[0, 0] F = expand(p / q)[0, 0] root, iter = halleyMethod( h, eta, self.ellipsoid1.R[0] / (self.ellipsoid1.R[0] + self.ellipsoid2.R[0]), epsilon) return sqrt(F(eta=root))
def perpendicular_bisector(self): # UHP r""" Return the perpendicular bisector of the hyperbolic geodesic ``self`` if that geodesic has finite length. EXAMPLES:: sage: UHP = HyperbolicPlane().UHP() sage: g = UHP.random_geodesic() sage: h = g.perpendicular_bisector() sage: c = lambda x: x.coordinates() sage: bool(c(g.intersection(h)[0]) - c(g.midpoint()) < 10**-9) True Infinite geodesics cannot be bisected:: sage: UHP.get_geodesic(0, 1).perpendicular_bisector() Traceback (most recent call last): ... ValueError: the length must be finite """ if self.length() == infinity: raise ValueError("the length must be finite") start = self._start.coordinates() d = self._model._dist_points(start, self._end.coordinates()) / 2 S = self.complete()._to_std_geod(start) T1 = matrix([[exp(d / 2), 0], [0, exp(-d / 2)]]) s2 = sqrt(2) * 0.5 T2 = matrix([[s2, -s2], [s2, s2]]) isom_mtrx = S.inverse() * (T1 * T2) * S # We need to clean this matrix up. if (isom_mtrx - isom_mtrx.conjugate()).norm() < 5 * EPSILON: # Imaginary part is small. isom_mtrx = (isom_mtrx + isom_mtrx.conjugate()) / 2 # Set it to its real part. H = self._model.get_isometry(isom_mtrx) return self._model.get_geodesic(H(self._start), H(self._end))
def icosahedron(self, base_ring=QQ): """ Return an icosahedron with edge length 1. INPUT: - ``base_ring`` -- Either ``QQ`` or ``RDF``. OUTPUT: A Polyhedron object of a floating point or rational approximation to the regular 3d icosahedron. If ``base_ring=QQ``, a rational approximation is used and the points are not exactly the vertices of the icosahedron. The icosahedron's coordinates contain the golden ratio, so there is no exact representation possible. EXAMPLES:: sage: ico = polytopes.icosahedron() sage: sum(sum( ico.vertex_adjacency_matrix() ))/2 30 """ if base_ring == QQ: g = QQ(1618033) / 1000000 # Golden ratio approximation r12 = QQ(1) / 2 elif base_ring == RDF: g = RDF((1 + sqrt(5)) / 2) r12 = RDF(QQ(1) / 2) else: raise ValueError("field must be QQ or RDF.") verts = [i([0, r12, g / 2]) for i in AlternatingGroup(3)] verts = verts + [i([0, r12, -g / 2]) for i in AlternatingGroup(3)] verts = verts + [i([0, -r12, g / 2]) for i in AlternatingGroup(3)] verts = verts + [i([0, -r12, -g / 2]) for i in AlternatingGroup(3)] return Polyhedron(vertices=verts, base_ring=base_ring)
def isco_radius(self, retrograde=False): r""" Return the Boyer-Lindquist radial coordinate of the innermost stable circular orbit (ISCO) in the equatorial plane. INPUT: - ``retrograde`` -- (default: ``False``) boolean determining whether retrograde or prograde (direct) orbits are considered OUTPUT: - Boyer-Lindquist radial coordinate `r` of the innermost stable circular orbit in the equatorial plane EXAMPLES:: sage: from kerrgeodesic_gw import KerrBH sage: a, m = var('a m') sage: BH = KerrBH(a, m) sage: BH.isco_radius() m*(sqrt((((a/m + 1)^(1/3) + (-a/m + 1)^(1/3))*(-a^2/m^2 + 1)^(1/3) + 1)^2 + 3*a^2/m^2) - sqrt(-(((a/m + 1)^(1/3) + (-a/m + 1)^(1/3))*(-a^2/m^2 + 1)^(1/3) + 2*sqrt((((a/m + 1)^(1/3) + (-a/m + 1)^(1/3))*(-a^2/m^2 + 1)^(1/3) + 1)^2 + 3*a^2/m^2) + 4)*(((a/m + 1)^(1/3) + (-a/m + 1)^(1/3))*(-a^2/m^2 + 1)^(1/3) - 2)) + 3) sage: BH.isco_radius(retrograde=True) m*(sqrt((((a/m + 1)^(1/3) + (-a/m + 1)^(1/3))*(-a^2/m^2 + 1)^(1/3) + 1)^2 + 3*a^2/m^2) + sqrt(-(((a/m + 1)^(1/3) + (-a/m + 1)^(1/3))*(-a^2/m^2 + 1)^(1/3) + 2*sqrt((((a/m + 1)^(1/3) + (-a/m + 1)^(1/3))*(-a^2/m^2 + 1)^(1/3) + 1)^2 + 3*a^2/m^2) + 4)*(((a/m + 1)^(1/3) + (-a/m + 1)^(1/3))*(-a^2/m^2 + 1)^(1/3) - 2)) + 3) sage: KerrBH(0.5).isco_radius() # tol 1.0e-13 4.23300252953083 sage: KerrBH(0.9).isco_radius() # tol 1.0e-13 2.32088304176189 sage: KerrBH(0.98).isco_radius() # tol 1.0e-13 1.61402966763547 ISCO in Schwarzschild spacetime:: sage: KerrBH(0, m).isco_radius() 6*m ISCO in extreme Kerr spacetime (`a=m`):: sage: KerrBH(m, m).isco_radius() m sage: KerrBH(m, m).isco_radius(retrograde=True) 9*m """ m = self._m a = self._a eps = -1 if not retrograde else 1 # Eq. (2.21) in Bardeen, Press & Teukolsky, ApJ 178, 347 (1972) asm = a / m asm2 = asm**2 one_third = QQ(1) / QQ(3) z1 = 1 + (1 - asm2)**one_third * ((1 + asm)**one_third + (1 - asm)**one_third) z2 = sqrt(3 * asm2 + z1**2) return m * (3 + z2 + eps * sqrt((3 - z1) * (3 + z1 + 2 * z2)))
def revolution_plot3d(curve, trange, phirange=None, parallel_axis='z', axis=(0, 0), print_vector=False, show_curve=False, **kwds): """ Return a plot of a revolved curve. There are three ways to call this function: - ``revolution_plot3d(f,trange)`` where `f` is a function located in the `x z` plane. - ``revolution_plot3d((f_x,f_z),trange)`` where `(f_x,f_z)` is a parametric curve on the `x z` plane. - ``revolution_plot3d((f_x,f_y,f_z),trange)`` where `(f_x,f_y,f_z)` can be any parametric curve. INPUT: - ``curve`` - A curve to be revolved, specified as a function, a 2-tuple or a 3-tuple. - ``trange`` - A 3-tuple `(t,t_{\min},t_{\max})` where t is the independent variable of the curve. - ``phirange`` - A 2-tuple of the form `(\phi_{\min},\phi_{\max})`, (default `(0,\pi)`) that specifies the angle in which the curve is to be revolved. - ``parallel_axis`` - A string (Either 'x', 'y', or 'z') that specifies the coordinate axis parallel to the revolution axis. - ``axis`` - A 2-tuple that specifies the position of the revolution axis. If parallel is: - 'z' - then axis is the point in which the revolution axis intersects the `x y` plane. - 'x' - then axis is the point in which the revolution axis intersects the `y z` plane. - 'y' - then axis is the point in which the revolution axis intersects the `x z` plane. - ``print_vector`` - If True, the parametrization of the surface of revolution will be printed. - ``show_curve`` - If True, the curve will be displayed. EXAMPLES: Let's revolve a simple function around different axes:: sage: u = var('u') sage: f=u^2 sage: revolution_plot3d(f,(u,0,2),show_curve=True,opacity=0.7).show(aspect_ratio=(1,1,1)) If we move slightly the axis, we get a goblet-like surface:: sage: revolution_plot3d(f,(u,0,2),axis=(1,0.2),show_curve=True,opacity=0.5).show(aspect_ratio=(1,1,1)) A common problem in calculus books, find the volume within the following revolution solid:: sage: line=u sage: parabola=u^2 sage: sur1=revolution_plot3d(line,(u,0,1),opacity=0.5,rgbcolor=(1,0.5,0),show_curve=True,parallel_axis='x') sage: sur2=revolution_plot3d(parabola,(u,0,1),opacity=0.5,rgbcolor=(0,1,0),show_curve=True,parallel_axis='x') sage: (sur1+sur2).show() Now let's revolve a parametrically defined circle. We can play with the topology of the surface by changing the axis, an axis in `(0,0)` (as the previous one) will produce a sphere-like surface:: sage: u = var('u') sage: circle=(cos(u),sin(u)) sage: revolution_plot3d(circle,(u,0,2*pi),axis=(0,0),show_curve=True,opacity=0.5).show(aspect_ratio=(1,1,1)) An axis on `(0,y)` will produce a cylinder-like surface:: sage: revolution_plot3d(circle,(u,0,2*pi),axis=(0,2),show_curve=True,opacity=0.5).show(aspect_ratio=(1,1,1)) And any other axis will produce a torus-like surface:: sage: revolution_plot3d(circle,(u,0,2*pi),axis=(2,0),show_curve=True,opacity=0.5).show(aspect_ratio=(1,1,1)) Now, we can get another goblet-like surface by revolving a curve in 3d:: sage: u = var('u') sage: curve=(u,cos(4*u),u^2) sage: revolution_plot3d(curve,(u,0,2),show_curve=True,parallel_axis='z',axis=(1,.2),opacity=0.5).show(aspect_ratio=(1,1,1)) A curvy curve with only a quarter turn:: sage: u = var('u') sage: curve=(sin(3*u),.8*cos(4*u),cos(u)) sage: revolution_plot3d(curve,(u,0,pi),(0,pi/2),show_curve=True,parallel_axis='z',opacity=0.5).show(aspect_ratio=(1,1,1),frame=False) """ from sage.symbolic.ring import SR from sage.symbolic.constants import pi from sage.functions.other import sqrt from sage.functions.trig import sin from sage.functions.trig import cos from sage.functions.trig import atan2 if parallel_axis not in ['x', 'y', 'z']: raise ValueError("parallel_axis must be either 'x', 'y', or 'z'.") vart = trange[0] if str(vart) == 'phi': phi = SR.var('fi') else: phi = SR.var('phi') if phirange is None: #this if-else provides a phirange phirange = (phi, 0, 2 * pi) elif len(phirange) == 3: phi = phirange[0] pass else: phirange = (phi, phirange[0], phirange[1]) if isinstance(curve, tuple) or isinstance(curve, list): #this if-else provides a vector v to be plotted #if curve is a tuple or a list of length 2, it is interpreted as a parametric curve #in the x-z plane. #if it is of length 3 it is interpreted as a parametric curve in 3d space if len(curve) == 2: x = curve[0] y = 0 z = curve[1] elif len(curve) == 3: x = curve[0] y = curve[1] z = curve[2] else: x = vart y = 0 z = curve if parallel_axis == 'z': x0 = axis[0] y0 = axis[1] # (0,0) must be handled separately for the phase value phase = 0 if x0 != 0 or y0 != 0: phase = atan2((y - y0), (x - x0)) R = sqrt((x - x0)**2 + (y - y0)**2) v = (R * cos(phi + phase) + x0, R * sin(phi + phase) + y0, z) elif parallel_axis == 'x': y0 = axis[0] z0 = axis[1] # (0,0) must be handled separately for the phase value phase = 0 if z0 != 0 or y0 != 0: phase = atan2((z - z0), (y - y0)) R = sqrt((y - y0)**2 + (z - z0)**2) v = (x, R * cos(phi + phase) + y0, R * sin(phi + phase) + z0) elif parallel_axis == 'y': x0 = axis[0] z0 = axis[1] # (0,0) must be handled separately for the phase value phase = 0 if z0 != 0 or x0 != 0: phase = atan2((z - z0), (x - x0)) R = sqrt((x - x0)**2 + (z - z0)**2) v = (R * cos(phi + phase) + x0, y, R * sin(phi + phase) + z0) if print_vector: print(v) if show_curve: curveplot = parametric_plot3d((x, y, z), trange, thickness=2, rgbcolor=(1, 0, 0)) return parametric_plot3d(v, trange, phirange, **kwds) + curveplot return parametric_plot3d(v, trange, phirange, **kwds)
def is_degenerate(self): """ Decide whether the binary recurrence sequence is degenerate. Let `\\alpha` and `\\beta` denote the roots of the characteristic polynomial `p(x) = x^2-bx -c`. Let `a = u_1-u_0\\beta/(\\beta - \\alpha)` and `b = u_1-u_0\\alpha/(\\beta - \\alpha)`. The sequence is, thus, given by `u_n = a \\alpha^n - b\\beta^n`. Then we say that the sequence is nondegenerate if and only if `a*b*\\alpha*\\beta \\neq 0` and `\\alpha/\\beta` is not a root of unity. More concretely, there are 4 classes of degeneracy, that can all be formulated in terms of the matrix `F = [[0,1], [c, b]]`. - `F` is singular -- this corresponds to ``c`` = 0, and thus `\\alpha*\\beta = 0`. This sequence is geometric after term ``u0`` and so we call it ``quasigeometric``. - `v = [[u_0], [u_1]]` is an eigenvector of `F` -- this corresponds to a ``geometric`` sequence with `a*b = 0`. - `F` is nondiagonalizable -- this corresponds to `\\alpha = \\beta`. This sequence will be the point-wise product of an arithmetic and geometric sequence. - `F^k` is scaler, for some `k>1` -- this corresponds to `\\alpha/\\beta` a `k` th root of unity. This sequence is a union of several geometric sequences, and so we again call it ``quasigeometric``. EXAMPLES:: sage: S = BinaryRecurrenceSequence(0,1) sage: S.is_degenerate() True sage: S.is_geometric() False sage: S.is_quasigeometric() True sage: R = BinaryRecurrenceSequence(3,-2) sage: R.is_degenerate() False sage: T = BinaryRecurrenceSequence(2,-1) sage: T.is_degenerate() True sage: T.is_arithmetic() True """ if (self.b**2 + 4 * self.c) != 0: if (self.b**2 + 4 * self.c).is_square(): A = sqrt((self.b**2 + 4 * self.c)) else: K = QuadraticField((self.b**2 + 4 * self.c), 'x') A = K.gen() aa = (self.u1 - self.u0 * (self.b + A) / 2) / (A) #called `a` in Docstring bb = (self.u1 - self.u0 * (self.b - A) / 2) / (A) #called `b` in Docstring #(b+A)/2 is called alpha in Docstring, (b-A)/2 is called beta in Docstring if (self.b - A) != 0: if ((self.b + A) / (self.b - A))**(6) == 1: return True else: return True if aa * bb * (self.b + A) * (self.b - A) == 0: return True return False return True
def cartan_invariants_matrix(self): r""" Return the Cartan invariants matrix of the algebra. OUTPUT: a matrix of non negative integers Let `A` be this finite dimensional algebra and `(S_i)_{i\in I}` be representatives of the right simple modules of `A`. Note that their adjoints `S_i^*` are representatives of the left simple modules. Let `(P^L_i)_{i\in I}` and `(P^R_i)_{i\in I}` be respectively representatives of the corresponding indecomposable projective left and right modules of `A`. In particular, we assume that the indexing is consistent so that `S_i^*=\operatorname{top} P^L_i` and `S_i=\operatorname{top} P^R_i`. The *Cartan invariant matrix* `(C_{i,j})_{i,j\in I}` is a matrix of non negative integers that encodes much of the representation theory of `A`; namely: - `C_{i,j}` counts how many times `S_i^*\otimes S_j` appears as composition factor of `A` seen as a bimodule over itself; - `C_{i,j}=\dim Hom_A(P^R_j, P^R_i)`; - `C_{i,j}` counts how many times `S_j` appears as composition factor of `P^R_i`; - `C_{i,j}=\dim Hom_A(P^L_i, P^L_j)`; - `C_{i,j}` counts how many times `S_i^*` appears as composition factor of `P^L_j`. In the commutative case, the Cartan invariant matrix is diagonal. In the context of solving systems of multivariate polynomial equations of dimension zero, `A` is the quotient of the polynomial ring by the ideal generated by the equations, the simple modules correspond to the roots, and the numbers `C_{i,i}` give the multiplicities of those roots. .. NOTE:: For simplicity, the current implementation, assumes that the index set `I` is of the form `\{0,\dots,n-1\}`. Better indexations will be possible in the future. ALGORITHM: The Cartan invariant matrix of `A` is computed from the dimension of the summands of its peirce decomposition. .. SEEALSO:: - :meth:`peirce_decomposition` - :meth:`isotypic_projective_modules` EXAMPLES: For a semisimple algebra, in particular for group algebras in chararacteristic zero, the Cartan invariants matrix is the identity:: sage: A3 = SymmetricGroup(3).algebra(QQ) sage: A3.cartan_invariants_matrix() [1 0 0] [0 1 0] [0 0 1] For the path algebra of a quiver, the Cartan invariants matrix counts the number of paths between two vertices:: sage: A = Algebras(QQ).FiniteDimensional().WithBasis().example() sage: A.cartan_invariants_matrix() [1 2] [0 1] In the commutative case, the Cartan invariant matrix is diagonal:: sage: Z12 = Monoids().Finite().example(); Z12 An example of a finite multiplicative monoid: the integers modulo 12 sage: A = Z12.algebra(QQ) sage: A.cartan_invariants_matrix() [1 0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0] [0 0 2 0 0 0 0 0 0] [0 0 0 1 0 0 0 0 0] [0 0 0 0 2 0 0 0 0] [0 0 0 0 0 1 0 0 0] [0 0 0 0 0 0 1 0 0] [0 0 0 0 0 0 0 2 0] [0 0 0 0 0 0 0 0 1] With the algebra of the `0`-Hecke monoid:: sage: from sage.monoids.hecke_monoid import HeckeMonoid sage: A = HeckeMonoid(SymmetricGroup(4)).algebra(QQ) sage: A.cartan_invariants_matrix() [1 0 0 0 0 0 0 0] [0 2 1 0 1 1 0 0] [0 1 1 0 1 0 0 0] [0 0 0 1 0 1 1 0] [0 1 1 0 1 0 0 0] [0 1 0 1 0 2 1 0] [0 0 0 1 0 1 1 0] [0 0 0 0 0 0 0 1] """ from sage.rings.integer_ring import ZZ A_quo = self.semisimple_quotient() idempotents_quo = A_quo.central_orthogonal_idempotents() # Dimension of simple modules dim_simples = [ sqrt(A_quo.principal_ideal(e).dimension()) for e in idempotents_quo ] # Orthogonal idempotents idempotents = self.orthogonal_idempotents_central_mod_radical() def C(i, j): summand = self.peirce_summand(idempotents[i], idempotents[j]) return summand.dimension() / (dim_simples[i] * dim_simples[j]) return Matrix(ZZ, len(idempotents), C)