Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
 def answer(num1, num2, lcm):
   return lcm - ilcm(num1, num2)
Exemplo n.º 6
0
 def distractor1(num1, num2, gcd):
   return gcd - ilcm(num1, num2)
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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))
Exemplo n.º 10
0
    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)