def f(i): if i == 0: return QQ(scalar) * y[0] * exp(tau * omega[0]) elif i in I: return tau / (1 - exp(tau * omega[i])) else: return 1 / (1 - y[i] * exp(tau * omega[i]))
def setup_fields_and_triangles(self): from sage.all import RealIntervalField, ComplexIntervalField, sin, cos, exp self.RIF = RealIntervalField(120) self.CIF = ComplexIntervalField(120) alpha = self.RIF(0.4) self.finiteTriangle1 = FiniteTriangle([ FinitePoint(z=exp(self.CIF(0, 2.1 * i + 0.1)) * cos(alpha), t=sin(alpha)) for i in range(3) ]) self.idealTriangle1 = IdealTriangle([ ProjectivePoint(z=exp(self.CIF(0, 2.1 * i + 0.1))) for i in range(3) ]) self.idealTriangle2 = IdealTriangle( [ProjectivePoint(self.CIF(z)) for z in [-1, 0, 1]]) self.idealTriangle3 = IdealTriangle([ ProjectivePoint(self.CIF(1)), ProjectivePoint(self.CIF(-1)), ProjectivePoint(self.CIF(0), True) ])
def number_of_coefficients_needed(Q, kappa_fe, lambda_fe, max_t): # TODO: This doesn't work. Trouble when computing t0 # We completely mimic what lcalc does when it decides whether # to print a warning. DIGITS = 14 # These are names of lcalc parameters, and we are DIGITS2 = 2 # mimicking them. logger.debug("Start NOC") theta = sum(kappa_fe) c = DIGITS2 * log(10.0) a = len(kappa_fe) c1 = 0.0 for j in range(a): logger.debug("In loop NOC") t0 = kappa_fe[j] * max_t + complex(lambda_fe[j]).imag() logger.debug("In loop 2 NOC") if abs(t0) < 2 * c / (math.pi * a): logger.debug("In loop 3_1 NOC") c1 += kappa_fe[j] * pi / 2.0 else: c1 += kappa_fe[j] * abs(c / (t0 * a)) logger.debug("In loop 3_2 NOC") return int(round(Q * exp(log(2.3 * DIGITS * theta / c1) * theta) + 10))
def signature_function_of_integral_matrix(V, prec=53): """ Computes the signature function sigma of V via numerical methods. Returns two lists, the first representing a partition of [0, 1]: x_0 = 0 < x_1 < x_2 < ... < x_n = 1 and the second list consisting of the values [v_0, ... , v_(n-1)] of sigma on the interval (x_i, x_(i+1)). Currently, the value of sigma *at* x_i is not computed. """ poly = alexander_poly_from_seifert(V) RR = RealField(prec) CC = ComplexField(prec) pi = RR.pi() I = CC.gen() partition = [RR(0)] + [a for a, e in roots_on_unit_circle(poly, prec) ] + [RR(1)] n = len(partition) - 1 values = [] for i in range(n): omega = exp((2 * pi * I) * (partition[i] + partition[i + 1]) / 2) A = (1 - omega) * V + (1 - omega.conjugate()) * V.transpose() values.append(signature_via_numpy(A)) assert list(reversed(values)) == values return partition, values
def from_conjugacy_class_index_to_polynomial(self, index): """ A function converting from a conjugacy class index (starting at 1) to the local Euler polynomial. Saves a sequence of processed polynomials, obtained from the local factors table, so it can reuse computations from prime to prime This sequence is indexed by conjugacy class indices (starting at 1, filled with dummy first) and gives the corresponding polynomials in the form [coeff_deg_0, coeff_deg_1, ...], where coeff_deg_i is in ComplexField(). This could be changed later, or made parametrizable """ try: return self._from_conjugacy_class_index_to_polynomial_fn(index) except AttributeError: local_factors = self.local_factors_table() field = ComplexField() root_of_unity = exp( (field.gen()) * 2 * field.pi() / int(self.character_field())) local_factor_processed_pols = [ 0 ] # dummy to account for the shift in indices for pol in local_factors: local_factor_processed_pols.append( process_polynomial_over_algebraic_integer( pol, field, root_of_unity)) def tmp(conjugacy_class_index_start_1): return local_factor_processed_pols[ conjugacy_class_index_start_1] self._from_conjugacy_class_index_to_polynomial_fn = tmp return self._from_conjugacy_class_index_to_polynomial_fn(index)
def compute_z_and_parities_from_flattening_w0_w1(w0, w1): """ Given a pair (w0, w1) with +- exp(w0) +- exp(-w1) = 1, compute (z, p, q) such that z = (-1)^p * exp(w0) and 1/(1-z) = (-1)^q exp(w1) where p, q in {0,1}. """ e0 = exp(w0) e1 = exp(-w1) l = [(((-1)**p) * e0, p, q) for p in [0, 1] for q in [0, 1] if Integer(1) in ((-1)**p) * e0 + ((-1)**q) * e1] if not len(l) == 1: raise Exception("Bad flattening %s %s %s" % (w0, w1, len(l))) return l[0]
def string2number(s): # a start to replace p2sage (used for the paramters in the FE) strs = str(s).replace(' ','') try: if 'e' in strs: # check for e(m/n) := exp(2*pi*i*m/n), used by Dirichlet characters, for example r = re.match(r'^\$?e\\left\(\\frac\{(?P<num>\d+)\}\{(?P<den>\d+)\}\\right\)\$?$',strs) if not r: r = re.match(r'^e\((?P<num>\d+)/(?P<den>\d+)\)$',strs) if r: q = Rational(r.groupdict()['num'])/Rational(r.groupdict()['den']) return CDF(exp(2*pi*I*q)) if 'I' in strs: return CDF(strs) elif (type(s) is list or type(s) is tuple) and len(s) == 2: return CDF(tuple(s)) elif '/' in strs: return Rational(strs) elif strs=='0.5': # Temporary fix because 0.5 in db for EC return Rational('1/2') elif '.' in strs: return float(strs) else: return Integer(strs) except: return s
def string2number(s): # a start to replace p2sage (used for the paramters in the FE) strs = str(s).replace(' ','') try: if 'e' in strs: # check for e(m/n) := exp(2*pi*i*m/n), used by Dirichlet characters, for example r = re.match('^\$?e\\\\left\(\\\\frac\{(?P<num>\d+)\}\{(?P<den>\d+)\}\\\\right\)\$?$',strs) if not r: r = re.match('^e\((?P<num>\d+)/(?P<den>\d+)\)$',strs) if r: q = Rational(r.groupdict()['num'])/Rational(r.groupdict()['den']) return CDF(exp(2*pi*I*q)) if 'I' in strs: return CDF(strs) elif '/' in strs: return Rational(strs) elif strs=='0.5': # Temporary fix because 0.5 in db for EC return Rational('1/2') elif '.' in strs: return float(strs) else: return Integer(strs) except: return s
def __init__(self, mcomplex, cut_off): # A list of pairs (lower bound, tile, generator) of corresponding to # unglued faces. self.unglued_generators = [] super(SpineTilingEngine, self).__init__(mcomplex) z = self.mcomplex.Tetrahedra[0].ShapeParameters[simplex.E01] self.CIF = z.parent() self.RIF = z.real().parent() self.cut_off = cut_off for tet in self.mcomplex.Tetrahedra: tet.SpineRadius = self.RIF(0) for f in simplex.TwoSubsimplices: tet.SpineRadius = tet.SpineRadius.max( tet.InCenter.dist(tet.Class[f].InCenter)) for e in simplex.OneSubsimplices: tet.SpineRadius = tet.SpineRadius.max( tet.InCenter.dist(tet.Class[e].MidPoint)) tet.SpineRadiusPlusCutOff = tet.SpineRadius + self.cut_off e = exp(tet.SpineRadiusPlusCutOff) tet.CutOffFactor = (e * e - 1) / (2 * e) for tet in self.mcomplex.Tetrahedra: tet.transform_taking_face_to_0_1_inf = { f : _compute_transform_taking_face_to_0_1_inf( tet, f, self.CIF) for f in simplex.TwoSubsimplices } self.initial_tile.word = []
def exp(self): val = zero_vector(self.val[0].parent(), self.degree + 1) val[0] = exp(self.val[0]) for k in range(1, self.degree + 1): for i in range(1, k + 1): val[k] += i * self.val[i] * val[k - i] val[k] = val[k] / k return Taylor(val.list(), self.degree)
def value(self, z, embedding=0): if self.prec == 0: return 0 else: q = exp(2 * CC.pi() * CC(0, 1) * z) return sum( self.coefficient_embedding(n, embedding) * q**n for n in range(self.prec))
def main4(): print("MAIN 4:") zeta = CDF(exp(Integer(2) * pi * I / Integer(5))) print(zeta) v = [legendre_symbol(n, Integer(5)) * zeta**(Integer(2) * n) for n in range(Integer(1), Integer(5))] S = sum([point(tuple(z), pointsize=Integer(100)) for z in v]) G = point(tuple(sum(v)), pointsize=Integer(100), rgbcolor='red') (S + G).save(filename="gauss_sum.png") print()
def laplace(cls, self, parameters, variable, x='x', s='t'): r""" Returns the Laplace transform of self with respect to the variable var. INPUT: - ``x`` - variable of self - ``s`` - variable of Laplace transform. We assume that a piecewise function is 0 outside of its domain and that the left-most endpoint of the domain is 0. EXAMPLES:: sage: x, s, w = var('x, s, w') sage: f = piecewise([[(0,1),1],[[1,2], 1-x]]) sage: f.laplace(x, s) -e^(-s)/s + (s + 1)*e^(-2*s)/s^2 + 1/s - e^(-s)/s^2 sage: f.laplace(x, w) -e^(-w)/w + (w + 1)*e^(-2*w)/w^2 + 1/w - e^(-w)/w^2 :: sage: y, t = var('y, t') sage: f = piecewise([[[1,2], 1-y]]) sage: f.laplace(y, t) (t + 1)*e^(-2*t)/t^2 - e^(-t)/t^2 :: sage: s = var('s') sage: t = var('t') sage: f1(t) = -t sage: f2(t) = 2 sage: f = piecewise([[[0,1],f1],[(1,infinity),f2]]) sage: f.laplace(t,s) (s + 1)*e^(-s)/s^2 + 2*e^(-s)/s - 1/s^2 """ from sage.all import assume, exp, forget x = SR.var(x) s = SR.var(s) assume(s > 0) result = 0 for domain, f in parameters: for interval in domain: a = interval.lower() b = interval.upper() result += (SR(f) * exp(-s * x)).integral(x, a, b) forget(s > 0) return result
def laplace(cls, self, parameters, variable, x='x', s='t'): r""" Returns the Laplace transform of self with respect to the variable var. INPUT: - ``x`` - variable of self - ``s`` - variable of Laplace transform. We assume that a piecewise function is 0 outside of its domain and that the left-most endpoint of the domain is 0. EXAMPLES:: sage: x, s, w = var('x, s, w') sage: f = piecewise([[(0,1),1],[[1,2], 1-x]]) sage: f.laplace(x, s) -e^(-s)/s + (s + 1)*e^(-2*s)/s^2 + 1/s - e^(-s)/s^2 sage: f.laplace(x, w) -e^(-w)/w + (w + 1)*e^(-2*w)/w^2 + 1/w - e^(-w)/w^2 :: sage: y, t = var('y, t') sage: f = piecewise([[[1,2], 1-y]]) sage: f.laplace(y, t) (t + 1)*e^(-2*t)/t^2 - e^(-t)/t^2 :: sage: s = var('s') sage: t = var('t') sage: f1(t) = -t sage: f2(t) = 2 sage: f = piecewise([[[0,1],f1],[(1,infinity),f2]]) sage: f.laplace(t,s) (s + 1)*e^(-s)/s^2 + 2*e^(-s)/s - 1/s^2 """ from sage.all import assume, exp, forget x = SR.var(x) s = SR.var(s) assume(s>0) result = 0 for domain, f in parameters: for interval in domain: a = interval.lower() b = interval.upper() result += (SR(f)*exp(-s*x)).integral(x,a,b) forget(s>0) return result
def example_plane_plane(self): from sage.all import exp d = self.RIF(1.125) i = IdealTriangle([ ProjectivePoint(exp(self.CIF(d, 2.1 * i + 0.1))) for i in range(3) ]) e = FiniteIdealTriangleDistanceEngine(self.finiteTriangle1, i) if not abs(e.compute_lowerbound() - d) < 1e-20: raise Exception("Wrong distance")
def volf(cls, m, p, klen_list, prec=53): """ Lattice volume. :param m: number of samples :param p: ECDSA modulus :param klen_list: list of lengths of key to recover :param prec: precision to use """ w = 2 ** (max(klen_list) - 1) RR = RealField(prec) f_list = [Integer(w / (2 ** (klen - 1))) for klen in klen_list] return RR(exp(log(p) * (m - 1) + sum(map(log, f_list)) + log(w)))
def spurious_keys_probability(k, n, r, S): """ Inner parallelization can result in reducing the number of plaintext-ciphertext blocks required for a success probability=1 attack, by separating spurious keys in different search spaces. We compute here the probability that this is _not_ the case. :params k: key length :params n: block size :params r: number of plaintext-ciphertext pairs :params S: number of key space subsets/parallel instances """ p = 1 - exp(-2**(k-n*r)/S) return p
def example_line_line(self): from sage.all import exp, sin, cos d = self.RIF(1.09375) r = exp(d) alpha = self.RIF(0.4) for l in [0, 0.8, 1.2, self.RIF.pi() / 2]: z = self.CIF(r) * exp(self.CIF(0, l)) * cos(alpha) for z1 in [self.CIF(0), self.CIF(0.1, 0.1)]: f = FiniteTriangle([ FinitePoint(z=z, t=r * sin(alpha)), FinitePoint(z=-z, t=r * sin(alpha)), FinitePoint(z1, t=self.RIF(10.0)) ]) e = FiniteIdealTriangleDistanceEngine(f, self.idealTriangle2) if not abs(e.compute_lowerbound() - d) < 1e-20: raise Exception("Wrong distance %r" % e.compute_lowerbound())
def _gen_rbt_Si( rbt ): var('a theta alpha d',domain=RR) D_exp2trig = { e**(SR.wild(0)) : e**SR.wild(0).real_part() * ( cos(SR.wild(0).imag_part()) + I*sin(SR.wild(0).imag_part()) ) } M = matrix(SR,[[1,0,0,a],[0,cos(alpha),-sin(alpha),0],[0,sin(alpha),cos(alpha),d],[0,0,0,1]]) P = matrix([[0,-1,0,0],[1,0,0,0],[0,0,0,0],[0,0,0,0]]) ePtM = (exp(P*theta)*M).expand().subs(D_exp2trig).simplify_rational() restore('a theta alpha d') if bool( ePtM != rbt.T_dh ): raise Exception('_gen_rbt_Si: interlink transformation does not follows implemented DH formulation') S = ( inverse_T(M) * P * M ).expand().simplify_trig() dof = rbt.dof Si = range(dof+1) for l in range(dof): Si[l+1] = se3unskew( S.subs(LoP_to_D(zip(rbt.params_dh , rbt.links_dh[l]))) ) return Si
def example_plane_line(self): from sage.all import exp d = self.RIF(1.375) z = exp(self.CIF(d)) for z1 in [self.CIF(0), self.CIF(0.1, 0.1)]: i = IdealTriangle([ ProjectivePoint(z), ProjectivePoint(-z), ProjectivePoint(z1, inverted=True) ]) e = FiniteIdealTriangleDistanceEngine(self.finiteTriangle1, i) if not abs(e.compute_lowerbound() - d) < 1e-20: raise Exception("Wrong distance %r" % e.compute_lowerbound())
def show_slopes(self): M = self.elevation.manifold.copy() plotlist = [] for n, arc in enumerate(self._show_homological_data()): slopes = [] for p in arc: if p.real != 0: z = (1 + 0.01 * n) * exp(-arg(p) * 1j) slopes.append(z) elif len(slopes) > 1: slopes.append(None) plotlist.append(slopes) self.slope_plot = Plot(plotlist, limits=((-1.25, 1.25), (-1.25, 1.25)), margins=(0, 0), aspect="equal", position=(0.07, 0.07, 0.8, 0.85), title='Realized slopes of %s' % self.manifold.name())
def ghf(cls, m, p, klen_list, prec=53): """ Estimate norm of shortest vector according to Gaussian Heuristic. :param m: number of samples :param p: ECDSA modulus :param klen_list: list of lengths of key to recover :param prec: precision to use """ # NOTE: The Gaussian Heuristic does not hold in small dimensions w = 2 ** (max(klen_list) - 1) RR = RealField(prec) w = RR(w) f_list = [Integer(w / (2 ** (klen - 1))) for klen in klen_list] d = m + 1 log_vol = log(p) * (m - 1) + sum(map(log, f_list)) + log(w) lgh = log_gamma(1 + d / 2.0) * (1.0 / d) - log(sqrt(pi)) + log_vol * (1.0 / d) return RR(exp(lgh))
def from_conjugacy_class_index_to_polynomial(self, index): """ A function converting from a conjugacy class index (starting at 1) to the local Euler polynomial. Saves a sequence of processed polynomials, obtained from the local factors table, so it can reuse computations from prime to prime This sequence is indexed by conjugacy class indices (starting at 1, filled with dummy first) and gives the corresponding polynomials in the form [coeff_deg_0, coeff_deg_1, ...], where coeff_deg_i is in ComplexField(). This could be changed later, or made parametrizable """ try: return self._from_conjugacy_class_index_to_polynomial_fn(index) except AttributeError: local_factors = self.local_factors_table() field = ComplexField() root_of_unity = exp((field.gen()) * 2 * field.pi() / int(self.character_field())) local_factor_processed_pols = [0] # dummy to account for the shift in indices for pol in local_factors: local_factor_processed_pols.append( process_polynomial_over_algebraic_integer(pol, field, root_of_unity)) def tmp(conjugacy_class_index_start_1): return local_factor_processed_pols[conjugacy_class_index_start_1] self._from_conjugacy_class_index_to_polynomial_fn = tmp return self._from_conjugacy_class_index_to_polynomial_fn(index)
def DLMV(K): """Compute the DLMV bound""" # First compute David's C_0 Delta_K = K.discriminant().abs() h_K = K.class_number() R_K = K.regulator() r_K = K.unit_group().rank() delta_K = log(2) / (r_K + 1) C_1_K = r_K**(r_K + 1) * delta_K**(-(r_K - 1)) / 2 C_2_K = exp(24 * C_1_K * R_K) CHEB_DEN_BOUND = (4 * log(Delta_K**h_K) + 5 * h_K + 5)**2 C_0 = ((CHEB_DEN_BOUND**(12 * h_K)) * C_2_K + CHEB_DEN_BOUND**(6 * h_K))**4 # Now the Type 1 and 2 bounds type_1_bound = (1 + 3**(12 * h_K))**2 type_2_bound = get_type_2_bound(K) return max(C_0, type_1_bound, type_2_bound)
def value(self, z, embedding=0): if self.prec == 0: return 0 else: q = exp(2*CC.pi()*CC(0,1)*z) return sum(self.coefficient_embedding(n,embedding)*q**n for n in range(self.prec))
def dimension(self,k,ignore=False, debug = 0): if k < 2 and not ignore: raise NotImplementedError("k has to >= 2") s = self._signature if not (2*k in ZZ): raise ValueError("k has to be integral or half-integral") if (2*k+s)%4 != 0 and not ignore: raise NotImplementedError("2k has to be congruent to -signature mod 4") if self._v2.has_key(0): v2 = self._v2[0] else: v2 = 1 if self._g != None: if not self._aniso_formula: vals = self._g.values() #else: #print "using aniso_formula" M = self._g else: vals = self._M.values() M = self._M prec = ceil(max(log(M.order(),2),52)+1)+17 #print prec RR = RealField(prec) CC = ComplexField(prec) d = self._d m = self._m if debug > 0: print d,m if self._alpha3 == None: if self._aniso_formula: self._alpha4 = 1 self._alpha3 = -sum([BB(a)*mm for a,mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += Integer(d) - Integer(1) - self._g.beta_formula() #print self._alpha3, self._g.a5prime_formula() self._alpha3 = self._alpha3/RR(2) else: self._alpha3 = sum([(1-a)*mm for a,mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += sum([(1-a)*mm for a,mm in vals.iteritems() if a != 0]) #print self._alpha3 self._alpha3 = self._alpha3 / Integer(2) self._alpha4 = 1/Integer(2)*(vals[0]+v2) # the codimension of SkL in MkL alpha3 = self._alpha3 alpha4 = self._alpha4 if debug > 0: print alpha3, alpha4 g1=M.char_invariant(1) g1=CC(g1[0]*g1[1]) #print g1 g2=M.char_invariant(2) g2=RR(real(g2[0]*g2[1])) if debug > 0: print g2, g2.parent() g3=M.char_invariant(-3) g3=CC(g3[0]*g3[1]) if debug > 0: print RR(d) / RR(4), sqrt(RR(m)) / RR(4), CC(exp(2 * CC.pi() * CC(0,1) * (2 * k + s) / Integer(8))) alpha1 = RR(d) / RR(4) - (sqrt(RR(m)) / RR(4) * CC(exp(2 * CC.pi() * CC(0,1) * (2 * k + s) / Integer(8))) * g2) if debug > 0: print alpha1 alpha2 = RR(d) / RR(3) + sqrt(RR(m)) / (3 * sqrt(RR(3))) * real(exp(CC(2 * CC.pi() * CC(0,1) * (4 * k + 3 * s - 10) / 24)) * (g1+g3)) if debug > 0: print alpha1, alpha2, g1, g2, g3, d, k, s dim = real(d + (d * k / Integer(12)) - alpha1 - alpha2 - alpha3) if debug > 0: print "dimension:", dim if abs(dim-round(dim)) > 1e-6: raise RuntimeError("Error ({0}) too large in dimension formula for {1} and k={2}".format(abs(dim-round(dim)), self._M if self._M is not None else self._g, k)) dimr = dim dim = Integer(round(dim)) if k >=2 and dim < 0: raise RuntimeError("Negative dimension (= {0}, {1})!".format(dim, dimr)) return dim
def draw_fundamental_domain(N, group="Gamma0", model="H", axes=None, filename=None, **kwds): r""" Draw fundamental domain INPUT: - ''model'' -- (default ''H'') = ''H'' -- Upper halfplane = ''D'' -- Disk model - ''filename''-- filename to print to - ''**kwds''-- additional arguments to matplotlib - ''axes'' -- set geometry of output =[x0,x1,y0,y1] -- restrict figure to [x0,x1]x[y0,y1] EXAMPLES:: sage: G=MySubgroup(Gamma0(3)) sage: G.draw_fundamental_domain() """ if group.strip() == "Gamma0": G = Gamma0(N) elif group.strip() == "Gamma1": G = Gamma1(N) elif group.strip() == "Gamma": G = Gamma(N) else: raise ValueError('group must be one of: "Gamma0", "Gamma1", "Gamma"') s = "$" + latex(G) + "$" s = s.replace("mbox", "mathrm") s = s.replace("Bold", "mathbb") name = s # name ="$\mbox{SL}_{2}(\mathbb{Z})$" # need a "nice" set of coset representatives to draw a connected # fundamental domain. Only implemented for Gamma_0(N) coset_reps = nice_coset_reps(G) # if(group=='Gamma0'): # else: # coset_reps = list(G.coset_reps()) from matplotlib.backends.backend_agg import FigureCanvasAgg if model == "D": g = _draw_funddom_d(coset_reps, format, I) else: g = _draw_funddom(coset_reps, format) if axes is not None: [x0, x1, y0, y1] = axes elif model == "D": x0 = -1 x1 = 1 y0 = -1.1 y1 = 1 else: # find the width of the fundamental domain # w = 0 # self.cusp_width(Cusp(Infinity)) FIXME: w is never used wmin = 0 wmax = 1 max_x = RR(0.55) rho = CC(exp(2 * pi * I / 3)) for V in coset_reps: ## we also compare the real parts of where rho and infinity are mapped r1 = (V.acton(rho)).real() if V[1, 0] != 0: inf1 = RR(V[0, 0] / V[1, 0]) else: inf1 = 0 if V[1, 0] == 0 and V[0, 0] == 1: if V[0, 1] > wmax: wmax = V[0, 1] if V[0, 1] < wmin: wmin = V[0, 1] if max(r1, inf1) > max_x: max_x = max(r1, inf1) logging.debug("wmin,wmax=%s,%s" % (wmin, wmax)) # x0=-1; x1=1; y0=-0.2; y1=1.5 x0 = RR(-max_x) x1 = RR(max_x) y0 = RR(-0.15) y1 = RR(1.5) ## Draw the axes manually (since can't figure out how to do it automatically) ax = line([[x0, 0.0], [x1, 0.0]], color="black") # ax = ax + line([[0.0,y0],[0.0,y1]],color='black') ## ticks ax = ax + line([[-0.5, -0.01], [-0.5, 0.01]], color="black") ax = ax + line([[0.5, -0.01], [0.5, 0.01]], color="black") g = g + ax if model == "H": t = text(name, (0, -0.1), fontsize=16, color="black") t = t + text("$ -\\frac{1}{2} $", (-0.5, -0.1), fontsize=12, color="black") t = t + text("$ \\frac{1}{2} $", (0.5, -0.1), fontsize=12, color="black") else: t = text(name, (0, -1.1), fontsize=16, color="black") g = g + t g.set_aspect_ratio(1) g.set_axes_range(x0, x1, y0, y1) g.axes(False) if filename is not None: fig = g.matplotlib() fig.set_canvas(FigureCanvasAgg(fig)) axes = fig.get_axes()[0] axes.minorticks_off() axes.set_yticks([]) fig.savefig(filename, **kwds) else: return g
def draw_fundamental_domain(N,group='Gamma0',model="H",axes=None,filename=None,**kwds): r""" Draw fundamental domain INPUT: - ''model'' -- (default ''H'') - ''H'' -- Upper halfplane - ''D'' -- Disk model - ''filename''-- filename to print to - ''**kwds''-- additional arguments to matplotlib - ''axes'' -- set geometry of output =[x0,x1,y0,y1] -- restrict figure to [x0,x1]x[y0,y1] EXAMPLES:: sage: G=MySubgroup(Gamma0(3)) sage: G.draw_fundamental_domain() """ G=eval(group+'('+str(N)+')') #print G name ="$"+latex(G)+"$" ## need a "nice" set of coset representatives to draw a connected fundamental domain. Only implemented for Gamma_0(N) coset_reps = nice_coset_reps(G) if(model=="D"): g=draw_funddom_d(coset_reps,format,I) else: g=draw_funddom(coset_reps,format) if(axes<>None): [x0,x1,y0,y1]=axes elif(model=="D"): x0=-1 ; x1=1 ; y0=-1.1 ; y1=1 else: # find the width of the fundamental domain w=0 #self.cusp_width(Cusp(Infinity)) wmin=0 ; wmax=1 max_x = RR(0.55) rho = CC( exp(2*pi*I/3)) for V in coset_reps: ## we also compare the real parts of where rho and infinity are mapped r1 = (V.acton(rho)).real() if(V[1,0]<>0): inf1 = RR(V[0,0] / V[1,0]) else: inf1 = 0 if(V[1 ,0 ]==0 and V[0 ,0 ]==1 ): if(V[0 ,1 ]>wmax): wmax=V[0 ,1 ] if(V[0 ,1 ]<wmin): wmin=V[0 ,1 ] if( max(r1,inf1) > max_x): max_x = max(r1,inf1) #print "wmin,wmax=",wmin,wmax #x0=-1; x1=1; y0=-0.2; y1=1.5 x0=RR(-max_x) ; x1=RR(max_x) ; y0=RR(-0.15) ; y1=RR(1.5) ## Draw the axes manually (since can't figure out how to do it automatically) ax = line([[x0,0.0],[x1,0.0]],color='black') #ax = ax + line([[0.0,y0],[0.0,y1]],color='black') ## ticks ax = ax + line([[-0.5,-0.01],[-0.5,0.01]],color='black') ax = ax + line([[0.5,-0.01],[0.5,0.01]],color='black') g = g + ax if model=="H": t = text(name, (0, -0.1), fontsize=16, color='black') else: t = text(name, (0, -1.1), fontsize=16, color='black') g = g + t g.set_aspect_ratio(1) g.set_axes_range(x0,x1,y0,y1) g.axes(False) if(filename<>None): fig = g.matplotlib() fig.set_canvas(FigureCanvasAgg(fig)) axes = fig.get_axes()[0] axes.minorticks_off() axes.set_yticks([]) fig.savefig(filename,**kwds) else: return g
def compute_cm_values_numeric(self,digits=12,insert_in_db=True): r""" Compute CM-values numerically. """ if isinstance(self._cm_values,dict) and self._cm_values <> {}: return self._cm_values # the points we want are i and rho. More can be added later... bits = ceil(int(digits) * int(4)) CF = ComplexField(bits) RF = ComplexField(bits) eps = RF(10 ** - (digits + 1)) if(self._verbose > 1): wmf_logger.debug("eps={0}".format(eps)) K = self.base_ring() # recall that degree = self.degree() cm_vals = dict() rho = CyclotomicField(3).gen() zi = CyclotomicField(4).gen() points = [rho, zi] maxprec = 1000 # max size of q-expansion minprec = 10 # max size of q-expansion for tau in points: q = CF(exp(2 * pi * I * tau)) fexp = dict() cm_vals[tau] = dict() if(tau == I and self.level() == -1): # cv= #"Exact(soon...)" #_cohen_exact_formula(k) for h in range(degree): cm_vals[tau][h] = cv continue if K.absolute_degree()==1: v1 = CF(0) v2 = CF(1) try: for prec in range(minprec, maxprec, 10): if(self._verbose > 1): wmf_logger.debug("prec={0}".format(prec)) v2 = self.as_factor().q_eigenform(prec).truncate(prec)(q) err = abs(v2 - v1) if(self._verbose > 1): wmf_logger.debug("err={0}".format(err)) if(err < eps): raise StopIteration() v1 = v2 cm_vals[tau][0] = None except StopIteration: cm_vals[tau][0] = v2 else: v1 = dict() v2 = dict() err = dict() for h in range(degree): v1[h] = 1 v2[h] = 0 try: for prec in range(minprec, maxprec, 10): if(self._verbose > 1): wmf_logger.debug("prec={0}".format(prec)) c = self.coefficients(range(prec),insert_in_db=insert_in_db) for h in range(degree): fexp[h] = list() v2[h] = 0 for n in range(prec): cn = c[n] if hasattr(cn, 'complex_embeddings'): cc = cn.complex_embeddings(CF.prec())[h] else: cc = CF(cn) v2[h] = v2[h] + cc * q ** n err[h] = abs(v2[h] - v1[h]) if(self._verbose > 1): wmf_logger.debug("v1[{0}]={1}".format(h,v1[h])) wmf_logger.debug("v2[{0}]={1}".format(h,v2[h])) wmf_logger.debug("err[{0}]={2}".format(h,err[h])) if(max(err.values()) < eps): raise StopIteration() v1[h] = v2[h] except StopIteration: pass for h in range(degree): if(err[h] < eps): cm_vals[tau][h] = v2[h] else: cm_vals[tau][h] = None self._cm_values = cm_vals
def __init__(self, f, ring, verbose = False): """ input: f a polynomial over a number field ring: Complex Field (with some prescribed precision) where we will work over We represent a divisor z \in Pic**0 by a divisor in D on X such that z = [D - D_0] where D_0 is a fixed divisor of degree d_0 \deg D = d_0 A divisor D on X is then represented by vector space H**0(\delta - D) for this representation to be faithful we need \delta - D to be base point free for that is sufficient \deg \delta >= \deg D + 2g, as we will be dealing with divisors of degree d_0 and 2d_0 we pick \delta = 3 * D_0 a vector space H**0(-) is represented by a bases of rational functions on X and these functions are represented by its evaluation at an effective divisor Z During our computations every function will lie in H**0(3D_0) or H**0(6D_0). Hence, for this representation to be faithful, it is necessary and sufficient that H**0({3,6}D_0 - Z) = {0}, eg \deg D_0 = 6 d_0 + 1. If possible \supp D_0 \cap \supp Z = empty set would be ideal. In summary, a vector space W will be represented with \deg Z rows and \dim columns. """ self.verbose = verbose; assert is_CF(ring) self.R = ring; self.prec = ring.precision() self.f = f; self.a0 = list(f)[0]; self.an = list(f)[-1]; self.g = int(ceil( f.degree() / 2 ) - 1); self.d0 = 2 * self.g + 2; self.extraprec = self.prec + 3 * self.d0 + 16; self.Rextraprec = ComplexField(self.extraprec); self.Rdoubleextraprec = ComplexField(2*self.extraprec) self.Pi = self.Rdoubleextraprec.pi(); self.I = self.Rdoubleextraprec(0, 1); self.almostzero = self.R(2)**(- self.prec * 0.7); self.notzero = self.R(2)**(- self.prec * 0.1); self.lower = 0; # D_0 = (g + 1)*( \infty_{-} + \infty_{+} ) = (g + 1) * \infty # Pick the effective divisor Z, ie, the evaluation points # Pick evaluation points /!\ Weierstrass pts ! # in theory we only need \deg Z >= 6 d_0 + 1 # in practice we aim for >= 6 d_0 + 2 self.nZ = 6 * self.d0 + 2; if self.verbose: print "Using %s points on the unit circle, almost uniformly spaced, to represent each function" % ( self.nZ, ) n = self.nZ; n = ceil(self.nZ/2); Z=[] while len(Z) < self.nZ: # X computed in self.Rdoubleextraprec X = [ exp( 2 * k * self.I * self.Pi / n ) for k in range(n) ] Z = []; for i, x in enumerate(X): #y = (-1)**i * sqrt( f(x) ) #Z.append( (x, y) ) # # x in self.Rdoubleextraprec ! y = self.Rextraprec( sqrt( self.f(x) ) ) x = self.Rextraprec( x ) # making sure the points don't collide if y.abs() < 1e-2: Z.append( (x, y) ) else: Z.append( (x, y) ) Z.append( (x, -y) ) n += 1 self.Z = Z; self.nZ = len(Z); #alternatively self.Z = Z[:self.nZ], but this might lose some of the good properties of having the points uniformly on the unit circle # V represents H**0 (3 D_0) V = Matrix(self.Rextraprec, self.nZ, 3 * self.d0 + 1 - self.g) # \dim = 6g + 6 + 1 - g = 5 g + 7 # Vout represents H**0(D_0) Vout = Matrix(self.Rextraprec, self.nZ, self.d0 + 1 - self.g) # \dim = g + 3 # H**0(D_0) = <1, x, x**2, ..., x**(g + 1), y> # H**0(3*D_0) = <1, x, x**2, ...,x**g, x**(g + 1), y, x**(g + 2) , y x, ..., x**(g + 1 + 2g + 2), y x**(2g + 2)>, dim = 5 g + 7 = 1 + g + 2*(2*g + 3) Vexps = [None]* (3 * self.d0 + 1 - self.g) i = 0; for n in xrange( 3 * (self.g + 1) + 1): Vexps[i] = [ n, 0]; i += 1; if n > self.g: Vexps[i] = [ n - self.g - 1, 1]; i += 1; for i, (x, y) in enumerate(self.Z): for j in range( 3 * self.d0 + 1 - self.g): V[ i, j] = x ** Vexps[j][0] * y ** Vexps[j][1] for j in range( self.g + 2 ): Vout[i,j] = x**j Vout[ i, self.g + 2] = y self.V = V; self.Vout = Vout; self.Vexps = Vexps; # W0 represents H**0 (2 D_0) W0 = Matrix(self.Rextraprec, self.nZ, 2 * self.d0 + 1 - self.g) for i in range( self.nZ ): for j in range( 2 * self.d0 + 1 - self.g): W0[i,j] = V[i,j] # KV = Ker(V***) = col(V)**perp KV, upper, lower = EqnMatrix(V, 3 * self.d0 + 1 - self.g); assert self.threshold_check(upper, lower), "upper = %s lower = %s" % (RealField(35)(upper), RealField(35)(lower)) self.lower = max(self.lower, lower) self.KV = KV; self.W0 = W0;
def stratum2print(stratum): if not stratum: return '[]' stratum = Counter(stratum) ans = ['['] for order in sorted(stratum.keys(), reverse=True): mult = stratum[order] if mult == 1: ans.extend([f'{order}', ',']) else: ans.extend([f'{order}^{mult}', ',']) ans[-1] = ']' return ''.join(ans) time_for_F = lambda w: N(exp(0.39 * w - 6.7)) time_for_Fs2 = lambda w: N(exp(0.38 * w - 5.2)) time_for_Fs3 = lambda w: N(exp(0.38 * w - 5)) time_for_Fs4 = lambda w: N(exp(0.71 * w - 6.4)) time_for_Fs22 = lambda w: N(exp(0.63 * w - 4.8)) time_for_Fs5 = lambda w: N(exp(0.68 * w - 5.5)) time_for_Fs23 = lambda w: N(exp(0.75 * w - 4.6)) time_for_Fs6 = lambda w: N(exp(0.885 * w - 3.8)) time_for_Fs24 = lambda w: N(exp(0.96 * w - 3.6)) time_for_Fs33 = lambda w: N(exp(0.745 * w - 3.8)) time_for_Fs7 = lambda w: N(exp(0.96 * w - 3.6)) time_for_Fs222 = lambda w: N(exp(w - 2.25)) def dfactorial(n): '''
def dimension(self, k, ignore=False, debug=0): if k < 2 and not ignore: raise NotImplementedError("k has to >= 2") s = self._signature if not (2 * k in ZZ): raise ValueError("k has to be integral or half-integral") if (2 * k + s) % 4 != 0 and not ignore: raise NotImplementedError( "2k has to be congruent to -signature mod 4") if self._v2.has_key(0): v2 = self._v2[0] else: v2 = 1 if self._g != None: if not self._aniso_formula: vals = self._g.values() #else: #print "using aniso_formula" M = self._g else: vals = self._M.values() M = self._M prec = ceil(max(log(M.order(), 2), 52) + 1) + 17 #print prec RR = RealField(prec) CC = ComplexField(prec) d = self._d m = self._m if debug > 0: print d, m if self._alpha3 == None: if self._aniso_formula: self._alpha4 = 1 self._alpha3 = -sum( [BB(a) * mm for a, mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += Integer(d) - Integer( 1) - self._g.beta_formula() #print self._alpha3, self._g.a5prime_formula() self._alpha3 = self._alpha3 / RR(2) else: self._alpha3 = sum([(1 - a) * mm for a, mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += sum([(1 - a) * mm for a, mm in vals.iteritems() if a != 0]) #print self._alpha3 self._alpha3 = self._alpha3 / Integer(2) self._alpha4 = 1 / Integer(2) * ( vals[0] + v2) # the codimension of SkL in MkL alpha3 = self._alpha3 alpha4 = self._alpha4 if debug > 0: print alpha3, alpha4 g1 = M.char_invariant(1) g1 = CC(g1[0] * g1[1]) #print g1 g2 = M.char_invariant(2) g2 = RR(real(g2[0] * g2[1])) if debug > 0: print g2, g2.parent() g3 = M.char_invariant(-3) g3 = CC(g3[0] * g3[1]) if debug > 0: print RR(d) / RR(4), sqrt(RR(m)) / RR(4), CC( exp(2 * CC.pi() * CC(0, 1) * (2 * k + s) / Integer(8))) alpha1 = RR(d) / RR(4) - (sqrt(RR(m)) / RR(4) * CC( exp(2 * CC.pi() * CC(0, 1) * (2 * k + s) / Integer(8))) * g2) if debug > 0: print alpha1 alpha2 = RR(d) / RR(3) + sqrt(RR(m)) / (3 * sqrt(RR(3))) * real( exp(CC(2 * CC.pi() * CC(0, 1) * (4 * k + 3 * s - 10) / 24)) * (g1 + g3)) if debug > 0: print alpha1, alpha2, g1, g2, g3, d, k, s dim = real(d + (d * k / Integer(12)) - alpha1 - alpha2 - alpha3) if debug > 0: print "dimension:", dim if abs(dim - round(dim)) > 1e-6: raise RuntimeError( "Error ({0}) too large in dimension formula for {1} and k={2}". format(abs(dim - round(dim)), self._M if self._M is not None else self._g, k)) dimr = dim dim = Integer(round(dim)) if k >= 2 and dim < 0: raise RuntimeError("Negative dimension (= {0}, {1})!".format( dim, dimr)) return dim
def draw_fundamental_domain(N, group='Gamma0', model="H", axes=None, filename=None, **kwds): r""" Draw fundamental domain INPUT: - ''model'' -- (default ''H'') = ''H'' -- Upper halfplane = ''D'' -- Disk model - ''filename''-- filename to print to - ''**kwds''-- additional arguments to matplotlib - ''axes'' -- set geometry of output =[x0,x1,y0,y1] -- restrict figure to [x0,x1]x[y0,y1] EXAMPLES:: sage: G=MySubgroup(Gamma0(3)) sage: G.draw_fundamental_domain() """ if group.strip() == 'Gamma0': G = Gamma0(N) elif group.strip() == 'Gamma1': G = Gamma1(N) elif group.strip() == 'Gamma': G = Gamma(N) else: raise ValueError('group must be one of: "Gamma0", "Gamma1", "Gamma"') s = "$" + latex(G) + "$" s = s.replace("mbox", "mathrm") s = s.replace("Bold", "mathbb") name = s # name ="$\mbox{SL}_{2}(\mathbb{Z})$" # need a "nice" set of coset representatives to draw a connected # fundamental domain. Only implemented for Gamma_0(N) coset_reps = nice_coset_reps(G) # if(group=='Gamma0'): # else: # coset_reps = list(G.coset_reps()) from matplotlib.backends.backend_agg import FigureCanvasAgg if (model == "D"): g = _draw_funddom_d(coset_reps, format, I) else: g = _draw_funddom(coset_reps, format) if (axes is not None): [x0, x1, y0, y1] = axes elif (model == "D"): x0 = -1 x1 = 1 y0 = -1.1 y1 = 1 else: # find the width of the fundamental domain # w = 0 # self.cusp_width(Cusp(Infinity)) FIXME: w is never used wmin = 0 wmax = 1 max_x = RR(0.55) rho = CC(exp(2 * pi * I / 3)) for V in coset_reps: ## we also compare the real parts of where rho and infinity are mapped r1 = (V.acton(rho)).real() if (V[1, 0] != 0): inf1 = RR(V[0, 0] / V[1, 0]) else: inf1 = 0 if (V[1, 0] == 0 and V[0, 0] == 1): if (V[0, 1] > wmax): wmax = V[0, 1] if (V[0, 1] < wmin): wmin = V[0, 1] if (max(r1, inf1) > max_x): max_x = max(r1, inf1) logging.debug("wmin,wmax=%s,%s" % (wmin, wmax)) # x0=-1; x1=1; y0=-0.2; y1=1.5 x0 = RR(-max_x) x1 = RR(max_x) y0 = RR(-0.15) y1 = RR(1.5) ## Draw the axes manually (since can't figure out how to do it automatically) ax = line([[x0, 0.0], [x1, 0.0]], color='black') # ax = ax + line([[0.0,y0],[0.0,y1]],color='black') ## ticks ax = ax + line([[-0.5, -0.01], [-0.5, 0.01]], color='black') ax = ax + line([[0.5, -0.01], [0.5, 0.01]], color='black') g = g + ax if model == "H": t = text(name, (0, -0.1), fontsize=16, color='black') t = t + text( "$ -\\frac{1}{2} $", (-0.5, -0.1), fontsize=12, color='black') t = t + text( "$ \\frac{1}{2} $", (0.5, -0.1), fontsize=12, color='black') else: t = text(name, (0, -1.1), fontsize=16, color='black') g = g + t g.set_aspect_ratio(1) g.set_axes_range(x0, x1, y0, y1) g.axes(False) if (filename is not None): fig = g.matplotlib() fig.set_canvas(FigureCanvasAgg(fig)) axes = fig.get_axes()[0] axes.minorticks_off() axes.set_yticks([]) fig.savefig(filename, **kwds) else: return g
def directionalFailureboosting(lwe_n, q, sd, B, m, name, limitedqueries=False, multitarget=False): alphabetalist = [] for i in range(0, CIPHERTEXTS): alpha = np.loadtxt('%s/tmp/alpha%d.txt' % (name, i)) beta = np.loadtxt('%s/tmp/beta%d.txt' % (name, i)) alphabetalist.append((alpha, beta, i)) # save the work needed to get x ciphertexts worklist = [] querylist = [] problist = [] # save the work needed to get x ciphertexts (old method) workoldlist = [] queryoldlist = [] proboldlist = [] # save the work needed to get the next ciphertext worknextciphertext = [] querynextciphertext = [] # number of ciphertexts x ciphertextlist = [] # list of optimal alpha beta values ablist = [] # set by hand if multitarget and limitedqueries: LMT = 59.5 if not multitarget and limitedqueries: LMT = 57.2 firstmt = not multitarget # if multitarget attack: don't restrict first sample for alphabetavalues in alphabetalist: # add new ciphertext alphac, betac, ciphertexts = alphabetavalues optimalab = min([(np.sqrt(a) * b**-1, b**-1, a) for a, b in zip(alphac, betac)], key=lambda x: x[0]) if limitedqueries and firstmt and optimalab[1] > 2**LMT: if max(betac) <= 2**-LMT: with open(name + '/attackcost.txt', 'a') as f: print('attack not possible for: limited queries: %r, multitarget %r' % (limitedqueries, multitarget)) print('attack not possible for: limited queries: %r, multitarget %r' % (limitedqueries, multitarget), file=f) return 0 idx = np.where(betac > 2**-LMT)[0][-1] optimalab = (np.sqrt(alphac[idx]) * betac[idx]**-1, betac[idx]**-1, alphac[idx]) firstmt = True ablist.append(optimalab) ciphertextlist.append(len(ablist)) worknextciphertext.append(optimalab[0]) querynextciphertext.append(optimalab[1]) # calculate the best attack strategy # setup the lagrange function and solve vlam = var('vlam') eq = 1 normalizer = ablist[0][0] for ab, b, a in ablist: eq *= vlam + (ab / normalizer) eq -= vlam**len(ablist) / (1 - exp(-1)) lam = find_root(eq, 0.001, 500000) # calculate the amount of work to get the next failure and sum work = 0 prob = 1 queries = 0 ab, b, a = ablist[0] l = np.log(lam * (normalizer / ab) + 1) if multitarget: queries += l * b / 2**64 else: queries = l * b work += l * ab prob *= 1 - exp(-l) for ab, b, a in ablist[1:]: l = np.log(lam * (normalizer / ab) + 1) queries += l * b work += l * ab prob *= 1 - exp(-l) # traditional method ab, b, a = ablist[0] queriesold = b * len(ablist) workold = ab * len(ablist) probold = 1 - exp(-1) # save all our results worklist.append(work) querylist.append(queries) problist.append(prob) workoldlist.append(workold) queryoldlist.append(queriesold) proboldlist.append(prob) # and print with open(name + '/attackcost.txt', 'a') as f: print('\n limited queries: %r, multitarget %r' % (limitedqueries, multitarget), file=f) print('work to obtain %d ciphertexts with same probability:' % len(ablist), file=f) print('queries: %f, total work:%f, probability: %f' % (np.log2(float(queries)), np.log2(float(work)), prob), file=f) ################ # Let's plot # ################ plt.loglog(ciphertextlist, worklist, label='work', basex=2, basey=2) if not multitarget: plt.loglog(ciphertextlist, workoldlist, label='work - traditional', basex=2, basey=2) plt.loglog(ciphertextlist, querylist, label='queries', basex=2, basey=2) if not multitarget: plt.loglog(ciphertextlist, queryoldlist, label='queries - traditional', basex=2, basey=2) plt.title('work/queries to obtain n ciphertexts') plt.xlabel(u'ciphertexts') plt.ylabel(u'total work/queries') plt.legend(loc='lower right') plt.tight_layout() plt.savefig(name + '/workqueriesforxciphertexts-LQ%r,MT%r.pdf' % (limitedqueries, multitarget)) # plt.show() plt.clf() plt.rcParams.update({'font.size': 16}) plt.loglog(ciphertextlist, worklist, label='work', basex=2, basey=2) if not multitarget: plt.loglog(ciphertextlist, workoldlist, label='work - traditional', basex=2, basey=2, linestyle='dashed') plt.title('work to obtain n ciphertexts') plt.xlabel(u'ciphertexts') plt.ylabel(u'total work') plt.legend(loc='upper left') plt.tight_layout() plt.savefig(name + '/workforxciphertexts-LQ%r,MT%r.pdf' % (limitedqueries, multitarget)) # plt.show() plt.clf() plt.rcParams.update({'font.size': 16}) plt.loglog(ciphertextlist, querylist, label='queries', basex=2, basey=2) if not multitarget: plt.loglog(ciphertextlist, queryoldlist, label='queries - traditional', basex=2, basey=2, linestyle='dashed') plt.title('queries to obtain n ciphertexts') plt.xlabel(u'ciphertexts') plt.ylabel(u'total queries') plt.legend(loc='upper left') plt.tight_layout() plt.savefig(name + '/queriesforxciphertexts-LQ%r,MT%r.pdf' % (limitedqueries, multitarget)) # plt.show() plt.clf() plt.rcParams.update({'font.size': 16}) plt.loglog(ciphertextlist, worknextciphertext, label='work', basex=2, basey=2) plt.loglog(ciphertextlist, querynextciphertext, label='query', basex=2, basey=2) plt.title('work/queries to obtain next ciphertexts') plt.xlabel(u'available failing ciphertexts') plt.ylabel(u'total work/queries') plt.legend(loc='lower left') plt.tight_layout() plt.savefig(name + '/worknextciphertext-LQ%r,MT%r.pdf' % (limitedqueries, multitarget)) # plt.show() plt.clf() plt.rcParams.update({'font.size': 10})
def draw_fundamental_domain(N, group='Gamma0', model="H", axes=None, filename=None, **kwds): r""" Draw fundamental domain INPUT: - ''model'' -- (default ''H'') - ''H'' -- Upper halfplane - ''D'' -- Disk model - ''filename''-- filename to print to - ''**kwds''-- additional arguments to matplotlib - ''axes'' -- set geometry of output =[x0,x1,y0,y1] -- restrict figure to [x0,x1]x[y0,y1] EXAMPLES:: sage: G=MySubgroup(Gamma0(3)) sage: G.draw_fundamental_domain() """ G = eval(group + '(' + str(N) + ')') #print G name = "$" + latex(G) + "$" ## need a "nice" set of coset representatives to draw a connected fundamental domain. Only implemented for Gamma_0(N) coset_reps = nice_coset_reps(G) if (model == "D"): g = draw_funddom_d(coset_reps, format, I) else: g = draw_funddom(coset_reps, format) if (axes <> None): [x0, x1, y0, y1] = axes elif (model == "D"): x0 = -1 x1 = 1 y0 = -1.1 y1 = 1 else: # find the width of the fundamental domain w = 0 #self.cusp_width(Cusp(Infinity)) wmin = 0 wmax = 1 max_x = RR(0.55) rho = CC(exp(2 * pi * I / 3)) for V in coset_reps: ## we also compare the real parts of where rho and infinity are mapped r1 = (V.acton(rho)).real() if (V[1, 0] <> 0): inf1 = RR(V[0, 0] / V[1, 0]) else: inf1 = 0 if (V[1, 0] == 0 and V[0, 0] == 1): if (V[0, 1] > wmax): wmax = V[0, 1] if (V[0, 1] < wmin): wmin = V[0, 1] if (max(r1, inf1) > max_x): max_x = max(r1, inf1) #print "wmin,wmax=",wmin,wmax #x0=-1; x1=1; y0=-0.2; y1=1.5 x0 = RR(-max_x) x1 = RR(max_x) y0 = RR(-0.15) y1 = RR(1.5) ## Draw the axes manually (since can't figure out how to do it automatically) ax = line([[x0, 0.0], [x1, 0.0]], color='black') #ax = ax + line([[0.0,y0],[0.0,y1]],color='black') ## ticks ax = ax + line([[-0.5, -0.01], [-0.5, 0.01]], color='black') ax = ax + line([[0.5, -0.01], [0.5, 0.01]], color='black') g = g + ax if model == "H": t = text(name, (0, -0.1), fontsize=16, color='black') else: t = text(name, (0, -1.1), fontsize=16, color='black') g = g + t g.set_aspect_ratio(1) g.set_axes_range(x0, x1, y0, y1) g.axes(False) if (filename <> None): fig = g.matplotlib() fig.set_canvas(FigureCanvasAgg(fig)) axes = fig.get_axes()[0] axes.minorticks_off() axes.set_yticks([]) fig.savefig(filename, **kwds) else: return g
def _sage_(self): import sage.all as sage return sage.exp(self.args[0]._sage_())
def populate_rational_rows(orbits, euler_factors_cc, rows, instances): rational_rows = {} order_of_vanishing = schema_lf_dict['order_of_vanishing'] accuracy = schema_lf_dict['accuracy'] positive_zeros = schema_lf_dict['positive_zeros'] sign_arg = schema_lf_dict['sign_arg'] Lhash = schema_lf_dict['Lhash'] plot_delta = schema_lf_dict['plot_delta'] plot_values = schema_lf_dict['plot_values'] central_character = schema_lf_dict['central_character'] positive_zeros = schema_lf_dict['positive_zeros'] leading_term = schema_lf_dict['leading_term'] root_number = schema_lf_dict['root_number'] k = 0 for mf_orbit_label, labels in orbits.iteritems(): try: level, weight, char_orbit, hecke_orbit = mf_orbit_label.split(".") level, weight = map(int, [level, weight]) # read and convert zeros to str # is important to do this before converting them zeros_as_real = [] root_numbers = [] for elt in labels: zeros_factor = rows[elt][positive_zeros] zeros_as_real.extend( zeros_factor ) # and now convert them to strings zeros_factor = [ z.str(truncate=False) for z in zeros_factor] rows[elt][positive_zeros] = str(zeros_factor).replace("'","\"") # same for root numbers root_numbers.append(rows[elt][root_number]) rows[elt][root_number] = rows[elt][root_number].str(style="question").replace('?', '') # for now skip degree > 80 # no more, now the limit is 40 if len(labels) > 20: # the real limit is 87 continue degree = 2*len(labels) row = constant_lf(level, weight, degree) row['origin'] = "ModularForm/GL2/Q/holomorphic/%d/%d/%s/%s" % (level, weight, char_orbit, hecke_orbit) row['self_dual'] = True row['conjugate'] = '\N' row['order_of_vanishing'] = sum([rows[elt][order_of_vanishing] for elt in labels]) row['accuracy'] = min([rows[elt][accuracy] for elt in labels]) zeros_as_real.sort() zeros_as_str = [ z.str(truncate=False) for z in zeros_as_real] row['positive_zeros'] = str(zeros_as_str).replace("'","\"") row['Lhash'] = ",".join(map(str, sorted([int(rows[elt][Lhash]) for elt in labels]))) for i in range(0,3): row['z' + str(i + 1)] = str(zeros_as_real[i]) # character if degree == 2: row['central_character'] = rows[labels[0]][central_character] else: G = DirichletGroup_conrey(level) chiprod = prod([G[ int(rows[elt][central_character].split(".")[-1]) ] for elt in labels]) chiprod_index = chiprod.number() row['central_character'] = "%s.%s" % (level, chiprod_index) row['sign_arg'] = sum([rows[elt][sign_arg] for elt in labels]) while row['sign_arg'] > 0.5: row['sign_arg'] -= 1 while row['sign_arg'] <= -0.5: row['sign_arg'] += 1 deltas = [rows[elt][plot_delta] for elt in labels] values = [rows[elt][plot_values] for elt in labels] row['plot_delta'], row['plot_values'] = prod_plot_values(deltas, values) row['leading_term'] = (prod(toRRR(rows[elt][leading_term], drop=False) for elt in labels)).str(style="question").replace('?', '') try: row['root_number'] = str(RRR(prod(root_numbers).real()).unique_integer()) if row['root_number'] == str(1): row['sign_arg'] = 0 elif row['root_number'] == str(-1): row['sign_arg'] = 0.5 else: assert row['root_number'] in map(str, [1, -1]), "%s" % row['root_number'] except ValueError: # couldn't pin down the unique integer through root_numbers row['root_number'] = str(RRR(CDF(exp(2*pi*I*row['sign_arg'])).real()).unique_integer()) row['coefficient_field'] = '1.1.1.1' euler_factors = [euler_factors_cc[elt] for elt in labels] row['euler_factors'], row['bad_lfactors'], dirichlet = rational_euler_factors(euler_factors, level, weight) # fill in ai for i, ai in enumerate(dirichlet): if i > 1: row['a' + str(i)] = int(dirichlet[i]) #print 'a' + str(i), dirichlet[i] for key in schema_lf: assert key in row, "%s not in row = %s" % (key, row.keys()) for key in row.keys(): assert key in schema_lf, "%s unexpected" % key assert len(row) == len(schema_lf), "%s != %s" % (len(row) , len(schema_lf)) #rewrite row as a list rational_rows[mf_orbit_label] = [row[key] for key in schema_lf] instances[mf_orbit_label] = (row['origin'], row['Lhash'], 'CMF') # if dim == 1, drop row if len(labels) == 1: rows.pop(labels[0]) instances.pop(labels[0]) except Exception: print mf_orbit_label, labels raise k += 1 if len(orbits) > 10: if (k % (len(orbits)//10)) == 0: print "populate_rational_rows %.2f%% done" % (k*100./len(orbits)) print "populate_rational_rows done" return rational_rows
def gaussum(n, N, prec=53): CC = ComplexField(prec) return sum(CC(exp(2 * CC.pi() * CC(0, 1) * n * m ** 2 / N)) for m in range(N))
def _hyperbolic_arc_d(self, z0, z3, first=False): """ Function to construct Bezier path as an approximation to the hyperbolic arc between the complex numbers z0 and z3 in the hyperbolic plane. """ w0 = self._cayley_transform(z0) w3 = self._cayley_transform(z3) if self._verbose>0: print "in plane z0,z3=",z0,z3 print "in disc: ",w0,w3 npts = 10 if z0 == infinity or z0==CC(infinity): zm = [z3 + I*(j+0.5) for j in range(npts)] wm = [self._cayley_transform(x) for x in zm] pts = [w3] pts.extend(wm) pts.append(w0) opt = self._options opt['fill']=False self._graphics.add_primitive(BezierPath([[(x.real(),x.imag()) for x in pts ]],opt)) return if z3 == infinity or z3==CC(infinity): zm = [z0 + I*(j+0.5) for j in range(npts)] wm = [self._cayley_transform(x) for x in zm] pts = [w0] pts.extend(wm) pts.append(w3) opt = self._options opt['fill']=False self._graphics.add_primitive(BezierPath([[(x.real(),x.imag()) for x in pts ]],opt)) #self._graphics.add_primitive(Line([w1.real(),w2.real()],[w1.imag(),w2.imag()],self._options)) #self.path.append([(0,w0.imag()),CC(0,y), (0,w3.imag())]) return x0=z0.real(); y0 = z0.imag() x3=z3.real(); y3 = z3.imag() if y0 == 0 and y3 == 0: p = (z0.real()+z3.real())/2 r = abs(z0-p) zm = CC(p, r) self._hyperbolic_arc_d(z0, zm, first) self._hyperbolic_arc_d(zm, z3) return else: p = ((x0+x3)*(x3-x0)+(y0+y3)*(y3-y0))/(2*(x3-x0)) r = sqrt((p - x0)**2 + y0**2) # radius of the circle in H zm = ((z0+z3)/2-p)/abs((z0+z3)/2-p)*r+p # midpoint (at least approximately) of geodesic between z0 and z3 t0 = CC(z0 - p).argument() t3 = CC(z3 - p).argument() if x0 <= x3: zm = [p + r*exp(I*(t0+t*(t3-t0)/npts)) for t in range(npts+1)] #print "zm=",zm else: zm = [p + r*exp(I*(t0+t*(t3-t0)/npts)) for t in range(npts+1)] #print "zm=",zm wm = [self._cayley_transform(x) for x in zm] opt = self._options opt['fill']=False w0 = self._cayley_transform(z0) w3 = self._cayley_transform(z3) pts = [w0] pts.extend(wm) pts.append(w3) self._graphics.add_primitive(BezierPath([[(x.real(),x.imag()) for x in pts ]],opt)) return #print "z0_test=",(p+r*exp(t0*I)) #print "z3_test=",(p+r*exp(t3*I)) #t = (8*zm-4*(z0+z3)).imag()/3/(z3-z0).real() # I have no idea what these points should represent.... #z1 = z0 + t*CC(z0.imag(), (p-z0.real())) #z2 = z3 - t*CC(z3.imag(), (p-z3.real())) wm = [self._cayley_transform(x) for x in zm] pp = self._cayley_transform(CC(p,0)) w1 = self._cayley_transform(z0) w2 = self._cayley_transform(z3) c = self._cayley_transform(CC(p,0)) # center of circle on the unit disk. if self._verbose>0: print "p,r=",p,r print "zm=",zm #print "t=",t #print "tt=",(8*zm-4*(z0+z3)).imag()/3/(z3-z0).real() print "C(c)=",pp print "C(zm)=",wm print "C(z0)=",w1 print "C(z3)=",w2 #print "z2=",z2 r = abs(w1-c) # radius t0 = CC(w0 - pp).argument() t3 = CC(w3 - pp).argument() t = abs(t0-t3) if self._verbose>0: print "adding a:rc ",zm.real(),zm.imag(),r,r,t,t0,t3 self._graphics.add_primitive(Line([w1.real(),w2.real(),wm.real()],[w1.imag(),w2.imag(),wm.imag()],{'thickness':2,'alpha':1, 'rgbcolor':'blue', 'legend_label':""})) self._graphics.add_primitive(Point([w1.real(),w2.real(),wm.real()],[w1.imag(),w2.imag(),wm.imag()],{'size':10,'alpha':1, 'faceted':True, 'rgbcolor':'red', 'legend_label':""}))
def populate_rational_rows(): order_of_vanishing = schema_lf_dict['order_of_vanishing'] accuracy = schema_lf_dict['accuracy'] sign_arg = schema_lf_dict['sign_arg'] Lhash = schema_lf_dict['Lhash'] plot_delta = schema_lf_dict['plot_delta'] plot_values = schema_lf_dict['plot_values'] central_character = schema_lf_dict['central_character'] # reverse euler factors from the table for p^d < 1000 rational_keys = {} for chi, a, n in rows.keys(): orbit_label = orbit_labels[chi] if (orbit_label, a) not in rational_keys: rational_keys[(orbit_label, a)] = [] rational_keys[(orbit_label, a)].append((chi, a, n)) for (orbit_label, a), triples in rational_keys.iteritems(): # for now skip degree >= 100 if len(triples) > 80: # the real limit is 87 continue pairs = [original_pair[elt] for elt in triples] #print a, pairs, triples chi = triples[0][0] degree = 2 * len(triples) row = constant_lf(level, weight, degree) row['origin'] = rational_origin(chi, a) print row['origin'] row['self_dual'] = 't' row['conjugate'] = '\N' row['order_of_vanishing'] = sum( [rows[elt][order_of_vanishing] for elt in triples]) row['accuracy'] = min([rows[elt][accuracy] for elt in triples]) ### zeros_as_real = [] for elt in triples: zeros_as_real.extend(real_zeros[elt]) zeros_as_real.sort() zeros_as_str = [z.str(truncate=False) for z in zeros_as_real] row['positive_zeros'] = str(zeros_as_str).replace("'", "\"") zeros_hash = sorted([(rows[elt][Lhash], real_zeros[elt][0]) for elt in triples], key=lambda x: x[1]) row['Lhash'] = ",".join([elt[0] for elt in zeros_hash]) # character if degree == 2: row['central_character'] = rows[triples[0]][central_character] else: G = DirichletGroup_conrey(level) chiprod = prod([ G[int(rows[elt][central_character].split(".")[-1])] for elt in triples ]) chiprod_index = chiprod.number() row['central_character'] = "%s.%s" % (level, chiprod_index) row['sign_arg'] = sum([rows[elt][sign_arg] for elt in triples]) while row['sign_arg'] > 0.5: row['sign_arg'] -= 1 while row['sign_arg'] <= -0.5: row['sign_arg'] += 1 zeros_zi = [] for i in range(0, 3): for elt in triples: zeros_zi.append(rows[elt][schema_lf_dict['z' + str(i + 1)]]) zeros_zi.sort(key=lambda x: RealNumber(x)) for i in range(0, 3): row['z' + str(i + 1)] = zeros_zi[i] deltas = [rows[elt][plot_delta] for elt in triples] values = [rows[elt][plot_values] for elt in triples] row['plot_delta'], row['plot_values'] = prod_plot_values( deltas, values) row['leading_term'] = '\N' row['root_number'] = str( RRR(CDF(exp(2 * pi * I * row['sign_arg'])).real()).unique_integer()) if row['root_number'] == str(1): row['sign_arg'] = 0 elif row['root_number'] == str(-1): row['sign_arg'] = 0.5 row['coefficient_field'] = '1.1.1.1' for chi, _, _ in triples: if (level, weight, chi) in traces_lists: for elt in traces_lists[(level, weight, chi)]: if set(elt[1]) <= set(pairs): traces = elt[0] break else: print pairs print traces_lists[(level, weight, chi)] assert False break else: print pairs print traces_lists assert False euler_factors_cc = [euler_factors[elt] for elt in pairs] row['euler_factors'], row[ 'bad_lfactors'], dirichlet = rational_euler_factors( traces, euler_factors_cc, level, weight) #handling Nones row['euler_factors'] = json.dumps(row['euler_factors']) row['bad_lfactors'] = json.dumps(row['bad_lfactors']) # fill in ai for i, ai in enumerate(dirichlet): if i > 1: row['a' + str(i)] = int(dirichlet[i]) #print 'a' + str(i), dirichlet[i] for key in schema_lf: assert key in row, "%s not in row = %s" % (key, row.keys()) for key in row.keys(): assert key in schema_lf, "%s unexpected" % key assert len(row) == len(schema_lf), "%s != %s" % (len(row), len(schema_lf)) #rewrite row as a list rational_rows[(orbit_label, a)] = [row[key] for key in schema_lf] instances[(orbit_label, a)] = tuple_instance(row) # if dim == 1, drop row if len(triples) == 1: rows.pop(triples[0]) instances.pop(triples[0])
def populate_complex_row(Ldbrow): row = dict(constant_lf(level, weight, 2)) chi = int(Ldbrow['chi']) j = int(Ldbrow['j']) chil, a, n = label(chi, j) assert chil == chi row['order_of_vanishing'] = int(Ldbrow['rank']) zeros_as_int = zeros[(chi, j)][row['order_of_vanishing']:] prec = row['accuracy'] = Ldbrow['zeroprec'] two_power = 2**prec double_zeros = [float(z / two_power) for z in zeros_as_int] zeros_as_real = [ RealNumber(z.str() + ".") / two_power for z in zeros_as_int ] real_zeros[(chi, a, n)] = zeros_as_real zeros_as_str = [z.str(truncate=False) for z in zeros_as_real] for i, z in enumerate(zeros_as_str): assert float(z) == double_zeros[i] assert (RealNumber(z) * two_power).round() == zeros_as_int[i] row['positive_zeros'] = str(zeros_as_str).replace("'", "\"") row['origin'] = origin(chi, a, n) row['central_character'] = "%s.%s" % (level, chi) row['self_dual'] = self_dual(chi, a, n) row['conjugate'] = None row['Lhash'] = str((zeros_as_int[0] * 2**(100 - prec)).round()) if prec < 100: row['Lhash'] = '_' + row['Lhash'] Lhashes[(chi, a, n)] = row['Lhash'] row['sign_arg'] = float(Ldbrow['signarg'] / (2 * pi)) for i in range(0, 3): row['z' + str(i + 1)] = (RealNumber(str(zeros_as_int[i]) + ".") / 2**prec).str() row['plot_delta'] = Ldbrow['valuesdelta'] row['plot_values'] = [ float(CDF(elt).real_part()) for elt in struct.unpack('{}d'.format(len(Ldbrow['Lvalues']) / 8), Ldbrow['Lvalues']) ] row['leading_term'] = '\N' if row['self_dual']: row['root_number'] = str( RRR(CDF(exp(2 * pi * I * row['sign_arg'])).real()).unique_integer()) if row['root_number'] == str(1): row['sign_arg'] = 0 elif row['root_number'] == str(-1): row['sign_arg'] = 0.5 else: row['root_number'] = str(CDF(exp(2 * pi * I * row['sign_arg']))) #row['dirichlet_coefficients'] = [None] * 10 #print label(chi,j) for i, ai in enumerate(coeffs[(chi, j)][2:12]): if i + 2 <= 10: row['a' + str(i + 2)] = CBF_to_pair(ai) # print 'a' + str(i+2), ai_jsonb #row['dirichlet_coefficients'][i] = ai_jsonb row['coefficient_field'] = 'CDF' # only 30 row['euler_factors'] = map(lambda x: map(CBF_to_pair, x), euler_factors[(chi, j)][:30]) row['bad_lfactors'] = map( lambda x: [int(x[0]), map(CBF_to_pair, x[1])], bad_euler_factors[(chi, j)]) for key in schema_lf: assert key in row, "%s not in row = %s" % (key, row) assert len(row) == len(schema_lf), "%s != %s" % (len(row), len(schema_lf)) #rewrite row as a list rows[(chi, a, n)] = [row[key] for key in schema_lf] instances[(chi, a, n)] = tuple_instance(row)
def dimension(self,k,ignore=False, debug = 0): if k < 2 and not ignore: raise NotImplementedError("k has to >= 2") s = self._signature if not (2*k in ZZ): raise ValueError("k has to be integral or half-integral") if (2*k+s)%2 != 0: return 0 m = self._m n2 = self._n2 if self._v2.has_key(0): v2 = self._v2[0] else: v2 = 1 if self._g != None: if not self._aniso_formula: vals = self._g.values() #else: #print "using aniso_formula" M = self._g else: vals = self._M.values() M = self._M if (2*k+s)%4 == 0: d = Integer(1)/Integer(2)*(m+n2) # |dimension of the Weil representation on even functions| self._d = d self._alpha4 = 1/Integer(2)*(vals[0]+v2) # the codimension of SkL in MkL else: d = Integer(1)/Integer(2)*(m-n2) # |dimension of the Weil representation on odd functions| self._d = d self._alpha4 = 1/Integer(2)*(vals[0]-v2) # the codimension of SkL in MkL prec = ceil(max(log(M.order(),2),52)+1)+17 #print prec RR = RealField(prec) CC = ComplexField(prec) if debug > 0: print "d, m = {0}, {1}".format(d,m) eps = exp( 2 * CC.pi() * CC(0,1) * (s + 2*k) / Integer(4) ) eps = round(real(eps)) if self._alpha3 is None or self._last_eps != eps: self._last_eps = eps if self._aniso_formula: self._alpha4 = 1 self._alpha3 = -sum([BB(a)*mm for a,mm in self._v2.iteritems() if a != 0]) #print self._alpha3 self._alpha3 += Integer(d) - Integer(1) - self._g.beta_formula() #print self._alpha3, self._g.a5prime_formula() self._alpha3 = self._alpha3/RR(2) else: self._alpha3 = eps*sum([(1-a)*mm for a,mm in self._v2.iteritems() if a != 0]) if debug>0: print "alpha3t = ", self._alpha3 self._alpha3 += sum([(1-a)*mm for a,mm in vals.iteritems() if a != 0]) #print self._alpha3 self._alpha3 = self._alpha3 / Integer(2) alpha3 = self._alpha3 alpha4 = self._alpha4 if debug > 0: print alpha3, alpha4 g1=M.char_invariant(1) g1=CC(g1[0]*g1[1]) #print g1 g2=M.char_invariant(2) g2=CC(g2[0]*g2[1]) if debug > 0: print g2, g2.parent() g3=M.char_invariant(-3) g3=CC(g3[0]*g3[1]) if debug > 0: print "eps = {0}".format(eps) if debug > 0: print "d/4 = {0}, m/4 = {1}, e^(2pi i (2k+s)/8) = {2}".format(RR(d) / RR(4), sqrt(RR(m)) / RR(4), CC(exp(2 * CC.pi() * CC(0,1) * (2 * k + s) / Integer(8)))) if eps == 1: g2_2 = real(g2) else: g2_2 = imag(g2)*CC(0,1) alpha1 = RR(d) / RR(4) - sqrt(RR(m)) / RR(4) * CC(exp(2 * CC.pi() * CC(0,1) * (2 * k + s) / Integer(8)) * g2_2) if debug > 0: print alpha1 alpha2 = RR(d) / RR(3) + sqrt(RR(m)) / (3 * sqrt(RR(3))) * real(exp(CC(2 * CC.pi() * CC(0,1) * (4 * k + 3 * s - 10) / 24)) * (g1 + eps*g3)) if debug > 0: print "alpha1 = {0}, alpha2 = {1}, alpha3 = {2}, g1 = {3}, g2 = {4}, g3 = {5}, d = {6}, k = {7}, s = {8}".format(alpha1, alpha2, alpha3, g1, g2, g3, d, k, s) dim = real(d + (d * k / Integer(12)) - alpha1 - alpha2 - alpha3) if debug > 0: print "dimension:", dim if abs(dim-round(dim)) > 1e-6: raise RuntimeError("Error ({0}) too large in dimension formula for {1} and k={2}".format(abs(dim-round(dim)), self._M if self._M is not None else self._g, k)) dimr = dim dim = Integer(round(dim)) if k >=2 and dim < 0: raise RuntimeError("Negative dimension (= {0}, {1})!".format(dim, dimr)) return dim