Exemplo n.º 1
0
def run_grover(eng, n, Ox):
    # start in uniform superposition
    x = eng.allocate_qureg(n)
    All(H) | x

    # the auxiliary indicator qbit, prepare it as '|->'
    y = eng.allocate_qubit()
    X | y
    H | y

    # number of iterations we have to run:
    ITER = int(math.pi / 4.0 * math.sqrt(1 << n))
    with Loop(eng, ITER):
        # oracle adds a (-1)-phase to the solution(s)
        Ox(eng, x, y)

        # reflection across uniform superposition
        with Compute(eng):
            All(H) | x
            All(X) | x

        with Control(eng, x[:-1]):  # Z == H-CNOT(x[-1])-H ??
            Z | x[-1]

        Uncompute(eng)

    All(Measure) | x
    Measure | y

    eng.flush()
    return ''.join([str(int(q)) for q in x])
Exemplo n.º 2
0
def _decompose_QPE(cmd):  # pylint: disable=invalid-name
    """Decompose the Quantum Phase Estimation gate."""
    eng = cmd.engine

    # Ancillas is the first qubit/qureg. System-qubit is the second qubit/qureg
    qpe_ancillas = cmd.qubits[0]
    system_qubits = cmd.qubits[1]

    # Hadamard on the ancillas
    Tensor(H) | qpe_ancillas

    # The Unitary Operator
    unitary = cmd.gate.unitary

    # Control U on the system_qubits
    if callable(unitary):
        # If U is a function
        for i, ancilla in enumerate(qpe_ancillas):
            with Control(eng, ancilla):
                unitary(system_qubits, time=2**i)
    else:
        for i, ancilla in enumerate(qpe_ancillas):
            ipower = int(2**i)
            with Loop(eng, ipower):
                with Control(eng, ancilla):
                    unitary | system_qubits

    # Inverse QFT on the ancillas
    get_inverse(QFT) | qpe_ancillas
Exemplo n.º 3
0
def ExecuteGrover(engine, n, oracle):
    x = engine.allocate_qureg(n)

    All(H) | x

    num_it = int(math.pi/4.*math.sqrt(1 << n))

    oracle_out = engine.allocate_qubit()
    X | oracle_out
    H | oracle_out

    with Loop(engine, num_it):
        oracle(engine, x, oracle_out)
        with Compute(engine):
            All(H) | x
            All(X) | x

        with Control(engine, x[0:-1]):
            Z | x[-1]

        Uncompute(engine)

    All(Measure) | x
    Measure | oracle_out

    engine.flush()
    return [int(qubit) for qubit in x]
Exemplo n.º 4
0
def run_phase_estimation(eng, U, state, m, n):
    """
    Phase estimation algorithm on unitary U. 

    Args:
        eng (MainEngine): Main compiler engine to run the phase_estimation algorithm
        U (np.matrix): the unitary that is to be estimated
        state (qureg): the input state, which has the form |psi> otimes |0>.
                        State is composed of two parts: 
                            1. The first n qubits are the input state |psi>, which is commonly
                               chosen to be the eigenstate of U
                            2. The last n qubits are initialized to |0>, which is used to 
                               store the binary digits of the estimated phase
        m (int): number of qubits for input state psi
        n (int): number of qubits used to store the phase to given precision
    """
    # The beginning index for the phase qubits will have an offset
    OFFSET = m
    # Phase 1. performs the controlled U^{2^j} operations
    for k in range(n):
        H | state[OFFSET + k]

        with Control(eng, state[OFFSET + k]):
            # number of loops required to perfrom the controlled U^{2^j} operation
            num = int(math.pow(2, k))
            # use the buildin loop
            with Loop(eng, num):
                U | state[:OFFSET]

    # Phase 2. performs the inverse QFT operation
    # Step 2.1 swap the qubits
    for k in range(int(math.floor(n / 2))):
        Swap | (state[OFFSET + k], state[OFFSET + n - k - 1])
    # Step 2.2 perfrom the original inverse QFT
    get_inverse(QFT) | state[OFFSET:]
Exemplo n.º 5
0
def _decompose_QPE(cmd):
    """ Decompose the Quantum Phase Estimation gate. """
    eng = cmd.engine

    # Ancillas is the first qubit/qureg. System-qubit is the second qubit/qureg
    qpe_ancillas = cmd.qubits[0]
    system_qubits = cmd.qubits[1]

    # Hadamard on the ancillas
    Tensor(H) | qpe_ancillas

    # The Unitary Operator
    U = cmd.gate.unitary

    # Control U on the system_qubits
    if (callable(U)):
        # If U is a function
        for i in range(len(qpe_ancillas)):
            with Control(eng, qpe_ancillas[i]):
                U(system_qubits, time=2**i)
    else:
        for i in range(len(qpe_ancillas)):
            ipower = int(2**i)
            with Loop(eng, ipower):
                with Control(eng, qpe_ancillas[i]):
                    U | system_qubits

    # Inverse QFT on the ancillas
    get_inverse(QFT) | qpe_ancillas
Exemplo n.º 6
0
def quanutm_phase_estimation(eng):

    All(H) | phase_reg

    with Control(eng, phase_reg[0]):
        run_qnn(eng)

    with Control(eng, phase_reg[1]):
        with Loop(eng, 2):
            run_qnn(eng)

    with Control(eng, phase_reg[2]):
        with Loop(eng, 4):
            run_qnn(eng)

    Swap | (phase_reg[0], phase_reg[2])

    get_inverse(QFT) | phase_reg
def test_complex_aa():
    rule_set = DecompositionRuleSet(modules=[aa])

    eng = MainEngine(
        backend=Simulator(),
        engine_list=[
            AutoReplacer(rule_set),
        ],
    )

    system_qubits = eng.allocate_qureg(6)

    # Prepare the control qubit in the |-> state
    control = eng.allocate_qubit()
    X | control
    H | control

    # Creates the initial state form the Algorithm
    complex_algorithm(eng, system_qubits)

    # Get the probabilty of getting the marked state before the AA
    # to calculate the number of iterations
    eng.flush()
    prob000000 = eng.backend.get_probability('000000', system_qubits)
    prob111111 = eng.backend.get_probability('111111', system_qubits)

    total_amp_before = math.sqrt(prob000000 + prob111111)
    theta_before = math.asin(total_amp_before)

    # Apply Quantum Amplitude Amplification the correct number of times
    # Theta is calculated previously using get_probability
    # We calculate also the theoretical final probability
    # of getting the good state
    num_it = int(math.pi / (4.0 * theta_before) + 1)
    theoretical_prob = math.sin((2 * num_it + 1.0) * theta_before)**2
    with Loop(eng, num_it):
        QAA(complex_algorithm, complex_oracle) | (system_qubits, control)

    # Get the probabilty of getting the marked state after the AA
    # to compare with the theoretical probability after the AA
    eng.flush()
    prob000000 = eng.backend.get_probability('000000', system_qubits)
    prob111111 = eng.backend.get_probability('111111', system_qubits)
    total_prob_after = prob000000 + prob111111

    All(Measure) | system_qubits
    H | control
    Measure | control

    eng.flush()

    assert total_prob_after == pytest.approx(
        theoretical_prob, abs=1e-2
    ), "The obtained probability is less than expected %f vs. %f" % (
        total_prob_after,
        theoretical_prob,
    )
Exemplo n.º 8
0
def run_grover(eng, n, oracle):
    """
    Runs Grover's algorithm on n qubit using the provided quantum oracle.

    Args:
        eng (MainEngine): Main compiler engine to run Grover on.
        n (int): Number of bits in the solution.
        oracle (function): Function accepting the engine, an n-qubit register,
            and an output qubit which is flipped by the oracle for the correct
            bit string.

    Returns:
        solution (list<int>): Solution bit-string.
    """
    x = eng.allocate_qureg(n)

    # start in uniform superposition
    All(H) | x

    # number of iterations we have to run:
    num_it = int(math.pi / 4. * math.sqrt(1 << n))
    print("Number of iterations we have to run: {}".format(num_it))

    # prepare the oracle output qubit (the one that is flipped to indicate the
    # solution. start in state 1/sqrt(2) * (|0> - |1>) s.t. a bit-flip turns
    # into a (-1)-phase.
    oracle_out = eng.allocate_qubit()
    X | oracle_out
    H | oracle_out

    # run num_it iterations
    with Loop(eng, num_it):
        # oracle adds a (-1)-phase to the solution
        oracle(eng, x, oracle_out)

        # reflection across uniform superposition
        with Compute(eng):
            All(H) | x
            All(X) | x

        with Control(eng, x[0:-1]):
            Z | x[-1]

        Uncompute(eng)

        All(Ph(math.pi / n)) | x

    All(Measure) | x
    Measure | oracle_out

    eng.flush()
    # return result
    return [int(qubit) for qubit in x]
def oraculo(eng, x, ctrl):
    with Compute(eng):
        All(NOT) | x[1::2]
    with Control(eng, x):
        NOT | ctrl
    Uncompute(eng)
    return


n = 4  #numero de bits da estrutura a ser buscada
eng = MainEngine()  #IBMBackend(True))
x = eng.allocate_qureg(n)
All(H) | x
ctrl = eng.allocate_qubit()
NOT | ctrl
H | ctrl
with Loop(eng, int(sqrt(2**n))):  #ou for?
    oraculo(eng, x, ctrl)
    with Compute(eng):
        All(H) | x
        All(NOT) | x
    with Control(eng, x[0:-1]):
        Z | x[-1]
    Uncompute(eng)
Measure | x
eng.flush()
print "Posicao encontrada:"
for i in range(n):
    print int(x[i]),
def run_unknown_number_grover(eng, Dataset, oracle, threshold):
    """
    Runs modified Grover's algorithm to find an element in a set larger than a 
    given value threshold, using the provided quantum oracle.

    Args:
        eng (MainEngine): Main compiler engine to run Grover on.
        Dataset(list): The set to search for an element.
        oracle (function): Function accepting the engine, an n-qubit register, 
                            Dataset, the threshold, and an output qubit which is flipped by the
                            oracle for the correct bit string.
        threshold: the threshold

    Returns:
        solution (list<int>): the location of Solution.
    """
    N = len(Dataset)
    n = int(math.ceil(math.log(N, 2)))

    # number of iterations we have to run:
    num_it = int(math.sqrt(N) * 9 / 4)

    m = 1
    landa = 6 / 5

    # run num_it iterations
    i = 0
    while i < num_it:

        random.seed(i)
        j = random.randint(0, int(m))

        x = eng.allocate_qureg(n)

        # start in uniform superposition
        All(H) | x

        # prepare the oracle output qubit (the one that is flipped to indicate the
        # solution. start in state 1/sqrt(2) * (|0> - |1>) s.t. a bit-flip turns
        # into a (-1)-phase.
        oracle_out = eng.allocate_qubit()
        X | oracle_out
        H | oracle_out

        #run j iterations
        with Loop(eng, j):
            # oracle adds a (-1)-phase to the solution
            oracle(eng, x, Dataset, threshold, oracle_out)

            # reflection across uniform superposition
            with Compute(eng):
                All(H) | x
                All(X) | x

            with Control(eng, x[0:-1]):
                Z | x[-1]

            Uncompute(eng)

        All(Measure) | x
        Measure | oracle_out

        #read the measure value
        k = 0
        xvalue = 0
        while k < n:
            xvalue = xvalue + int(x[k]) * (2**k)
            k += 1

        #compare to threshold
        if Dataset[xvalue] > threshold:
            return xvalue
        m = m * landa
        i = i + 1

    #fail to find a solution (with high probability the solution doesnot exist)
    return ("no answer")
Exemplo n.º 11
0
        output_reg = eng.allocate_qureg(3)
        des_output = eng.allocate_qubit()
        ancilla_qubit = eng.allocate_qubit()
        ancilla2 = eng.allocate_qubit()
        phase_reg = eng.allocate_qureg(3)

        #initialize the ancilla and weight qubits
        X | ancilla_qubit
        H | ancilla_qubit

        All(H) | layer1_weight_reg
        All(H) | layer2_weight_reg

        #run the training cycle, one should adjust the number of loops and run the whole program again to get results for different iterations
        with Loop(eng, 2):
            run_qbnn(eng)

        H | ancilla_qubit
        X | ancilla_qubit

        All(Measure) | layer1_weight_reg
        All(Measure) | layer2_weight_reg

        eng.flush()

        print(
            "==========================================================================="
        )
        print("This is the QBNN demo")
        print("The measured weight string is")
Exemplo n.º 12
0
def SolveSudoku(eng, sudoku):
    '''
    Main function. Applies the grover algorithm one time to the qubits and returns the measured result. This result will be the solution of the sudoku with high probability.
    Args:
        eng (MainEngine): Main compiler engine the algorithm is being run on.
        sudoku (string): Sudoku codified in a string.
    '''
    #Prepare a list of suitable groups and a list of slot names, identified by an 'x'.
    groups = prep_sudoku(sudoku)
    l_slots = sorted(
        ['x' + sudoku[i + 1] for i in range(len(sudoku)) if sudoku[i] == 'x'],
        key=lambda n: int(n[1]))

    #Prepare a dictionary that assigns two qubits to each slot.
    qudic = {}
    for slot in l_slots:
        qudic[slot] = eng.allocate_qureg(2)
        q_list = [q for key in qudic.keys() for q in qudic[key]]

    #Compute the number of Grover iterations
    num_it = int(math.pi / 4. * math.sqrt(1 << len(q_list)))

    #Create one ancilla per group
    ancillas = eng.allocate_qureg(len(groups))

    #Prepare the oracle qubit, used to mark with a negative phase the sudoku solution
    phase_q = eng.allocate_qubit()
    X | phase_q
    H | phase_q

    #Start the superposition state
    All(H) | q_list

    with Loop(eng, num_it):
        #Generate the oracles and connect them to their group ancilla.
        with Compute(eng):
            apply_oracles(eng, groups, qudic, ancillas)

        #Most important step. Applies a toffoli gate between all the ancillas and the phase qubit. The state that fulfills the sudoku rules for all the groups, and thus solves the sudoku, will get a minus sign.
        with Control(eng, ancillas):
            X | phase_q
        #Uncompute to clean the ancillas for future iterations
        Uncompute(eng)

        #Apply Grover diffusion operator
        All(H) | q_list
        All(X) | q_list
        with Control(eng, q_list):
            X | phase_q
        All(X) | q_list
        All(H) | q_list

    #Measure everything
    All(Measure) | q_list
    All(Measure) | ancillas
    Measure | phase_q

    # Call the main engine to execute
    eng.flush()

    # Obtain the output. The measured result will be the solution with high probability.
    results = ''
    for q in q_list:
        results = results + str(int(q))

    #Translate the bit string to a list of numbers
    xlist = bin_to_n(results)
    return xlist
Exemplo n.º 13
0
def run_exactgrover(eng, n, oracle, oracle_modified):
    """
    Runs exact Grover's algorithm on n qubit using the two kind of provided 
    quantum oracles (oracle and oracle_modified).
    This is an algorithm which can output solution with probability 1.

    Args:
        eng (MainEngine): Main compiler engine to run Grover on.
        n (int): Number of bits in the solution.
        oracle (function): Function accepting the engine, an n-qubit register,
            and an output qubit which is flipped by the oracle for the correct
            bit string.

    Returns:
        solution (list<int>): Solution bit-string.
    """
    x = eng.allocate_qureg(n)

    # start in uniform superposition
    All(H) | x

    # number of iterations we have to run:
    num_it = int(math.pi/4.*math.sqrt(1 << n))
    
    #phi is the parameter of modified oracle
    #varphi is the parameter of reflection across uniform superposition
    theta=math.asin(math.sqrt(1/(1 << n)))
    phi=math.acos(-math.cos(2*theta)/(math.sin(2*theta)*math.tan((2*num_it+1)*theta)))
    varphi=math.atan(1/(math.sin(2*theta)*math.sin(phi)*math.tan((2*num_it+1)*theta)))*2

    # prepare the oracle output qubit (the one that is flipped to indicate the
    # solution. start in state 1/sqrt(2) * (|0> - |1>) s.t. a bit-flip turns
    # into a (-1)-phase.
    oracle_out = eng.allocate_qubit()
    X | oracle_out
    H | oracle_out

    # run num_it iterations
    with Loop(eng, num_it):
        # oracle adds a (-1)-phase to the solution
        oracle(eng, x, oracle_out)

        # reflection across uniform superposition
        with Compute(eng):
            All(H) | x
            All(X) | x

        with Control(eng, x[0:-1]):
            Z | x[-1]

        Uncompute(eng)
   
    # prepare the oracle output qubit (the one that is flipped to indicate the
    # solution. start in state |1> s.t. a bit-flip turns into a e^(i*phi)-phase. 
    H | oracle_out
    oracle_modified(eng, x, oracle_out, phi)
    
    with Compute(eng):
        All(H) | x
        All(X) | x

    with Control(eng, x[0:-1]):
        Rz(varphi) | x[-1]
        Ph(varphi/2) | x[-1]

    Uncompute(eng)
    
    All(Measure) | x
    Measure | oracle_out

    eng.flush()
    # return result
    return [int(qubit) for qubit in x]
Exemplo n.º 14
0
        layer1_weight_reg = eng.allocate_qureg(3)
        layer1_input_reg = eng.allocate_qureg(3)

        output = eng.allocate_qubit()
        des_output = eng.allocate_qubit()
        ancilla_qubit2 = eng.allocate_qubit()
        ancilla_qubit = eng.allocate_qubit()
        phase_reg = eng.allocate_qureg(3)

        X | ancilla_qubit
        H | ancilla_qubit

        All(H) | layer1_weight_reg

        #run the training cycle, one should adjust the number of loops and run the whole program again to get results for different iterations
        with Loop(eng, 1):
            run_qbnn(eng)

        H | ancilla_qubit
        X | ancilla_qubit

        eng.flush()

        w1 = eng.backend.get_probability('000', layer1_weight_reg)
        w2 = eng.backend.get_probability('001', layer1_weight_reg)
        w3 = eng.backend.get_probability('010', layer1_weight_reg)
        w4 = eng.backend.get_probability('011', layer1_weight_reg)
        w5 = eng.backend.get_probability('100', layer1_weight_reg)
        w6 = eng.backend.get_probability('101', layer1_weight_reg)
        w7 = eng.backend.get_probability('110', layer1_weight_reg)
        w8 = eng.backend.get_probability('111', layer1_weight_reg)
def tracjectory_simplify(eng,
                         Dataset,
                         targetPoint=5,
                         LSSEDthreshold=0,
                         simType="#"):
    """
    The algorithm to find the maximum data in a dataset. The length of the input
    dataset should be 2^x, x is a positive integer.
    
    Args:
        eng (MainEngine): Main compiler engine the algorithm is being run on.
        Dataset(list): The dataset.
    """

    d_1 = 9999999

    N = len(Dataset)
    qubitLength = N - 2
    #all possible solutions since we fixed 2 xs
    Nsolution = pow(2, N - 2)

    memo = [[False for i in range(len(Dataset))] for j in range(len(Dataset))]

    if (simType == "#"):
        d_0 = ""
        for i in range(0, ((len(Dataset) - 2) - (targetPoint - 2))):
            d_0 += '0'
        for i in range(0, targetPoint - 2):
            d_0 += '1'
    else:
        d_0 = ""
        for i in range(0, (len(Dataset) - 2)):
            d_0 += '1'

    [d_0LSSED, memo] = LSSEDSTATE(simTraj, '1' + d_0 + '1', memo)
    d_1LSSED = d_0LSSED
    # c=math.floor(1/2*pow(2,N-2))
    c = 10
    i = 0
    for i in range(0, c):
        #F = oracle
        if (i == 0):
            print("initial guessing is ", '1' + d_0 + '1')
            print("with SED", d_0LSSED)
        oracleFunction = oracleF(Dataset,
                                 d_0LSSED,
                                 simType=simType,
                                 LSSEDthreshold=LSSEDthreshold,
                                 targetPoint=targetPoint - 2,
                                 memo=memo)
        # print(F)
        while (simType == "#" and (
            (d_1 == 9999999) or
            (d_1LSSED > d_0LSSED
             or count_set_bitsString(d_1) != targetPoint - 2))) or (
                 simType == "SED" and
                 ((d_1 == 9999999) or
                  ((d_1LSSED > d_0LSSED and d_0LSSED != 0)
                   or LSSEDthreshold < d_1LSSED
                   or count_set_bitsString(d_1) > count_set_bitsString(d_0)))):
            # print('d_1 > d_0')
            # print(simType)
            # print(d_0)
            # print(d_1)
            # print(d_1LSSED)
            # print(d_0LSSED)
            # print(count_set_bitsString(d_1))
            # print(count_set_bitsString(d_0))
            #map F to quantum state
            #grover long
            # sineBeta = np.sqrt(Msolution/Nsolution)
            # beta = np.arcsin(sineBeta)
            # # find J >= floor((np.pi-beta)/beta) + 1
            # J = math.floor((math.pi-beta)/beta) + 1
            # print("J",J)
            # angleRotation = 2* np.arcsin(  math.sin( np.pi/((4*J)+2) )  /  sineBeta  )
            # print("angleRotation",angleRotation)
            #phase rotation on qubits with J iteration
            if (simType == "#"):
                mapAllstate = [
                    oracleFunction(Int2binString(elem, qubitLength), d_1LSSED,
                                   memo) for elem in range(pow(2, qubitLength))
                ]
            else:
                mapAllstate = [
                    oracleFunction(Int2binString(elem, qubitLength), d_1LSSED,
                                   count_set_bitsString(d_0), LSSEDthreshold,
                                   memo) for elem in range(pow(2, qubitLength))
                ]
            # print(mapAllstate)
            if (sum(mapAllstate) == 0):
                d_1 = d_0
                break
            num = [0] * (qubitLength)
            p = mapAllstate.index(1)
            # print('p',p, LSSEDSTATE(Dataset,'1'+Int2binString(p,qubitLength)+'1') )
            mapAllstate[p] = 0
            mapAllstate[p] = 0
            binaryIndex = 0
            while p / 2 != 0:
                num[binaryIndex] = p % 2
                p = p // 2
                binaryIndex += 1
            # print("num",num)
            # a1 = sum(elemnum)
            # num1=num.copy()
            # while a1>0:
            #     p = num1.index(1)
            #     a1 = a1-1
            #     num1[p]=0
            #     print("mark qubit at",p)
            #     X | z[p]
            # with Control(eng, z):
            #     X | oracle_out
            # print("num again",num)
            # a1=sum(num)
            # while a1>0:
            #     p = num.index(1)
            #     a1 = a1-1
            #     num[p]=0
            #     print("mark2 qubit at",p)
            #     X | z[p]
            z = eng.allocate_qureg(qubitLength)

            # start in uniform superposition
            All(H) | z

            # number of iterations we have to run:
            num_it = int(math.pi / 4. * math.sqrt(1 << qubitLength))

            #phi is the parameter of modified oracle
            #varphi is the parameter of reflection across uniform superposition
            theta = math.asin(math.sqrt(1 / (1 << qubitLength)))
            phi = math.acos(-math.cos(2 * theta) /
                            (math.sin(2 * theta) * math.tan(
                                (2 * num_it + 1) * theta)))
            varphi = math.atan(1 /
                               (math.sin(2 * theta) * math.sin(phi) * math.tan(
                                   (2 * num_it + 1) * theta))) * 2

            # prepare the oracle output qubit (the one that is flipped to indicate the
            # solution. start in state 1/sqrt(2) * (|0> - |1>) s.t. a bit-flip turns
            # into a (-1)-phase.
            oracle_out = eng.allocate_qubit()
            X | oracle_out
            H | oracle_out

            # run num_it iterations
            with Loop(eng, num_it):
                # oracle adds a (-1)-phase to the solution
                with Compute(eng):
                    #be 0
                    for k in range(qubitLength):
                        if (num[k] == 0):
                            X | z[k]
                    # X | z[1]
                    # X | z[4]
                    # X | z[5]
                with Control(eng, z):
                    X | oracle_out
                Uncompute(eng)

                # reflection across uniform superposition
                with Compute(eng):
                    All(H) | z
                    All(X) | z

                with Control(eng, z[0:-1]):
                    Z | z[-1]

                Uncompute(eng)

            # prepare the oracle output qubit (the one that is flipped to indicate the
            # solution. start in state |1> s.t. a bit-flip turns into a e^(i*phi)-phase.
            H | oracle_out
            with Compute(eng):
                #be 1
                for k in range(qubitLength):
                    if (num[k] == 1):
                        X | z[k]
                # X| z[0]
                # X| z[2]
                # X| z[3]
            with Control(eng, z):
                Rz(phi) | oracle_out
                Ph(phi / 2) | oracle_out

            Uncompute(eng)

            with Compute(eng):
                All(H) | z
                All(X) | z

            with Control(eng, z[0:-1]):
                Rz(varphi) | z[-1]
                Ph(varphi / 2) | z[-1]

            Uncompute(eng)

            All(Measure) | z
            Measure | oracle_out
            eng.flush()
            xprime_i = ""
            for z_i in z:
                if (int(z_i) == 0):
                    xprime_i = xprime_i + '0'
                else:
                    xprime_i = xprime_i + '1'
            xprime = xprime_i
            d_1 = xprime
            print("d_1", d_1)
            [d_1LSSED, memo] = LSSEDSTATE(simTraj, '1' + d_1 + '1', memo)
        if (simType == "#" and
            (d_1LSSED < d_0LSSED
             and count_set_bitsString(d_1) == targetPoint - 2)) or (
                 simType == "SED" and
                 (d_1LSSED < d_0LSSED
                  and count_set_bitsString(d_1) < count_set_bitsString(d_0))):
            print('d_1 < d_0')
            i = 0
        elif (simType == "#" and
              (d_1LSSED == d_0LSSED
               and count_set_bitsString(d_1) == targetPoint - 2)) or (
                   simType == "SED" and
                   (d_1LSSED < d_0LSSED and count_set_bitsString(d_1)
                    == count_set_bitsString(d_0))):
            print('d_1 == d_0')
            print("d_1", d_1)
            # return '1'+d_0+'1'
            shit = 1
            return '1' + d_1 + '1'
        print('set d_0=d_1')
        d_0 = d_1
        d_0LSSED = d_1LSSED
        if (simType == "#"):
            d_1 = 9999999
        else:
            d_1 = 9999999
    print("break with c", c)
    return '1' + d_0 + '1'
def grover_long(eng,
                Dataset,
                oracle,
                threshold,
                targetPoint=5,
                LSSEDthreshold=0,
                simType="#",
                prevSED=0,
                memo=[]):
    """
    Runs modified Grover's algorithm to find an element in a set larger than a 
    given value threshold, using the provided quantum oracle.

    Args:
        eng (MainEngine): Main compiler engine to run Grover on.
        Dataset(list): The set to search for an element.
        oracle (function): Function accepting the engine, an n-qubit register, 
        Dataset, the threshold, and an output qubit which is flipped by the
        oracle for the correct bit string.
        threshold: the threshold.

    Returns:
        solution (list<int>): the location of Solution.
    """
    N = pow(2, len(Dataset) - 2)
    n = int(math.ceil(math.log(N, 2)))

    # number of iterations we have to run:
    num_it = int(math.sqrt(N) * 9 / 4)

    m = 1
    landa = 6 / 5

    # run num_it iterations
    i = 0
    while i < num_it:

        random.seed(i)
        j = random.randint(0, int(m))

        x = eng.allocate_qureg(n)

        All(H) | x

        oracle_out = eng.allocate_qubit()
        X | oracle_out
        H | oracle_out

        with Loop(eng, j):

            oracle(eng,
                   x,
                   Dataset,
                   threshold,
                   oracle_out,
                   targetPoint=targetPoint,
                   simType=simType,
                   LSSEDthreshold=LSSEDthreshold,
                   prevSED=prevSED,
                   memo=memo)

            with Compute(eng):
                All(H) | x
                All(X) | x

            with Control(eng, x[0:-1]):
                Z | x[-1]

            Uncompute(eng)

        All(Measure) | x
        Measure | oracle_out

        k = 0
        xvalue = 0
        z_i = ""
        for i in range(len(x)):
            # print(int(x[k]))
            # xvalue=xvalue+int(x[k])*(2**k)
            if (int(x[i]) == 0):
                z_i += '0'
            else:
                z_i += '1'
            # k+=1
        # print(z_i)
        # print(int(x))
        #
        #     print(int(x[i]))
        #     # if(int(x[i])==0):
        #     #     z_i+='0'
        #     # else:
        #     #     z_i+='1'
        [curLSSED, memo] = LSSEDSTATE(simTraj, '1' + z_i + '1', memo)
        if (simType == "#"):
            if (count_set_bitsString(z_i) == (targetPoint - 2)):
                if (curLSSED < threshold):
                    return [z_i, memo]
        else:
            if (((curLSSED < threshold and count_set_bitsString(z_i)
                  == count_set_bitsString(prevSED))
                 or count_set_bits(z_i) < count_set_bits(prevSED))
                    and curLSSED < LSSEDthreshold):
                return [z_i, memo]
            if (prevSED == 0 and curLSSED < LSSEDthreshold):
                return [z_i, memo]
        m = m * landa
        i = i + 1

    #fail to find a solution (with high probability the solution doesnot exist)
    return ["no answer", memo]