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
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
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, )