Ejemplo n.º 1
0
def run_inv(a=11, b=1, param="simulation"):
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(modules=[projectq.libs.math,
                                             projectq.setups.decompositions])
    compilerengines = [AutoReplacer(rule_set),
                       TagRemover(),
                       LocalOptimizer(3),
                       AutoReplacer(rule_set),
                       TagRemover(),
                       LocalOptimizer(3),
                       resource_counter]

    # create a main compiler engine
    a1 = a
    b1 = b
    if a == 0:
        a1 = 1
    if b == 0:
        b1 = 1
    n = max(int(math.log(a1, 2)), int(math.log(b1, 2))) + 1

    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)
        xa = initialisation_n(eng2, a, n + 1)
        xb = initialisation_n(eng2, b, n + 1)
        # b --> phi(b)
        QFT | xb
        phi_adder(eng2, xa, xb)
        with Dagger(eng2):
            QFT | xb
        All(Measure) | xa
        All(Measure) | xb
        eng2.flush()
        print(drawing_engine.get_latex())
    else:
        eng = MainEngine(Simulator(), compilerengines)
        xa = initialisation_n(eng, a, n + 1)
        xb = initialisation_n(eng, b, n + 1)
        # b --> phi(b)
        QFT | xb
        with Dagger(eng):
            phi_adder(eng, xa, xb)
        with Dagger(eng):
            QFT | xb
        All(Measure) | xa
        All(Measure) | xb
        eng.flush()
        n = n+1
        measurements_a = [0] * n
        measurements_b = [0] * n
        for k in range(n):
            measurements_a[k] = int(xa[k])
            measurements_b[k] = int(xb[k])

        return [measurements_a, meas2int(measurements_b), measurements_b]
Ejemplo n.º 2
0
def run_shor(eng, N, a, verbose=False):
    """
    Runs the quantum subroutine of Shor's algorithm for factoring. with 2n control qubits

    Args:
        eng (MainEngine): Main compiler engine to use.
        N (int): Number to factor.
        a (int): Relative prime to use as a base for a^x mod N.
        verbose (bool): If True, display intermediate measurement results.

    Returns:
        r (float): Potential period of a.
    """
    n = int(math.ceil(math.log(N, 2)))

    x = eng.allocate_qureg(n)
    xN = initialisation_n(eng, N, n)
    xb = initialisation_n(eng, 0, n)
    aux = initialisation_n(eng, 0, 1)
    X | x[0]  # set x to 1

    measurements = [0] * (2 * n)  # will hold the 2n measurement results

    ctrl_qubit = eng.allocate_qureg(2 * n)

    for k in range(2 * n):
        current_a = pow(a, 1 << k, N)
        # one iteration of 1-qubit QPE
        H | ctrl_qubit[k]
        gateUa(eng, current_a, mod_inv(current_a, N), x, xb, xN, aux,
               ctrl_qubit[k], N)

    with Dagger(eng):
        QFT | ctrl_qubit

    # and measure
    All(Measure) | ctrl_qubit
    eng.flush()
    for k in range(2 * n):
        measurements[k] = int(ctrl_qubit[k])

    All(Measure) | x
    # turn the measured values into a number in [0,1)
    y = sum([(measurements[i] * 1. / (1 << (i + 1))) for i in range(2 * n)])

    # continued fraction expansion to get denominator (the period?)
    r = Fraction(y).limit_denominator(N - 1).denominator

    # return the (potential) period
    return r
def inv_cMultModN_non_Dagger(eng, a, xb, xx, xN, aux, xc, N):
    """
    |b> --> |b+(ax) mod N> if xc=1; else |b> -> |b>
    :param eng:
    :param a:
    :param xc: control bit
    :param aux: auxiliary
    :param xx: multiplier
    :param xb: modified qubit
    :param xN: Mod
    :return:
    """
    # b-->phi(b)
    QFT | xb
    n = len(xx) - 1
    for i in range(n - 1, -1, -1):
        xa = initialisation_n(eng, ((2**i) * a) % N,
                              n + 1)  # both input of modularAdder must be <N
        # TODO define xa in a iterative way just by adding a new qubit 0 as LSB
        with Dagger(eng):
            modularAdder(eng, xa, xb, xN, xx[i], xc, aux)
    with Dagger(eng):
        QFT | xb
Ejemplo n.º 4
0
def run_shor(eng, N, a, verbose=True):
    """
    Runs the quantum subroutine of Shor's algorithm for factoring.
    The 1 controling qubits version
    [2, 3, 4, 5, 6, 7, 8]
    [1002,2926,6822,13802, 25257, 42548, 67868]
    Args:
        eng (MainEngine): Main compiler engine to use.
        N (int): Number to factor.
        a (int): Relative prime to use as a base for a^x mod N.
        verbose (bool): If True, display intermediate measurement results.

    Returns:
        r (float): Potential period of a.
    """
    n = int(math.ceil(math.log(N, 2)))

    x = eng.allocate_qureg(n)
    xN = initialisation_n(eng, N, n)
    xb = initialisation_n(eng, 0, n)
    aux = initialisation_n(eng, 0, 1)

    X | x[0]

    measurements = [0] * (2 * n)  # will hold the 2n measurement results

    ctrl_qubit = eng.allocate_qubit()
    # each iteration -> 454*log2(N) + c -> 2*n(454*log2(N) +c ) -> 908 * log2(N)^2 -> O(n^2)
    # c = 3 ou 4
    # last interation measurment -> 3*n
    # donc 908*(n**2) + 3*n
    for k in range(2 * n):

        current_a = pow(a, 1 << (2 * n - 1 - k), N)
        # one iteration of 1-qubit QPE
        H | ctrl_qubit
        """
        with Control(eng, ctrl_qubit):
            MultiplyByConstantModN(current_a, N) | x
        """
        gateUa(eng, current_a, mod_inv(current_a, N), x, xb, xN, aux,
               ctrl_qubit, N)
        # nb of gate linear in log2(N) approx ~ 454*log2(N)
        # perform inverse QFT --> Rotations conditioned on previous outcomes
        """
        for i in range(k):
            if measurements[i]:
                R(-math.pi/(1 << (k - i))) | ctrl_qubit
        """
        H | ctrl_qubit

        # and measure
        Measure | ctrl_qubit
        eng.flush()
        measurements[k] = int(ctrl_qubit)
        if measurements[k]:
            X | ctrl_qubit

        if verbose:
            print("\033[95m{}\033[0m".format(measurements[k]), end="")
            sys.stdout.flush()
    Measure | aux
    All(Measure) | xN
    All(Measure) | xb
    All(Measure) | x
    # turn the measured values into a number in [0,1)
    y = sum([(measurements[2 * n - 1 - i] * 1. / (1 << (i + 1)))
             for i in range(2 * n)])

    # continued fraction expansion to get denominator (the period?)
    r = Fraction(y).limit_denominator(N - 1).denominator

    # return the (potential) period
    return r
def run(a=4, b=6, N=7, x=2, param="count"):
    """
    Last update 19/02 : nb of gate linear in log(N)
    Be careful this algo is a bit long to execute
    |b> --> |b+(ax) mod N> works for
    :param a:
    :param b:
    :param N:
    :param x:
    :param param:
    :return:
    """
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3), resource_counter
    ]

    # create a main compiler engine
    n = int(math.log(N, 2)) + 1

    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)
        xN = initialisation_n(eng2, N, n + 1)
        xx = initialisation_n(eng2, x, n + 1)
        xb = initialisation_n(eng2, b, n + 1)
        [xc, aux] = initialisation(eng2, [1, 0])
        cMultModN_non_Dagger(eng2, a, xb, xx, xN, aux, xc)
        eng2.flush()
        Measure | aux
        Measure | xc
        All(Measure) | xx
        All(Measure) | xb
        All(Measure) | xN
        eng2.flush()
        print(drawing_engine.get_latex())
    else:
        if param == "count":
            eng = MainEngine(resource_counter)
        else:
            eng = MainEngine(Simulator(), compilerengines)
        xN = initialisation_n(eng, N, n + 1)
        xx = initialisation_n(eng, x, n + 1)
        xb = initialisation_n(eng, b, n + 1)
        [aux, xc] = initialisation(eng, [0, 1])
        cMultModN_non_Dagger(eng, a, xb, xx, xN, aux, xc, N)
        Measure | aux
        Measure | xc
        All(Measure) | xx
        All(Measure) | xb
        All(Measure) | xN
        eng.flush()
        if param == "count":
            return resource_counter

        measurements_b = [0] * n
        measurements_x = [0] * n
        measurements_N = [0] * n
        for k in range(n):
            measurements_b[k] = int(xb[k])
            measurements_N[k] = int(xN[k])
            measurements_x[k] = int(xx[k])

        mes_aux = int(aux[0])
        mes_c = int(aux[0])
        return [
            measurements_b,
            meas2int(measurements_b), (b + a * x) % N, measurements_N,
            measurements_x, mes_aux, mes_c,
            meas2int(measurements_b),
            meas2int(measurements_N),
            meas2int(measurements_x)
        ]
Ejemplo n.º 6
0
def arcsinQ(eng, x, N):
    """
    with 4 qubits takes ~1800s to run with a C engine
    :param eng:
    :param x: int that represent a reel in [0,1] by taking its binary decomposition
    :param N: int (2^n)
    :return: arcsin(x [N])
    """
    n = int(log(N, 2)) + 1
    start = time()
    output = initialisation_n(eng, 1, n + 1)
    xN = initialisation_n(eng, N, n + 1)
    xb = initialisation_n(eng, 1, n + 1)

    x_3 = initialisation_n(eng, 3, n + 1)
    aux = initialisation_n(eng, 0, 1)
    t1 = time()
    print("initialisation : ", t1 - start)

    expoModN(eng, x, output, xb, xN, aux, x_3, N)
    t2 = time()
    print("expoModN : ", t2 - t1)

    All(Measure) | x_3

    inv_6 = 4  # 1/6 ~ 1/2^3 + 1/2^5 soit [0,0,1,0,1] en réduisant à 4 qubits [0,0,1,0]=4
    c1 = initialisation_n(eng, 1, 1)

    cMultModN_non_Dagger(eng, inv_6, xb, output, xN, aux, c1, N)

    t3 = time()
    print("inv : ", t3 - t2)

    xX = initialisation_n(eng, x, n + 1)

    QFT | xX
    c2 = initialisation_n(eng, 1, 1)
    modularAdder(eng, output, xX, xN, c1, c2, aux)
    t4 = time()
    print("Modular Adder : ", t4 - t3)
    with Dagger(eng):
        QFT | xX
    t5 = time()
    print("QFT : ", t5 - t4)

    Measure | aux
    Measure | c1
    Measure | c2
    All(Measure) | output
    All(Measure) | xX
    All(Measure) | xb
    All(Measure) | xN

    eng.flush()
    t6 = time()
    print("eng.flush : ", t6 - t5)
    print("Temps total : ", t6 - start)
    measurements_x = [0] * n
    measurements_N = [0] * n
    for k in range(n):
        measurements_N[k] = int(xN[k])
        measurements_x[k] = int(xX[k])
    return [measurements_x, meas2int(measurements_x), measurements_N]
Ejemplo n.º 7
0
def run(a=4, N=7, x=2, param="count"):
    """
    |b> --> |b+(ax) mod N>
    nb of gate ~454*log2(N)
    :param a: a<N and must be invertible mod[N]
    :param N:
    :param x:
    :param param:
    :return:
    """
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3), resource_counter
    ]

    # create a main compiler engine
    a = a % N
    inv_a = mod_inv(a, N)
    b = 0
    n = int(math.log(N, 2)) + 1

    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)
        xN = initialisation_n(eng2, N, n + 1)
        xx = initialisation_n(eng2, x, n + 1)
        xb = initialisation_n(eng2, b, n + 1)
        [xc, aux] = initialisation(eng2, [1, 0])
        gateUa(eng2, a, inv_a, xx, xb, xN, aux, xc, N)
        eng2.flush()
        Measure | aux
        Measure | xc
        All(Measure) | xx
        All(Measure) | xb
        All(Measure) | xN
        eng2.flush()
        print(drawing_engine.get_latex())
    else:
        if param == "count":
            eng = MainEngine(resource_counter)
        else:
            eng = MainEngine(Simulator(), compilerengines)
        xN = initialisation_n(eng, N, n + 1)
        xx = initialisation_n(eng, x, n + 1)
        xb = initialisation_n(eng, b, n + 1)
        [xc, aux] = initialisation(eng, [1, 0])
        gateUa(eng, a, inv_a, xx, xb, xN, aux, xc, N)
        Measure | aux
        Measure | xc
        All(Measure) | xx
        All(Measure) | xb
        All(Measure) | xN
        eng.flush()
        if param == "count":
            return resource_counter
        measurements_b = [0] * n
        measurements_x = [0] * n
        measurements_N = [0] * n
        for k in range(n):
            measurements_b[k] = int(xb[k])
            measurements_N[k] = int(xN[k])
            measurements_x[k] = int(xx[k])

        mes_aux = int(aux[0])
        mes_c = int(aux[0])

        assert int(xb[n]) == 0
        assert int(xN[n]) == 0
        assert int(xx[n]) == 0
        assert meas2int(measurements_b) == 0
        assert meas2int(measurements_N) == N
        assert mes_aux == 0

        return [(a * x) % N, meas2int(measurements_x), measurements_x, mes_c]
Ejemplo n.º 8
0
def run(a=4, N=7, x=2, param="run"):
    """

    :param a: a<N and must be invertible mod[N]
    :param N:
    :param x:
    :param param:
    :return: |1> --> |(a**x) mod N>
    """
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3), resource_counter
    ]

    # create a main compiler engine
    a = a % N
    b = 0
    n = int(math.log(N, 2)) + 1

    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng = MainEngine(drawing_engine)
    if param == "count":
        eng = MainEngine(resource_counter)
    else:
        eng = MainEngine(Simulator(), compilerengines)

    output = initialisation_n(eng, 1, n + 1)
    xN = initialisation_n(eng, N, n + 1)
    xx = initialisation_n(eng, x, n + 1)
    xb = initialisation_n(eng, b, n + 1)
    aux = initialisation_n(eng, 0, 1)
    expoModN(eng, a, output, xb, xN, aux, xx, N)

    Measure | aux
    All(Measure) | output
    All(Measure) | xx
    All(Measure) | xb
    All(Measure) | xN
    eng.flush()

    if param == "count":
        return resource_counter
    if param == "latex":
        print(drawing_engine.get_latex())

    measurements_b = [0] * n
    measurements_x = [0] * n
    measurements_N = [0] * n
    for k in range(n):
        measurements_b[k] = int(xb[k])
        measurements_N[k] = int(xN[k])
        measurements_x[k] = int(output[k])

    mes_aux = int(aux[0])

    assert int(xb[n]) == 0
    assert int(xN[n]) == 0
    assert int(xx[n]) == 0
    assert meas2int(measurements_b) == 0
    assert meas2int(measurements_N) == N
    assert mes_aux == 0

    return [(a**x) % N, meas2int(measurements_x), measurements_x]
Ejemplo n.º 9
0
def run(a=11, b=1, N=12, param="simulation"):
    # build compilation engine list
    resource_counter = ResourceCounter()
    rule_set = DecompositionRuleSet(
        modules=[projectq.libs.math, projectq.setups.decompositions])
    compilerengines = [
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3),
        AutoReplacer(rule_set),
        TagRemover(),
        LocalOptimizer(3), resource_counter
    ]

    # create a main compiler engine
    n = int(math.log(N, 2)) + 1
    if param == "latex":
        drawing_engine = CircuitDrawer()
        eng2 = MainEngine(drawing_engine)

        xN = initialisation_n(eng2, N, n + 1)
        xa = initialisation_n(eng2, a, n + 1)
        xb = initialisation_n(eng2, b, n + 1)
        c1 = initialisation_n(eng2, 1)
        c2 = initialisation_n(eng2, 1)
        aux = initialisation_n(eng2, 0)
        # b --> phi(b)
        QFT | xb
        modularAdder(eng2, xa, xb, xN, c1, c2, aux)
        with Dagger(eng2):
            QFT | xb
        Measure | c1
        Measure | c2
        Measure | aux
        All(Measure) | xa
        All(Measure) | xb
        All(Measure) | xN
        eng2.flush()
        print(drawing_engine.get_latex())
    else:
        eng = MainEngine(Simulator(), compilerengines)
        xN = initialisation_n(eng, N, n + 1)
        xa = initialisation_n(eng, a, n + 1)
        xb = initialisation_n(eng, b, n + 1)
        [c1, c2, aux] = initialisation(eng, [1, 1, 0])
        # b --> phi(b)
        QFT | xb
        modularAdder(eng, xa, xb, xN, c1, c2, aux)
        with Dagger(eng):
            QFT | xb
        Measure | c1
        Measure | c2
        Measure | aux
        All(Measure) | xa
        All(Measure) | xb
        All(Measure) | xN
        eng.flush()

        measurements_a = [0] * n
        measurements_b = [0] * n
        measurements_N = [0] * n
        for k in range(n):
            measurements_a[k] = int(xa[k])
            measurements_b[k] = int(xb[k])
            measurements_N[k] = int(xN[k])

        return [
            measurements_a, measurements_b,
            int(xb[n]), measurements_N,
            int(aux[0]),
            int(c1[0]),
            int(c2[0]),
            meas2int(measurements_b), (a + b) % N
        ]