Ejemplo n.º 1
0
    def create_qsvt_circuit(num_qubits, num_ancillas, add_measurements,
                            block_encoding, block_encoding_inv, angles):
        qsvt_circuit = Circuit()
        if num_ancillas != 1:
            raise NotImplementedError(
                "The general QSVT circuit generation is not yet implemented!")
        else:
            qubits = list(range(1, num_qubits + 1))

            # Quanutm Singular Value Transformation
            qsvt_circuit.h(0)
            for i in range(0, len(angles)):
                if i % 2 == 0:
                    qsvt_circuit.add_circuit(block_encoding, target=qubits)
                else:
                    qsvt_circuit.add_circuit(block_encoding_inv, target=qubits)
                # qsvt_circuit.x(1)
                qsvt_circuit.cnot(1, 0)
                qsvt_circuit.rz(0, -2 * angles[i])
                # For debugging purposes to get the global phase right replace the above line with the following:
                # qsvt_circuit.u1(-angles[i],0)
                # qsvt_circuit.x(0)
                # qsvt_circuit.u1(angles[i],0)
                # qsvt_circuit.x(0)
                qsvt_circuit.cnot(1, 0)
                # qsvt_circuit.x(1)
            qsvt_circuit.h(0)

            return qsvt_circuit
Ejemplo n.º 2
0
def grover_iterator(A, flag_qubit, qubits=None, use_explicit_unitary=False):
    """
    Function to implement the Grover iterator Q=A R_0 A* R_B.

    Args:
        A: Circuit defining the unitary A
        flag_qubit: Specifies which of the qubits A acts on labels the good/bad subspace.
                    Must be an element of qubits (if passed) or A.qubits.
        qubits: list of qubits on which to apply the gates (including the flag_qubit).
                If qubits is different from A.qubits, A is applied to qubits instead.
        use_explicit_unitary: Flag to specify that we should implement R_0 using using a custom
                              gate defined by the unitary diag(-1,1,...,1). Default is False.
    """
    # If no qubits are passed, apply the gates to the targets of A
    if qubits is None:
        qubits = A.qubits
    else:
        # If qubits are passed, make sure it's the right number to remap from A.
        if len(qubits) != len(A.qubits):
            raise ValueError(
                "Number of desired target qubits differs from number of targets in A"
                .format(flag_qubit=repr(flag_qubit)))

    # Verify that flag_qubit is one of the qubits on which A acts, or one of the user defined qubits
    if flag_qubit not in qubits:
        raise ValueError(
            "flag_qubit {flag_qubit} is not in targets of A".format(
                flag_qubit=repr(flag_qubit)))

    # Instantiate the circuit
    circ = Circuit()

    # Apply -R_B to the flag qubit
    circ.minus_R_B(flag_qubit)

    # Apply A^\dagger. Use target mapping if different qubits are specified
    circ.add_circuit(A.adjoint(), target=qubits)

    # Apply -R_0
    circ.minus_R_zero(qubits, use_explicit_unitary)

    # Apply A, mapping targets if desired.
    circ.add_circuit(A, target=qubits)

    return circ
Ejemplo n.º 3
0
    def job_factory(matrix, num_shots, shots_multiplier, add_measurements):
        if matrix is None:
            raise NotImplementedError("The matrix is Not specified")
        num_qubits = matrix["qubits"]
        num_ancillas = matrix["ancillas"]

        if num_ancillas != 1:
            raise NotImplementedError(
                "The general HHL circuit generation is not yet implemented!")

        # Build block-encoding of A
        block_encoding = Circuit()
        HHLJob.list_to_circuit(matrix["circuit"], block_encoding)
        # block_encoding.draw()

        # Angles describing the polynomial inverting A
        angles = matrix["angles"]

        # Quanutm Singular Value Transformation
        qsvt_circuit = HHLJob.create_qsvt_circuit(
            num_qubits,
            num_ancillas,
            add_measurements,
            block_encoding.adjoint(),
            block_encoding,
            angles,
        )

        # For debug purposes
        # reorder = QuantumCircuit(num_qubits+1)
        # reorder.swap(0,3)
        # reorder.swap(1,2)

        # Debugging the circuit
        # print(block_encoding)
        # print_unitary=reorder.compose(block_encoding,qubits=list(range(1,num_qubits + 1))).extend(reorder)
        # #job execution and getting the unitary matrix of the circuit
        # job = execute(print_unitary, BasicAer.get_backend('unitary_simulator'))
        # print(DataFrame(job.result().get_unitary(print_unitary, decimals=2)))

        # raise NotImplementedError("Stop now")

        # Debugging the circuit
        # print(qsvt_circuit)
        # print_unitary=reorder.combine(qsvt_circuit).extend(reorder)
        # # job execution and getting the unitary matrix of the circuit
        # job = execute(print_unitary, BasicAer.get_backend('unitary_simulator'))
        # print(DataFrame(job.result().get_unitary(print_unitary, decimals=2)))

        used_qubits = num_qubits - num_ancillas

        for m_idx in range(shots_multiplier):
            for basis_vec in range(0, 2**used_qubits):
                instance_circuit = Circuit()
                # Here we assume that there is a single ancilla
                instance_circuit.x(1)
                for i in range(used_qubits):
                    if basis_vec % 2**(i + 1) >= 2**i:
                        instance_circuit.x(num_qubits - i)
                instance_circuit.add_circuit(qsvt_circuit)

                yield HHLJob(
                    instance_circuit,
                    num_qubits,
                    num_ancillas,
                    basis_vec,
                    num_shots,
                    m_idx,
                    add_measurements,
                )