def create_swap_test_old_circuit(index_state,
                                 theta,
                                 use_barriers=False,
                                 readout_swap=None):
    q = qiskit.QuantumRegister(5, "q")
    c = qiskit.ClassicalRegister(2, "c")
    qc = qiskit.QuantumCircuit(q, c, name="improvement")

    # Index on q_0
    h(qc, q[0])
    if use_barriers: barrier(qc)

    # Conditionally exite x_1 on data q_2 (center!)
    h(qc, q[2])
    if use_barriers: barrier(qc)
    rz(qc, math.pi, q[2]).inverse()
    if use_barriers: barrier(qc)
    s(qc, q[2])
    if use_barriers: barrier(qc)
    cz(qc, q[0], q[2])
    if use_barriers: barrier(qc)

    # Label y_1
    cx(qc, q[0], q[1])
    if use_barriers: barrier(qc)

    # Ancilla Superposition
    h(qc, q[4])
    if use_barriers: barrier(qc)

    # Unknown data
    #     standard.rx(qc, theta - 0.2*math.pi, q[3])
    rx(qc, theta, q[3])
    if use_barriers: barrier(qc)

    # c-SWAP!!!
    cswap(qc, q[4], q[2], q[3])
    if use_barriers: barrier(qc)

    # Hadamard on ancilla q_4
    h(qc, q[4])

    # Measure on ancilla q_4 and label q_1
    if readout_swap is not None:
        barrier(qc)
        for i in range(q.size):
            j = readout_swap.get(i, i)
            if i != j:
                swap(qc, q[i], q[j])
    else:
        readout_swap = {}

    barrier(qc)
    m1 = readout_swap.get(4, 4)
    m2 = readout_swap.get(1, 1)
    qiskit.circuit.measure.measure(qc, q[m1], c[0])
    qiskit.circuit.measure.measure(qc, q[m2], c[1])

    return qc
def create_product_state_n_copies_circuit(index_state,
                                          theta,
                                          copies=1,
                                          use_barriers=False):
    a = qiskit.QuantumRegister(1, "a")
    index = qiskit.QuantumRegister(1, "m")
    d = qiskit.QuantumRegister(copies, "d")
    label = qiskit.QuantumRegister(1, "l")
    inp = qiskit.QuantumRegister(copies, "in")

    c = qiskit.ClassicalRegister(2, "c")
    qc = qiskit.QuantumCircuit(a, index, d, label, inp, c, name="improvement")

    # Index on q_0
    alpha_y, _ = compute_rotation(index_state)
    if alpha_y is None:
        h(qc, index)
    else:
        ry(qc, -alpha_y, index).inverse()
    if use_barriers: barrier(qc)

    # Unknown data
    for copy in range(copies):
        rx(qc, theta, inp[copy])
        if use_barriers: barrier(qc)

    # Conditionally exite x_1 on data q_2 (center!)
    for copy in range(copies):
        h(qc, d[copy])
        if use_barriers: barrier(qc)
        rz(qc, math.pi, d[copy]).inverse()
        if use_barriers: barrier(qc)
        s(qc, d[copy])
        if use_barriers: barrier(qc)
        cz(qc, index, d[copy])
        if use_barriers: barrier(qc)

    # Label y_1
    cx(qc, index, label)
    if use_barriers: barrier(qc)

    barrier(qc)
    # Ancilla Superposition
    h(qc, a)
    if use_barriers: barrier(qc)

    # c-SWAP!!!

    for copy in range(copies):
        cswap(qc, a[0], d[copy], inp[copy])
        if use_barriers: barrier(qc)

    # Hadamard on ancilla
    h(qc, a)
    if use_barriers: barrier(qc)

    # Measure on ancilla and label
    barrier(qc)
    qiskit.circuit.measure.measure(qc, a[0], c[0])
    qiskit.circuit.measure.measure(qc, label[0], c[1])

    return qc
def create_swap_test_circuit_ourense(index_state, theta, **kwargs):
    # type: (List[float], float, Optional[dict]) -> QuantumCircuit
    """

    :param index_state:
    :param theta:
    :param kwargs: use_barriers (bool) and readout_swap (Dict[int, int])
    :return:
    """
    use_barriers = kwargs.get('use_barriers', False)
    readout_swap = kwargs.get('readout_swap', None)

    q = qiskit.QuantumRegister(5, "q")
    qb_a, qb_d, qb_in, qb_m, qb_l = (q[0], q[1], q[2], q[3], q[4])
    c = qiskit.ClassicalRegister(2, "c")
    qc = qiskit.QuantumCircuit(q, c, name="swap_test_ourense")

    # Index on q_0
    alpha_y, _ = compute_rotation(index_state)
    if alpha_y is None:
        h(qc, qb_m)
    else:
        ry(qc, -alpha_y, qb_m).inverse()
    if use_barriers: barrier(qc)

    # Conditionally exite x_1 on data q_2 (center!)
    h(qc, qb_d)
    if use_barriers: barrier(qc)
    rz(qc, math.pi, qb_d).inverse()
    if use_barriers: barrier(qc)
    s(qc, qb_d)
    if use_barriers: barrier(qc)
    cz(qc, qb_m, qb_d)
    if use_barriers: barrier(qc)

    # Label y_1
    cx(qc, qb_m, qb_l)
    if use_barriers: barrier(qc)

    # Unknown data
    rx(qc, theta, qb_in)
    if use_barriers: barrier(qc)

    # Swap-Test itself
    # Hadamard on ancilla
    h(qc, qb_a)
    if use_barriers: barrier(qc)

    # c-SWAP!!!
    qc.append(Ourense_Fredkin(), [qb_a, qb_in, qb_d], [])
    if use_barriers: barrier(qc)

    # Hadamard on ancilla
    h(qc, qb_a)
    if use_barriers: barrier(qc)

    # Measure on ancilla and label
    if readout_swap is not None:
        barrier(qc)
        for i in range(q.size):
            j = readout_swap.get(i, i)
            if i != j:
                swap(qc, q[i], q[j])
    else:
        readout_swap = {}

    barrier(qc)
    readout_swap_qb = dict(
        map(lambda k, v: (q[k], q[v]),
            readout_swap))  # type: Dict[QuantumRegister, QuantumRegister]
    m1 = readout_swap_qb.get(qb_a, qb_a)
    m2 = readout_swap_qb.get(qb_l, qb_l)
    qiskit.circuit.measure.measure(qc, m1, c[0])
    qiskit.circuit.measure.measure(qc, m2, c[1])

    return qc
def create_hadamard_circuit_ourense(index_state, theta, **kwargs):
    # type: (List[float], float, Optional[dict]) -> QuantumCircuit
    """

    :param index_state:
    :param theta:
    :param kwargs: use_barriers (bool) and readout_swap (Dict[int, int])
    :return:
    """
    use_barriers = kwargs.get('use_barriers', False)
    readout_swap = kwargs.get('readout_swap', None)

    q = qiskit.QuantumRegister(4, "q")
    c = qiskit.ClassicalRegister(2, "c")
    qc = qiskit.QuantumCircuit(q, c, name="hadmard-classifier")

    q_m = q[2]
    q_a = q[0]
    q_d = q[1]
    q_l = q[3]

    # Index on q_0
    alpha_y, _ = compute_rotation(index_state)
    if alpha_y is None:
        h(qc, q_m)
    else:
        rx(qc, -alpha_y, q_m).inverse()
    if use_barriers: barrier(qc)

    # Ancilla Superposition
    h(qc, q_a)
    if use_barriers: barrier(qc)

    # Test Data
    cu3(qc, theta - 0.0 * math.pi, -math.pi / 2, math.pi / 2, q_a, q_d)
    if use_barriers: barrier(qc)

    # Training Data
    ## Conditionally excite x_1 on data q_2 (center!)
    x(qc, q_a)
    if use_barriers: barrier(qc)
    ch(qc, q_a, q_d)
    if use_barriers: barrier(qc)
    crz(qc, math.pi + 0.0 * math.pi, q_a, q_d).inverse()
    if use_barriers: barrier(qc)
    cu1(qc, math.pi / 2 - 0.0 * math.pi, q_a, q_d)
    if use_barriers: barrier(qc)
    ## 2-Controlled Z-Gate
    h(qc, q_d)
    if use_barriers: barrier(qc)
    ### Logical Swap on q_m & q_d
    # qc.append(Ourense_ToffoliGate(), [q_a, q_m, q_d], [])
    ccx(qc, q_a, q_m, q_d)
    if use_barriers: barrier(qc)
    # h(qc, q_m) # q_d -> q_m swapped
    h(qc, q_d)  # q_d -> q_m swapped
    if use_barriers: barrier(qc)

    # Label y_1
    # cx(qc, q_d, q_l) # q_m -> q_d swapped
    cx(qc, q_m, q_l)  # q_m -> q_d swapped
    if use_barriers: barrier(qc)

    # Hadamard on ancilla
    h(qc, q_a)
    if use_barriers: barrier(qc)

    # Measure on ancilla and label
    if readout_swap is not None:
        barrier(qc)
        for i in range(q.size):
            j = readout_swap.get(i, i)
            if i != j:
                swap(qc, q[i], q[j])
    else:
        readout_swap = {}

    barrier(qc)
    readout_swap_qb = dict(
        map(lambda k, v: (q[k], q[v]),
            readout_swap))  # type: Dict[QuantumRegister, QuantumRegister]
    m1 = readout_swap_qb.get(q_a, q_a)
    m2 = readout_swap_qb.get(q_l, q_l)
    qiskit.circuit.measure.measure(qc, m1, c[0])
    qiskit.circuit.measure.measure(qc, m2, c[1])

    return qc
def create_swap_test_circuit(index_state, theta, **kwargs):
    # type: (List[float], float, Optional[dict]) -> QuantumCircuit
    """

    :param index_state:
    :param theta:
    :param kwargs: use_barriers (bool) and readout_swap (Dict[int, int])
    :return:
    """
    use_barriers = kwargs.get('use_barriers', False)
    readout_swap = kwargs.get('readout_swap', None)

    q = qiskit.QuantumRegister(5, "q")
    c = qiskit.ClassicalRegister(2, "c")
    qc = qiskit.QuantumCircuit(q, c, name="improvement")

    # Index on q_0
    alpha_y, _ = compute_rotation(index_state)
    if alpha_y is None:
        h(qc, q[0])
    else:
        ry(qc, -alpha_y, q[0]).inverse()
    if use_barriers: barrier(qc)

    # Conditionally exite x_1 on data q_2 (center!)
    h(qc, q[2])
    if use_barriers: barrier(qc)
    rz(qc, math.pi, q[2]).inverse()
    if use_barriers: barrier(qc)
    s(qc, q[2])
    if use_barriers: barrier(qc)
    cz(qc, q[0], q[2])
    if use_barriers: barrier(qc)

    # Label y_1
    cx(qc, q[0], q[1])
    if use_barriers: barrier(qc)

    # Ancilla Superposition
    h(qc, q[4])
    if use_barriers: barrier(qc)

    # Unknown data
    rx(qc, theta, q[3])
    if use_barriers: barrier(qc)

    # c-SWAP!!!
    # standard.barrier(qc)
    cswap(qc, q[4], q[2], q[3])
    if use_barriers: barrier(qc)

    # Hadamard on ancilla q_4
    h(qc, q[4])
    if use_barriers: barrier(qc)

    # Measure on ancilla q_4 and label q_1
    if readout_swap is not None:
        barrier(qc)
        for i in range(q.size):
            j = readout_swap.get(i, i)
            if i != j:
                swap(qc, q[i], q[j])
    else:
        readout_swap = {}

    barrier(qc)
    m1 = readout_swap.get(4, 4)
    m2 = readout_swap.get(1, 1)
    qiskit.circuit.measure.measure(qc, q[m1], c[0])
    qiskit.circuit.measure.measure(qc, q[m2], c[1])

    return qc