def as_subindex(self, index): # The docstring of this method is currently on NDindex.as_subindex, as # this is the only method that is actually implemented so far. from .ndindex import ndindex index = ndindex(index) if not isinstance(index, Slice): raise NotImplementedError( "Slice.as_subindex is only implemented for slices") s = self.reduce() index = index.reduce() if s.step < 0 or index.step < 0: raise NotImplementedError( "Slice.as_subindex is only implemented for slices with positive steps" ) # After reducing, start is not None when step > 0 if index.stop is None or s.stop is None or s.start < 0 or index.start < 0 or s.stop < 0 or index.stop < 0: raise NotImplementedError( "Slice.as_subindex is only implemented for slices with nonnegative start and stop. Try calling reduce() with a shape first." ) # Chinese Remainder Theorem. We are looking for a solution to # # x = s.start (mod s.step) # x = index.start (mod index.step) # # If crt() returns None, then there are no solutions (the slices do # not overlap). res = crt([s.step, index.step], [s.start, index.start]) if res is None: return Slice(0, 0, 1) common, _ = res lcm = ilcm(s.step, index.step) start = max(s.start, index.start) def _smallest(x, a, m): """ Gives the smallest integer >= x that equals a (mod m) Assumes x >= 0, m >= 1, and 0 <= a < m. """ n = int(math.ceil((x - a) / m)) return a + n * m # Get the smallest lcm multiple of common that is >= start start = _smallest(start, common, lcm) # Finally, we need to shift start so that it is relative to index start = (start - index.start) // index.step step = lcm // index.step # = s.step//igcd(s.step, index.step) stop = math.ceil((min(s.stop, index.stop) - index.start) / index.step) if stop < 0: stop = 0 return Slice(start, stop, step)
def find_period_xyz(pos, vel, steps): period = [0, 0, 0] # isolate each axis... for c in [0, 1, 2]: cpos = [] for body in pos: cpos_b = [0, 0, 0] cpos_b[c] = body[c] cpos.append(cpos_b) cvel = [] for bodyv in vel: cvel_b = [0, 0, 0] cvel_b[c] = bodyv[c] cvel.append(cvel_b) # ...and find its period period[c] = find_period(cpos, cvel, steps) return ilcm(*period) # sympy least common multiple
def get_period(self): """ Return a number P such that G(x*exp(I*P)) == G(x). >>> from sympy.functions.special.hyper import meijerg >>> from sympy.abc import z >>> from sympy import pi, S >>> meijerg([1], [], [], [], z).get_period() 2*pi >>> meijerg([pi], [], [], [], z).get_period() oo >>> meijerg([1, 2], [], [], [], z).get_period() oo >>> meijerg([1,1], [2], [1, S(1)/2, S(1)/3], [1], z).get_period() 12*pi """ # This follows from slater's theorem. from sympy import oo, ilcm, pi, Min from sympy.simplify.hyperexpand import Mod1 def compute(l): # first check that no two differ by an integer for i, b in enumerate(l): if not b.is_Rational: return oo for j in range(i + 1, len(l)): if Mod1(b) == Mod1(l[j]): return oo return reduce(ilcm, (x.q for x in l), 1) beta = compute(self.bm) alpha = compute(self.an) p, q = len(self.ap), len(self.bq) if p == q: if beta == oo or alpha == oo: return oo return 2 * pi * ilcm(alpha, beta) elif p < q: return 2 * pi * beta else: return 2 * pi * alpha
def get_period(self): """ Return a number P such that G(x*exp(I*P)) == G(x). >>> from sympy.functions.special.hyper import meijerg >>> from sympy.abc import z >>> from sympy import pi, S >>> meijerg([1], [], [], [], z).get_period() 2*pi >>> meijerg([pi], [], [], [], z).get_period() oo >>> meijerg([1, 2], [], [], [], z).get_period() oo >>> meijerg([1,1], [2], [1, S(1)/2, S(1)/3], [1], z).get_period() 12*pi """ # This follows from slater's theorem. from sympy import oo, ilcm, pi, Min, Mod def compute(l): # first check that no two differ by an integer for i, b in enumerate(l): if not b.is_Rational: return oo for j in range(i + 1, len(l)): if not Mod((b - l[j]).simplify(), 1): return oo return reduce(ilcm, (x.q for x in l), 1) beta = compute(self.bm) alpha = compute(self.an) p, q = len(self.ap), len(self.bq) if p == q: if beta == oo or alpha == oo: return oo return 2 * pi * ilcm(alpha, beta) elif p < q: return 2 * pi * beta else: return 2 * pi * alpha
def answer(num1, num2, lcm): return lcm - ilcm(num1, num2)
def distractor1(num1, num2, gcd): return gcd - ilcm(num1, num2)
def diop_quadratic(var, coeff, t): """ Solves quadratic diophantine equations, i.e equations of the form Ax**2 + Bxy + Cy**2 + Dx + Ey + F = 0. Returns a set containing the tuples (x, y) which contains the solutions. Usage ===== diop_quadratic(var, coeff) -> var is a list of variables and coeff is a dictionary containing coefficients of the symbols. Details ======= ``var`` a list which contains two variables x and y. ``coeff`` a dict which generally contains six key value pairs. The set of keys is {x**2, y**2, x*y, x, y, Integer(1)}. ``t`` the parameter to be used in the solution. Examples ======== >>> from sympy.abc import x, y, t >>> from sympy import Integer >>> from sympy.solvers.diophantine import diop_quadratic >>> diop_quadratic([x, y], {x**2: 1, y**2: 1, x*y: 0, x: 2, y: 2, Integer(1): 2}, t) set([(-1, -1)]) References ========== .. [1] http://www.alpertron.com.ar/METHODS.HTM """ x = var[0] y = var[1] for term in [x**2, y**2, x * y, x, y, Integer(1)]: if term not in coeff.keys(): coeff[term] = Integer(0) A = coeff[x**2] B = coeff[x * y] C = coeff[y**2] D = coeff[x] E = coeff[y] F = coeff[Integer(1)] d = igcd(A, igcd(B, igcd(C, igcd(D, igcd(E, F))))) A = A // d B = B // d C = C // d D = D // d E = E // d F = F // d # (1) Linear case: A = B = C = 0 -> considered under linear diophantine equations # (2) Simple-Hyperbolic case:A = C = 0, B != 0 # In this case equation can be converted to (Bx + E)(By + D) = DE - BF # We consider two cases; DE - BF = 0 and DE - BF != 0 # More details, http://www.alpertron.com.ar/METHODS.HTM#SHyperb l = set([]) if A == 0 and C == 0 and B != 0: if D * E - B * F == 0: if divisible(int(E), int(B)): l.add((-E / B, t)) if divisible(int(D), int(B)): l.add((t, -D / B)) else: div = divisors(D * E - B * F) div = div + [-term for term in div] for d in div: if divisible(int(d - E), int(B)): x0 = (d - E) // B if divisible(int(D * E - B * F), int(d)): if divisible(int((D * E - B * F) // d - D), int(B)): y0 = ((D * E - B * F) // d - D) // B l.add((x0, y0)) # (3) Elliptical case: B**2 - 4AC < 0 # More Details, http://www.alpertron.com.ar/METHODS.HTM#Ellipse # In this case x should lie between the roots of # (B**2 - 4AC)x**2 + 2(BE - 2CD)x + (E**2 - 4CF) = 0 elif B**2 - 4 * A * C < 0: z = symbols("z", real=True) roots = solve((B**2 - 4 * A * C) * z**2 + 2 * (B * E - 2 * C * D) * z + E**2 - 4 * C * F) solve_y = lambda x, e: (-(B * x + E) + e * sqrt( (B * x + E)**2 - 4 * C * (A * x**2 + D * x + F))) / (2 * C) if len(roots) == 1 and isinstance(roots[0], Integer): x_vals = [roots[0]] elif len(roots) == 2: x_vals = [ i for i in range(ceiling(min(roots)), ceiling(max(roots))) ] # ceiling = floor +/- 1 else: x_vals = [] for x0 in x_vals: if isinstance( sqrt((B * x0 + E)**2 - 4 * C * (A * x0**2 + D * x0 + F)), Integer): if isinstance(solve_y(x0, 1), Integer): l.add((Integer(x0), solve_y(x0, 1))) if isinstance(solve_y(x0, -1), Integer): l.add((Integer(x0), solve_y(x0, -1))) # (4) Parabolic case: B**2 - 4*A*C = 0 # There are two subcases to be considered in this case. # sqrt(c)D - sqrt(a)E = 0 and sqrt(c)D - sqrt(a)E != 0 # More Details, http://www.alpertron.com.ar/METHODS.HTM#Parabol elif B**2 - 4 * A * C == 0: g = igcd(A, C) g = abs(g) * sign(A) a = A // g b = B // g c = C // g e = sign(B / A) if e * sqrt(c) * D - sqrt(a) * E == 0: z = symbols("z", real=True) roots = solve(sqrt(a) * g * z**2 + D * z + sqrt(a) * F) for root in roots: if isinstance(root, Integer): l.add( (diop_solve(sqrt(a) * x + e * sqrt(c) * y - root)[x], diop_solve(sqrt(a) * x + e * sqrt(c) * y - root)[y])) elif isinstance(e * sqrt(c) * D - sqrt(a) * E, Integer): solve_x = lambda u: e*sqrt(c)*g*(sqrt(a)*E - e*sqrt(c)*D)*t**2 - (E + 2*e*sqrt(c)*g*u)*t\ - (e*sqrt(c)*g*u**2 + E*u + e*sqrt(c)*F) // (e*sqrt(c)*D - sqrt(a)*E) solve_y = lambda u: sqrt(a)*g*(e*sqrt(c)*D - sqrt(a)*E)*t**2 + (D + 2*sqrt(a)*g*u)*t \ + (sqrt(a)*g*u**2 + D*u + sqrt(a)*F) // (e*sqrt(c)*D - sqrt(a)*E) for z0 in range(0, abs(e * sqrt(c) * D - sqrt(a) * E)): if divisible( sqrt(a) * g * z0**2 + D * z0 + sqrt(a) * F, e * sqrt(c) * D - sqrt(a) * E): l.add((solve_x(z0), solve_y(z0))) # (5) B**2 - 4*A*C > 0 elif B**2 - 4 * A * C > 0: # Method used when B**2 - 4*A*C is a square, is descibed in p. 6 of the below paper # by John P. Robertson. # http://www.jpr2718.org/ax2p.pdf if isinstance(sqrt(B**2 - 4 * A * C), Integer): if A != 0: r = sqrt(B**2 - 4 * A * C) u, v = symbols("u, v", integer=True) eq = simplify(4 * A * r * u * v + 4 * A * D * (B * v + r * u + r * v - B * u) + 2 * A * 4 * A * E * (u - v) + 4 * A * r * 4 * A * F) sol = diop_solve(eq, t) sol = list(sol) for solution in sol: s0 = solution[0] t0 = solution[1] x_0 = S(B * t0 + r * s0 + r * t0 - B * s0) / (4 * A * r) y_0 = S(s0 - t0) / (2 * r) if isinstance(s0, Symbol) or isinstance(t0, Symbol): if check_param(x_0, y_0, 4 * A * r, t) != (None, None): l.add((check_param(x_0, y_0, 4 * A * r, t)[0], check_param(x_0, y_0, 4 * A * r, t)[1])) elif divisible(B * t0 + r * s0 + r * t0 - B * s0, 4 * A * r): if divisible(s0 - t0, 2 * r): if is_solution_quad(var, coeff, x_0, y_0): l.add((x_0, y_0)) else: var[0], var[1] = var[1], var[0] # Interchange x and y s = diop_quadratic(var, coeff, t) while len(s) > 0: sol = s.pop() l.add((sol[1], sol[0])) else: # In this case equation can be transformed into a Pell equation A, B = _transformation_to_pell(var, coeff) D, N = _find_DN(var, coeff) solns_pell = diop_pell(D, N) n = symbols("n", integer=True) a = diop_pell(D, 1) T = a[0][0] U = a[0][1] if (isinstance(A[0], Integer) and isinstance(A[1], Integer) and isinstance(A[2], Integer) and isinstance(A[3], Integer) and isinstance(B[0], Integer) and isinstance(B[1], Integer)): for sol in solns_pell: r = sol[0] s = sol[1] x_n = S((r + s * sqrt(D)) * (T + U * sqrt(D))**n + (r - s * sqrt(D)) * (T - U * sqrt(D))**n) / 2 y_n = S((r + s * sqrt(D)) * (T + U * sqrt(D))**n - (r - s * sqrt(D)) * (T - U * sqrt(D))**n) / (2 * sqrt(D)) x_n, y_n = (A * Matrix([x_n, y_n]) + B)[0], (A * Matrix([x_n, y_n]) + B)[1] l.add((x_n, y_n)) else: L = ilcm( S(A[0]).q, ilcm( S(A[1]).q, ilcm( S(A[2]).q, ilcm(S(A[3]).q, ilcm(S(B[0]).q, S(B[1]).q))))) k = 0 done = False T_k = T U_k = U while not done: k = k + 1 if (T_k - 1) % L == 0 and U_k % L == 0: done = True T_k, U_k = T_k * T + D * U_k * U, T_k * U + U_k * T for soln in solns_pell: x_0 = soln[0] y_0 = soln[1] x_i = x_0 y_i = y_0 for i in range(k): X = (A * Matrix([x_i, y_i]) + B)[0] Y = (A * Matrix([x_i, y_i]) + B)[1] if isinstance(X, Integer) and isinstance(Y, Integer): if is_solution_quad(var, coeff, X, Y): x_n = S((x_i + sqrt(D) * y_i) * (T + sqrt(D) * U)**(n * L) + (x_i - sqrt(D) * y_i) * (T - sqrt(D) * U)**(n * L)) / 2 y_n = S((x_i + sqrt(D) * y_i) * (T + sqrt(D) * U)**(n * L) - (x_i - sqrt(D) * y_i) * (T - sqrt(D) * U)**(n * L)) / (2 * sqrt(D)) x_n, y_n = (A * Matrix([x_n, y_n]) + B)[0], (A * Matrix([x_n, y_n]) + B)[1] l.add((x_n, y_n)) x_i = x_i * T + D * U * y_i y_i = x_i * U + y_i * T return l
def diop_quadratic(var, coeff, t): """ Solves quadratic diophantine equations, i.e equations of the form Ax**2 + Bxy + Cy**2 + Dx + Ey + F = 0. Returns a set containing the tuples (x, y) which contains the solutions. Usage ===== diop_quadratic(var, coeff) -> var is a list of variables and coeff is a dictionary containing coefficients of the symbols. Details ======= ``var`` a list which contains two variables x and y. ``coeff`` a dict which generally contains six key value pairs. The set of keys is {x**2, y**2, x*y, x, y, Integer(1)}. ``t`` the parameter to be used in the solution. Examples ======== >>> from sympy.abc import x, y, t >>> from sympy import Integer >>> from sympy.solvers.diophantine import diop_quadratic >>> diop_quadratic([x, y], {x**2: 1, y**2: 1, x*y: 0, x: 2, y: 2, Integer(1): 2}, t) set([(-1, -1)]) References ========== .. [1] http://www.alpertron.com.ar/METHODS.HTM """ x = var[0] y = var[1] for term in [x**2, y**2, x*y, x, y, Integer(1)]: if term not in coeff.keys(): coeff[term] = Integer(0) A = coeff[x**2] B = coeff[x*y] C = coeff[y**2] D = coeff[x] E = coeff[y] F = coeff[Integer(1)] d = igcd(A, igcd(B, igcd(C, igcd(D, igcd(E, F))))) A = A // d B = B // d C = C // d D = D // d E = E // d F = F // d # (1) Linear case: A = B = C = 0 -> considered under linear diophantine equations # (2) Simple-Hyperbolic case:A = C = 0, B != 0 # In this case equation can be converted to (Bx + E)(By + D) = DE - BF # We consider two cases; DE - BF = 0 and DE - BF != 0 # More details, http://www.alpertron.com.ar/METHODS.HTM#SHyperb l = set([]) if A == 0 and C == 0 and B != 0: if D*E - B*F == 0: if divisible(int(E), int(B)): l.add((-E/B, t)) if divisible(int(D), int(B)): l.add((t, -D/B)) else: div = divisors(D*E - B*F) div = div + [-term for term in div] for d in div: if divisible(int(d - E), int(B)): x0 = (d - E) // B if divisible(int(D*E - B*F), int(d)): if divisible(int((D*E - B*F)// d - D), int(B)): y0 = ((D*E - B*F) // d - D) // B l.add((x0, y0)) # (3) Elliptical case: B**2 - 4AC < 0 # More Details, http://www.alpertron.com.ar/METHODS.HTM#Ellipse # In this case x should lie between the roots of # (B**2 - 4AC)x**2 + 2(BE - 2CD)x + (E**2 - 4CF) = 0 elif B**2 - 4*A*C < 0: z = symbols("z", real=True) roots = solve((B**2 - 4*A*C)*z**2 + 2*(B*E - 2*C*D)*z + E**2 - 4*C*F) solve_y = lambda x, e: (-(B*x + E) + e*sqrt((B*x + E)**2 - 4*C*(A*x**2 + D*x + F)))/(2*C) if len(roots) == 1 and isinstance(roots[0], Integer): x_vals = [roots[0]] elif len(roots) == 2: x_vals = [i for i in range(ceiling(min(roots)), ceiling(max(roots)))] # ceiling = floor +/- 1 else: x_vals = [] for x0 in x_vals: if isinstance(sqrt((B*x0 + E)**2 - 4*C*(A*x0**2 + D*x0 + F)), Integer): if isinstance(solve_y(x0, 1), Integer): l.add((Integer(x0), solve_y(x0, 1))) if isinstance(solve_y(x0, -1), Integer): l.add((Integer(x0), solve_y(x0, -1))) # (4) Parabolic case: B**2 - 4*A*C = 0 # There are two subcases to be considered in this case. # sqrt(c)D - sqrt(a)E = 0 and sqrt(c)D - sqrt(a)E != 0 # More Details, http://www.alpertron.com.ar/METHODS.HTM#Parabol elif B**2 - 4*A*C == 0: g = igcd(A, C) g = abs(g) * sign(A) a = A // g b = B // g c = C // g e = sign(B/A) if e*sqrt(c)*D - sqrt(a)*E == 0: z = symbols("z", real=True) roots = solve(sqrt(a)*g*z**2 + D*z + sqrt(a)*F) for root in roots: if isinstance(root, Integer): l.add((diop_solve(sqrt(a)*x + e*sqrt(c)*y - root)[x], diop_solve(sqrt(a)*x + e*sqrt(c)*y - root)[y])) elif isinstance(e*sqrt(c)*D - sqrt(a)*E, Integer): solve_x = lambda u: e*sqrt(c)*g*(sqrt(a)*E - e*sqrt(c)*D)*t**2 - (E + 2*e*sqrt(c)*g*u)*t\ - (e*sqrt(c)*g*u**2 + E*u + e*sqrt(c)*F) // (e*sqrt(c)*D - sqrt(a)*E) solve_y = lambda u: sqrt(a)*g*(e*sqrt(c)*D - sqrt(a)*E)*t**2 + (D + 2*sqrt(a)*g*u)*t \ + (sqrt(a)*g*u**2 + D*u + sqrt(a)*F) // (e*sqrt(c)*D - sqrt(a)*E) for z0 in range(0, abs(e*sqrt(c)*D - sqrt(a)*E)): if divisible(sqrt(a)*g*z0**2 + D*z0 + sqrt(a)*F, e*sqrt(c)*D - sqrt(a)*E): l.add((solve_x(z0), solve_y(z0))) # (5) B**2 - 4*A*C > 0 elif B**2 - 4*A*C > 0: # Method used when B**2 - 4*A*C is a square, is descibed in p. 6 of the below paper # by John P. Robertson. # http://www.jpr2718.org/ax2p.pdf if isinstance(sqrt(B**2 - 4*A*C), Integer): if A != 0: r = sqrt(B**2 - 4*A*C) u, v = symbols("u, v", integer=True) eq = simplify(4*A*r*u*v + 4*A*D*(B*v + r*u + r*v - B*u) + 2*A*4*A*E*(u - v) + 4*A*r*4*A*F) sol = diop_solve(eq, t) sol = list(sol) for solution in sol: s0 = solution[0] t0 = solution[1] x_0 = S(B*t0 + r*s0 + r*t0 - B*s0)/(4*A*r) y_0 = S(s0 - t0)/(2*r) if isinstance(s0, Symbol) or isinstance(t0, Symbol): if check_param(x_0, y_0, 4*A*r, t) != (None, None): l.add((check_param(x_0, y_0, 4*A*r, t)[0], check_param(x_0, y_0, 4*A*r, t)[1])) elif divisible(B*t0 + r*s0 + r*t0 - B*s0, 4*A*r): if divisible(s0 - t0, 2*r): if is_solution_quad(var, coeff, x_0, y_0): l.add((x_0, y_0)) else: var[0], var[1] = var[1], var[0] # Interchange x and y s = diop_quadratic(var, coeff, t) while len(s) > 0: sol = s.pop() l.add((sol[1], sol[0])) else: # In this case equation can be transformed into a Pell equation A, B = _transformation_to_pell(var, coeff) D, N = _find_DN(var, coeff) solns_pell = diop_pell(D, N) n = symbols("n", integer=True) a = diop_pell(D, 1) T = a[0][0] U = a[0][1] if (isinstance(A[0], Integer) and isinstance(A[1], Integer) and isinstance(A[2], Integer) and isinstance(A[3], Integer) and isinstance(B[0], Integer) and isinstance(B[1], Integer)): for sol in solns_pell: r = sol[0] s = sol[1] x_n = S((r + s*sqrt(D))*(T + U*sqrt(D))**n + (r - s*sqrt(D))*(T - U*sqrt(D))**n)/2 y_n = S((r + s*sqrt(D))*(T + U*sqrt(D))**n - (r - s*sqrt(D))*(T - U*sqrt(D))**n)/(2*sqrt(D)) x_n, y_n = (A*Matrix([x_n, y_n]) + B)[0], (A*Matrix([x_n, y_n]) + B)[1] l.add((x_n, y_n)) else: L = ilcm(S(A[0]).q, ilcm(S(A[1]).q, ilcm(S(A[2]).q, ilcm(S(A[3]).q, ilcm(S(B[0]).q, S(B[1]).q))))) k = 0 done = False T_k = T U_k = U while not done: k = k + 1 if (T_k - 1) % L == 0 and U_k % L == 0: done = True T_k, U_k = T_k*T + D*U_k*U, T_k*U + U_k*T for soln in solns_pell: x_0 = soln[0] y_0 = soln[1] x_i = x_0 y_i = y_0 for i in range(k): X = (A*Matrix([x_i, y_i]) + B)[0] Y = (A*Matrix([x_i, y_i]) + B)[1] if isinstance(X, Integer) and isinstance(Y, Integer): if is_solution_quad(var, coeff, X, Y): x_n = S( (x_i + sqrt(D)*y_i)*(T + sqrt(D)*U)**(n*L) + (x_i - sqrt(D)*y_i)*(T - sqrt(D)*U)**(n*L) )/ 2 y_n = S( (x_i + sqrt(D)*y_i)*(T + sqrt(D)*U)**(n*L) - (x_i - sqrt(D)*y_i)*(T - sqrt(D)*U)**(n*L) )/ (2*sqrt(D)) x_n, y_n = (A*Matrix([x_n, y_n]) + B)[0], (A*Matrix([x_n, y_n]) + B)[1] l.add((x_n, y_n)) x_i = x_i*T + D*U*y_i y_i = x_i*U + y_i*T return l
def test_multiple_parameters(): assert_equal("\\lcm(830,450)", lcm(830, 450)) assert_equal("\\lcm(6,321,429)", ilcm(6, 321, 429)) assert_equal("\\lcm(14,2324)", lcm(14, 2324)) assert_equal("\\lcm(3, 6, 2)", ilcm(3, 6, 2)) assert_equal("\\lcm(8, 9, 21)", ilcm(8, 9, 21)) assert_equal("\\lcm(144, 2988, 37116)", ilcm(144, 2988, 37116)) assert_equal("\\lcm(144,2988,37116,18,72)", ilcm(144, 2988, 37116, 18, 72)) assert_equal("\\lcm(144, 2988, 37116, 18, 72, 12, 6)", ilcm(144, 2988, 37116, 18, 72, 12, 6)) assert_equal("\\lcm(32)", lcm(32, 32)) assert_equal("\\lcm(-8, 4, -2)", lcm(-8, lcm(4, -2))) assert_equal("\\lcm(x, y, z)", lcm(x, lcm(y, z)), symbolically=True) assert_equal("\\lcm(6*4, 48, 3)", ilcm(6 * 4, 48, 3)) assert_equal("\\lcm(2.4, 3.6, 0.6)", lcm(Rational('2.4'), lcm(Rational('3.6'), Rational('0.6')))) assert_equal("\\lcm(\\sqrt{3}, \\sqrt{2},\\sqrt{100})", lcm(sqrt(3), lcm(sqrt(2), sqrt(100)))) assert_equal("\\lcm(1E12, 1E6, 1E3, 10)", ilcm(Rational('1E12'), Rational('1E6'), Rational('1E3'), 10)) assert_equal("\\operatorname{lcm}(830,450)", lcm(830, 450)) assert_equal("\\operatorname{lcm}(6,321,429)", ilcm(6, 321, 429)) assert_equal("\\operatorname{lcm}(14,2324)", lcm(14, 2324)) assert_equal("\\operatorname{lcm}(3, 6, 2)", ilcm(3, 6, 2)) assert_equal("\\operatorname{lcm}(8, 9, 21)", ilcm(8, 9, 21)) assert_equal("\\operatorname{lcm}(144, 2988, 37116)", ilcm(144, 2988, 37116)) assert_equal("\\operatorname{lcm}(144,2988,37116,18,72)", ilcm(144, 2988, 37116, 18, 72)) assert_equal("\\operatorname{lcm}(144, 2988, 37116, 18, 72, 12, 6)", ilcm(144, 2988, 37116, 18, 72, 12, 6)) assert_equal("\\operatorname{lcm}(32)", lcm(32, 32)) assert_equal("\\operatorname{lcm}(-8, 4, -2)", lcm(-8, lcm(4, -2))) assert_equal("\\operatorname{lcm}(x, y, z)", lcm(x, lcm(y, z)), symbolically=True) assert_equal("\\operatorname{lcm}(6*4,48, 3)", ilcm(6 * 4, 48, 3)) assert_equal("\\operatorname{lcm}(2.4, 3.6,0.6)", lcm(Rational('2.4'), lcm(Rational('3.6'), Rational('0.6')))) assert_equal("\\operatorname{lcm}(\\sqrt{3}, \\sqrt{2},\\sqrt{100})", lcm(sqrt(3), lcm(sqrt(2), sqrt(100)))) assert_equal("\\operatorname{lcm}(1E12,1E6, 1E3, 10)", ilcm(Rational('1E12'), Rational('1E6'), Rational('1E3'), 10))
def __initialize(self): """ Method for actually initializing the de Bruijn sequence generator. Users need not to run this method. """ # populate states self._associates = _get_associate_poly(self._polys) for entry in self._associates: entry_state = [] degree = _sympy.degree(entry['associate']) init_state = [1] * degree for i in xrange(entry['order']): entry_state.append( _seq_decimation(entry['associate'], entry['order'], i, init_state)[:degree]) entry_state.append([0] * degree) self._states.append(entry_state) # find special state p_matrix = [] for poly in self._polys: degree = poly.degree() for i in xrange(degree): state = [0] * degree state[i] = 1 for j in xrange(self._order - degree): state.append(_lfsr_from_poly(poly, state[-degree:])[-1]) p_matrix += state p_matrix = _sympy.Matrix(self._order, self._order, p_matrix) self._p_matrix = p_matrix special_state = map( int, _sympy.Matrix(1, self._order, [1] + [0] * (self._order - 1)) * p_matrix.inv_mod(2)) special_states = [] i = 0 for j, poly in enumerate(self._polys): check_state = special_state[i:i + _sympy.degree(poly)] cur_states = self._states[j] for cur_shift in xrange(self._associates[j]['period']): try: which = cur_states.index(check_state) if which == len(cur_states) - 1: special_states.append(0) else: special_states.append(self._associates[j]['order'] * cur_shift + which) break except ValueError: cur_states = [_lfsr_from_poly(poly, s) for s in cur_states] continue i += _sympy.degree(poly) # get zech logs zech_logs = [ _retrieve_zech_log(e['associate']) for e in self._associates ] # find conjugate pairs and construct adjacency graph # in here, -1 represents -Inf (in Zech's logarithm) graph = self._graph for z1_vals in _iters.product(*[ range(-1, 2**(e['associate'].degree()) - 1) for e in self._associates ]): t_vals = [ self._associates[i]['order'] for i in xrange(len(z1_vals)) ] z2_vals = [] for i, z in enumerate(z1_vals): if z == special_states[i]: z2_vals.append(-1) elif z == -1: z2_vals.append(special_states[i]) else: conj_val = special_states[i] + zech_logs[i][ z - special_states[i]] conj_val %= 2**self._polys[i].degree() - 1 z2_vals.append(conj_val) param_1, param_2 = [], [] shift_1, shift_2 = [], [] for i, z1, z2 in zip(range(len(z1_vals)), z1_vals, z2_vals): if z2 == -1: p1, p2 = z1 % t_vals[i], t_vals[i] s1, s2 = z1 / t_vals[i], 0 elif z1 == -1: p1, p2 = t_vals[i], z2 % t_vals[i] s1, s2 = 0, z2 / t_vals[i] else: p1, p2 = z1 % t_vals[i], z2 % t_vals[i] s1, s2 = z1 / t_vals[i], z2 / t_vals[i] param_1.append(p1) param_2.append(p2) shift_1.append(s1) shift_2.append(s2) f1_vals = [ 1 if s == t_vals[i] else self._associates[i]['period'] for i, s in enumerate(param_1) ] f2_vals = [ 1 if s == t_vals[i] else self._associates[i]['period'] for i, s in enumerate(param_2) ] for i, s1, s2 in zip(range(len(z1_vals)), shift_1, shift_2): modulus1 = _sympy.gcd(f1_vals[i], _sympy.ilcm(*([1, 1] + f1_vals[:i]))) modulus2 = _sympy.gcd(f2_vals[i], _sympy.ilcm(*([1, 1] + f2_vals[:i]))) param_1.append((s1 - shift_1[0]) % modulus1) param_2.append((s2 - shift_2[0]) % modulus2) # lazy check if it's actually a conjugate pair # state_1 = [] # state_2 = [] # for i, p in enumerate(self._polys): # cur_state_1 = self._states[i][param_1[i]] # cur_state_2 = self._states[i][param_2[i]] # for j in range(shift_1[i]): # cur_state_1 = _lfsr_from_poly(p, cur_state_1) # for j in range(shift_2[i]): # cur_state_2 = _lfsr_from_poly(p, cur_state_2) # state_1 += cur_state_1 # state_2 += cur_state_2 # state_1 = (_sympy.Matrix(1, self._order, state_1) * self._p_matrix).applyfunc(lambda x: x % 2) # state_2 = (_sympy.Matrix(1, self._order, state_2) * self._p_matrix).applyfunc(lambda x: x % 2) # state_1[0] = 1 - state_1[0] if param_1 > param_2: # and state_1 == state_2 param_1 = tuple(param_1) param_2 = tuple(param_2) graph.add_edge(param_1, param_2, shift={ param_1: shift_1, param_2: shift_2 }) self._adjacency_matrix = -_sympy.Matrix( _nx.to_numpy_matrix(self._graph)).applyfunc(int) for i in range(self._adjacency_matrix.rows): self._adjacency_matrix[i, i] -= sum(self._adjacency_matrix[i, :]) simple_graph = _nx.Graph(self._graph) self._param_generator = self.__param_generator( _spanning_trees(simple_graph)) # if auto_arm: anf = self.__get_algebraic_normal_form(*self._param_generator.next()) self._fsr = _FSR(anf, order=self._order, init_state=self._state)