def initPari(self): """ initialises the pari version of the curve for fast implementation """ curve = "[" + str(self.a) + "," + str(self.b) + "]" + " , " + str( self.fp) # get string rep of curve self.E = pari('ellinit(' + curve + ')') # create pari version of curve try: self.card = pari(self.E).ellcard() # get cardinality except: pass
def quantize(word): Lq = cypari.pari("[q,0;1,1/q]") Tq = cypari.pari("[q,1;0,1/q]") if len(word) == 0: return cypari.pari("[1,0;0,1]") result = Lq if word[0] == "L" else Tq for c in word[1:]: result *= (Lq if c == "L" else Tq) return result
def rational_p_adic_to_Q(p, initial_segment, period): """ Converts a periodic p-adic expansion in the corresponding irreducible fraction in Q. :Example: >>> rational_p_adic_to_Q(2,'101','1') -3 >>> rational_p_adic_to_Q(2,'1','10') 1/3 >>> rational_p_adic_to_Q(2,'101','') 5 >>> rational_p_adic_to_Q(3,'2','1') 1/2 """ if len(period) == 0: period = '0' value_initial_segment = int(initial_segment[::-1], p) value_period = int(period[::-1], p) padic_fraction = "1/(1-{}^{})".format(p, len(period)) formula_str = "{} + {}^({})*({})*({})".format(value_initial_segment, p, len(initial_segment), value_period, padic_fraction) return cypari.pari(formula_str)
def isPrime(p): """ uses pari to test for primes (easier to use than my own implementation) """ if p != int(p): return False return pari("isprime(" + str(int(p)) + ")")
def getR(self): """ returns a new generator point if one exists""" generators = pari(self.E).ellgenerators() # get all generators print(str(generators)) # find G if self.G is not None: G = self.G # else generate it else: pG = str(generators[0]) if pG.startswith("[Mod"): Gx = int(pG.split(",")[0].split("(")[1]) # extract x coord Gy = int(pG.split(",")[2].split("(")[1]) # extract y coord else: Gx, Gy = pG.split(",") for gen in generators: pR = str(gen) # get string representation if pR.startswith("[Mod"): Rx = int(pR.split(",")[0].split("(")[1]) # extract x coord Ry = int(pR.split(",")[2].split("(")[1]) # extract y coord else: Rx, Ry = str(pR).split(",") if Rx != Gx and Ry != Gy: # if not the same as G return pR # return result return False # return point
def secondCurve(curve, degree): """ creates a second curve over an extended field """ p = pow(curve.fp, degree) field = pari("a = ffgen(" + str(p) + ", 'a)") curve2str = "[" + str(curve.a) + "," + str( curve.b) + "]" + ", " + str(field) curve2 = pari("E2 = ellinit(" + curve2str + ")") c = Curve() c.setE(curve2) return c.getR(), c
def cyclicLog(G, Q, o): """ answers the log problem of G = Q^k over a cyclic field of order o """ # might not work try: return pari('fflog(' + G + ',' + Q + ',' + o + ')') except: return 0
def weil(self, G, P, m): """ uses pari to compute the weil paring of a point on the curve to a new prime extension field """ P = "[" + str(P.x) + "," + str( P.y) + "]" # string representation of point wP = pari("ellweilpairing(" + str(self.E) + ", " + str(G) + "," + P + "," + str(m) + ")") return str(wP)
def Collatz_rational_2_adic(segment_init, period): """ Returns the Collatz sequence (until cycle) of the rational 2-adic number given by its initial segment and period. The function also returns the closest element to 0 in the cycle that is reached. :Example: >>> Collatz_rational_2_adic('1','10') ([1/3, 1, 2, 1], 1) >>> Collatz_rational_2_adic('01','01') ([-2/3, -1/3, 0, 0], 0) >>> Collatz_rational_2_adic('0111','01') ([10/3, 5/3, 3, 5, 8, 4, 2, 1, 2], 1) >>> Collatz_rational_2_adic('1','011') ([-5/7, -4/7, -2/7, -1/7, 2/7, 1/7, 5/7, 11/7, 20/7, 10/7, 5/7], 5/7) >>> Collatz_rational_2_adic('1011','1') ([-3, -4, -2, -1, -1], -1) >>> Collatz_rational_2_adic('101101','1') ([-19, -28, -14, -7, -10, -5, -7], -5) """ rational_2adic = rational_p_adic_to_Q(2, segment_init, period) CollatzSeq = [rational_2adic] seen = {} while True: numerator = cypari.pari('numerator({})'.format(rational_2adic)) # Cannot just call T_0 and T_1 because # `cypari` doesnt like the fact that they use # // instead of / if numerator % 2 == 0: rational_2adic = rational_2adic / 2 else: rational_2adic = (3 * rational_2adic + 1) / 2 CollatzSeq.append(rational_2adic) if rational_2adic in seen: period = [] record = False for element in CollatzSeq: if element == rational_2adic: record = True if record: period.append(element) sign = 1 if min(period) >= 0 else -1 return CollatzSeq, sign * min(map(abs, period)) seen[rational_2adic] = True
def valid(self): """ checks the graph is valid over the real numbers and has actual points on it """ # delta =-16 * (4a^3 + 27b^2) self.discriminant = -16 * (4 * self.a * self.a * self.a + 27 * self.b * self.b) try: orderOfCurve = pari(self.E).ellcard() # try to get order except: return False # if there's an exception the curve has no integer points return self.discriminant != 0
def order(self, point): """ gives the order of a point on the curve """ # check point is on curve first # and pari curve exists if not self.onCurve(point) or self.E is None: return 0 P = "[" + str(point.x) + "," + str( point.y) + "]" # string representation of point # finds order using Schoof-Elkies-Atkin algorithm orderP = pari(self.E).ellorder(P) # use Pari to calculate order return int(orderP)
def getG(self): """ returns a generator point using Pari """ # if exists return it if self.G is not None: return self.G # else generate it pG = pari(self.E).ellgenerators()[0] # get first generator using pari pG = str(pG) # get string representation Gx = int(pG.split(",")[0].split("(")[1]) # extract x coord Gy = int(pG.split(",")[2].split("(")[1]) # extract y coord G = Point(Gx, Gy, self) # create as Point class self.G = G # store result self.ord = self.order(G) # store order return G # return point
def rational_cycle_solution(compact): """ Returns the rational number of which cycle is supported by the\ given parity vector (if not given in the CompactRep format it will be converted). The explicit formula for the solution is (see Wirsching): x = (\sum_{i=0}^{l(s)-1} 3^{l(s)-1-i}2^{i+s_0+...+s_i})/(2^||s|| - 3^l(s)) :Example: >>> rational_cycle_solution(Parvec([1])) -1 >>> rational_cycle_solution(Parvec([1,1,0])) -5 >>> rational_cycle_solution(Parvec([1,1,1,1,0,1,1,1,0,0,0])) -17 >>> rational_cycle_solution(Parvec([1,1,0,1,0,0])) 23/37 >>> rational_cycle_solution(Parvec([0,0,1,0,0])) 4/29 >>> rational_cycle_solution(Parvec([1,1,0,1,1])) -85/49 >>> rational_cycle_solution(Parvec([1,0,0,1,1,1])) -179/17 """ if type(compact) != CompactRep: if type(compact) == Parvec: compact = compact.to_compact() else: return formula_str = "+".join(["3^({})*2^({})".format(compact.span-1-i,i+sum(compact.compact[:i+1])) for i in range(compact.span)]) formula_str = '(' +formula_str + ')/(2^{}-3^{})'.format(compact.norm, compact.span) return cypari.pari(formula_str)
def group(self): """ returns ellgroup """ return str(pari(self.E).ellgroup()[0])
''' A module for representing and manipulating real algebraic numbers and the fields that they live in. ''' from fractions import Fraction from functools import total_ordering from math import log10 as log from numbers import Integral import cypari as cp import sympy as sp from .interval import Interval sp_x = sp.Symbol('x') cp_x = cp.pari('x') def log_plus(x): ''' Return the height of the number ``x``. ''' return log(max(1, abs(x))) def sp_polynomial(coefficients): ''' Return the sympy polynomial with the given coefficients. ''' return sp.Poly(coefficients[::-1], sp_x) def cp_polynomial(coefficients): ''' Return the cypari polynomial with the given coefficients. ''' return cp.pari(' + '.join('{}*x^{}'.format(coefficient, index) for index, coefficient in enumerate(coefficients))) class RealNumberField(object): ''' Represents the NumberField QQ(lmbda) = QQ[x] / << f(x) >> where lmbda is a real root of f(x). ''' def __init__(self, coefficients, index=-1): # List of integers and / or Fractions, integer index
def cp_polynomial(coefficients): ''' Return the cypari polynomial with the given coefficients. ''' return cp.pari(' + '.join('{}*x^{}'.format(coefficient, index) for index, coefficient in enumerate(coefficients)))
#!/usr/bin/python3 # -*- utf-8 -*- # try: from cypari import pari except: print("""To run this program, you have to install the python library cypari with the command ~# pip3 install cypari """) pari.allocatemem(16 * 1024 * 1024) f = open("primes.txt", "r") for line in f: line = line.replace("\n", '') line.strip() try: p = pari(int(line)) except: pass if not p.isprime(): print(p) print("is not prime!!!!!!") else: print("The number is prime") f.close()