def setUp(self): super().setUp() self._oracle = Statevector.from_label('111') self._expected_grover_op = GroverOperator(oracle=self._oracle) self._expected = QuantumCircuit(self._expected_grover_op.num_qubits) self._expected.compose(self._expected_grover_op.state_preparation, inplace=True) self._expected.compose(self._expected_grover_op.power(2), inplace=True) backend = BasicAer.get_backend('statevector_simulator') self._sv = QuantumInstance(backend)
def test_state_to_matrix(self): """ state to matrix test """ np.testing.assert_array_equal(Zero.to_matrix(), np.array([1, 0])) np.testing.assert_array_equal(One.to_matrix(), np.array([0, 1])) np.testing.assert_array_almost_equal(Plus.to_matrix(), (Zero.to_matrix() + One.to_matrix()) / (np.sqrt(2))) np.testing.assert_array_almost_equal(Minus.to_matrix(), (Zero.to_matrix() - One.to_matrix()) / (np.sqrt(2))) # TODO Not a great test because doesn't test against validated values # or test internal representation. Fix this. gnarly_state = (One ^ Plus ^ Zero ^ Minus * .3) @ \ StateFn(Statevector.from_label('r0+l')) + (StateFn(X ^ Z ^ Y ^ I) * .1j) gnarly_mat = gnarly_state.to_matrix() gnarly_mat_separate = (One ^ Plus ^ Zero ^ Minus * .3).to_matrix() gnarly_mat_separate = np.dot(gnarly_mat_separate, StateFn(Statevector.from_label('r0+l')).to_matrix()) gnarly_mat_separate = gnarly_mat_separate + (StateFn(X ^ Z ^ Y ^ I) * .1j).to_matrix() np.testing.assert_array_almost_equal(gnarly_mat, gnarly_mat_separate)
def test_state_max_size(self): """Test `max_size` parameter for latex ket notation.""" sv = Statevector.from_label("+-rl") output = state_drawer(sv, "latex_source", max_size=4) expected_output = ( r"\frac{1}{4} |0000\rangle- \frac{i}{4} |0001\rangle" r" + \ldots - \frac{1}{4} |1111\rangle" ) self.assertEqual(output, expected_output)
def test_fusion_output(self): """Test Fusion returns same final unitary""" seed = 54321 circuit = QuantumVolume(4, seed=seed) circuit = transpile(circuit, self.SIMULATOR) qobj = assemble([circuit], shots=1) options_disabled = self.fusion_options(enabled=False, threshold=1) result_disabled = self.SIMULATOR.run( qobj, backend_options=options_disabled).result() self.assertSuccess(result_disabled) options_enabled = self.fusion_options(enabled=True, threshold=1) result_enabled = self.SIMULATOR.run( qobj, backend_options=options_enabled).result() self.assertSuccess(result_enabled) sv_no_fusion = Statevector(result_disabled.get_statevector(0)) sv_fusion = Statevector(result_enabled.get_statevector(0)) self.assertEqual(sv_no_fusion, sv_fusion)
def __call__( self, circuit_indices: Sequence[int] | None = None, observable_indices: Sequence[int] | None = None, parameter_values: Sequence[Sequence[float]] | Sequence[float] | None = None, **run_options, ) -> EstimatorResult: if self._is_closed: raise QiskitError("The primitive has been closed.") if isinstance(parameter_values, np.ndarray): parameter_values = parameter_values.tolist() if parameter_values and not isinstance(parameter_values[0], (np.ndarray, Sequence)): parameter_values = cast("Sequence[float]", parameter_values) parameter_values = [parameter_values] if circuit_indices is None: circuit_indices = list(range(len(self._circuits))) if observable_indices is None: observable_indices = list(range(len(self._observables))) if parameter_values is None: parameter_values = [[]] * len(circuit_indices) if len(circuit_indices) != len(observable_indices): raise QiskitError( f"The number of circuit indices ({len(circuit_indices)}) does not match " f"the number of observable indices ({len(observable_indices)})." ) if len(circuit_indices) != len(parameter_values): raise QiskitError( f"The number of circuit indices ({len(circuit_indices)}) does not match " f"the number of parameter value sets ({len(parameter_values)})." ) bound_circuits = [] for i, value in zip(circuit_indices, parameter_values): if len(value) != len(self._parameters[i]): raise QiskitError( f"The number of values ({len(value)}) does not match " f"the number of parameters ({len(self._parameters[i])}).") bound_circuits.append(self._circuits[i].bind_parameters( dict(zip(self._parameters[i], value)))) sorted_observables = [self._observables[i] for i in observable_indices] expectation_values = [] for circ, obs in zip(bound_circuits, sorted_observables): if circ.num_qubits != obs.num_qubits: raise QiskitError( f"The number of qubits of a circuit ({circ.num_qubits}) does not match " f"the number of qubits of a observable ({obs.num_qubits})." ) expectation_values.append(Statevector(circ).expectation_value(obs)) return EstimatorResult(np.real_if_close(expectation_values), [{}] * len(expectation_values))
def test_global_phase_1q(self): """Test global phase preservation with some simple 1q statevectors""" target_list = [ Statevector([1j, 0]), Statevector([0, 1j]), Statevector([1j / np.sqrt(2), 1j / np.sqrt(2)]), ] n_qubits = 1 dim = 2**n_qubits qr = QuantumRegister(n_qubits) for target in target_list: with self.subTest(i=target): initializer = QuantumCircuit(qr) initializer.initialize(target, qr) # need to get rid of the resets in order to use the Operator class disentangler = Operator( initializer.data[0][0].definition.data[1][0]) zero = Statevector.from_int(0, dim) actual = zero @ disentangler self.assertEqual(target, actual)
def test_adjoint_vector_to_circuit_fn(self): """Test it is possible to adjoint a VectorStateFn that was converted to a CircuitStateFn.""" left = StateFn([0, 1]) left_circuit = left.to_circuit_op().primitive right_circuit = QuantumCircuit(1) right_circuit.x(0) circuit = left_circuit.inverse().compose(right_circuit) self.assertTrue(Statevector(circuit).equiv([1, 0]))
def __init__(self, state): """Create new instruction to set the statevector state of the simulator. Args: state (Statevector): a statevector. Raises: ExtensionError: if the input is not a valid state. .. note:: This set instruction must always be performed on the full width of qubits in a circuit, otherwise an exception will be raised during simulation. """ if not isinstance(state, Statevector): state = Statevector(state) if not state.num_qubits or not state.is_valid(): raise ExtensionError("The input statevector is not valid") super().__init__('set_statevector', state.num_qubits, 0, [state.data])
def test_bind_after_composition(self): """Test binding the parameters after the circuit was composed onto a larger one.""" circuit = QuantumCircuit(2) circuit.h([0, 1]) raw = RawFeatureVector(4) circuit.append(raw, [0, 1]) bound = circuit.bind_parameters([1, 0, 0, 0]) self.assertTrue(Statevector.from_label('00').equiv(bound))
def assertMultiplicationIsCorrect( self, num_state_qubits: int, num_result_qubits: int, multiplier: QuantumCircuit ): """Assert that multiplier correctly implements the product. Args: num_state_qubits: The number of bits in the numbers that are multiplied. num_result_qubits: The number of qubits to limit the output to with modulo. multiplier: The circuit performing the multiplication of two numbers with ``num_state_qubits`` bits. """ circuit = QuantumCircuit(*multiplier.qregs) # create equal superposition circuit.h(range(2 * num_state_qubits)) # apply multiplier circuit circuit.compose(multiplier, inplace=True) # obtain the statevector and the probabilities, we don't trace out the ancilla qubits # as we verify that all ancilla qubits have been uncomputed to state 0 again statevector = Statevector(circuit) probabilities = statevector.probabilities() pad = "0" * circuit.num_ancillas # state of the ancillas # compute the expected results expectations = np.zeros_like(probabilities) num_bits_product = num_state_qubits * 2 # iterate over all possible inputs for x in range(2 ** num_state_qubits): for y in range(2 ** num_state_qubits): # compute the product product = x * y % (2 ** num_result_qubits) # compute correct index in statevector bin_x = bin(x)[2:].zfill(num_state_qubits) bin_y = bin(y)[2:].zfill(num_state_qubits) bin_res = bin(product)[2:].zfill(num_bits_product) bin_index = pad + bin_res + bin_y + bin_x index = int(bin_index, 2) expectations[index] += 1 / 2 ** (2 * num_state_qubits) np.testing.assert_array_almost_equal(expectations, probabilities)
def test_rescaling(self): """Test the rescaling.""" amplitude = 0.8 scaling = 0.25 circuit = QuantumCircuit(1) circuit.ry(2 * np.arcsin(amplitude), 0) problem = EstimationProblem(circuit, objective_qubits=[0]) rescaled = problem.rescale(scaling) rescaled_amplitude = Statevector.from_instruction(rescaled.state_preparation).data[3] self.assertAlmostEqual(scaling * amplitude, rescaled_amplitude)
def run_random_circuits(backend, shots=None, **run_options): """Test random circuits on different executor fictures""" job_size = 10 circuits = [ random_circuit(num_qubits=2, depth=2, seed=i) for i in range(job_size) ] # Sample references counts targets = [] for circ in circuits: state = Statevector(circ) state.seed = 101 targets.append(state.sample_counts(shots=shots)) # Add measurements for simulation for circ in circuits: circ.measure_all() circuits = transpile(circuits, backend) job = backend.run(circuits, shots=shots, **run_options) result = job.result() return result, circuits, targets
def compare_statevector(result, circuits, targets, ignore_phase=False, atol=1e-8, rtol=1e-5): """Compare final statevectors to targets.""" for pos, test_case in enumerate(zip(circuits, targets)): circuit, target = test_case target = Statevector(target) output = Statevector(result.get_statevector(circuit)) equiv = matrix_equal(output.data, target.data, ignore_phase=ignore_phase, atol=atol, rtol=rtol) if equiv: return msg = "Circuit ({}/{}): {} != {}".format(pos + 1, len(circuits), output.data, target.data) raise Exception(msg)
def unitary_random_gate_counts_nondeterministic(shots): """Unitary gate test circuits with nondeterministic counts.""" # random_unitary seed = nq targets = [] for n in range(1, 5): unitary1 = random_unitary(2**n, seed=n) state = Statevector.from_label(n * '0').evolve(unitary1) state.seed(10) counts = state.sample_counts(shots=shots) hex_counts = {hex(int(key, 2)): val for key, val in counts.items()} targets.append(hex_counts) return targets
def test_max_num_iterations(self): """Test the iteration stops when the maximum number of iterations is reached.""" def zero(): while True: yield 0 grover = Grover(iterations=zero(), quantum_instance=self.statevector) n = 5 problem = AmplificationProblem(Statevector.from_label('1' * n), is_good_state=['1' * n]) result = grover.amplify(problem) self.assertEqual(len(result.iterations), 2**n)
def _init_grover_ops(self): """ Inits grover oracles for the actions set :return: a list of qiskit instructions ready to be appended to circuit """ states_binars = [ format(i, '0{}b'.format(self.acts_reg_dim)) for i in range(self.acts_dim) ] targ_states = [Statevector.from_label(s) for s in states_binars] grops = [GroverOperator(oracle=ts) for ts in targ_states] return [g.to_instruction() for g in grops]
def test_state(self): """Test latex state vector drawer works with default settings.""" sv = Statevector.from_label("+-rl") output = state_drawer(sv, "latex_source") expected_output = ( r"\frac{1}{4} |0000\rangle- \frac{i}{4} |0001\rangle+\frac{i}{4} |0010\rangle" r"+\frac{1}{4} |0011\rangle- \frac{1}{4} |0100\rangle+\frac{i}{4} |0101\rangle" r" + \ldots +\frac{1}{4} |1011\rangle- \frac{1}{4} |1100\rangle" r"+\frac{i}{4} |1101\rangle- \frac{i}{4} |1110\rangle- \frac{1}{4} |1111\rangle" ) self.assertEqual(output, expected_output)
def __init__(self, Qiskit_circuit): #takes input of Qiskit Circuit self.circuit = Qiskit_circuit self.num_levels = ( Qiskit_circuit.depth() ) #define the number of levels as the depth of the circuit. self.array = np.zeros( Operator(self.circuit).data.shape[0] ) #prepare an empty state vector with the dimension of the system self.array[0] = 1 self.initial = Statevector( self.array ) # this sets the initial state of the system to be the all zeros string.
def compare_statevector(self, result, circuits, targets, ignore_phase=False, atol=1e-8, rtol=1e-5): """Compare final statevectors to targets.""" for pos, test_case in enumerate(zip(circuits, targets)): circuit, target = test_case target = Statevector(target) output = Statevector(result.get_statevector(circuit)) test_msg = "Circuit ({}/{}):".format(pos + 1, len(circuits)) with self.subTest(msg=test_msg): msg = " {} != {}".format(output, target) delta = matrix_equal(output.data, target.data, ignore_phase=ignore_phase, atol=atol, rtol=rtol) self.assertTrue(delta, msg=msg)
def __init__(self, players = ["P1", "P2"]): N = 8 self.player1 = players[0] self.player2 = players[1] # Two boards. One for the quantum states associated with the board # Other one to store the values after measurement self.quantum_board = [[None]*N for _ in range(N)] self.classical_board = np.zeros([N, N]) self.classical_board[4][3] = 1 self.classical_board[3][4] = 1 self.classical_board[4][4] = 2 self.classical_board[3][3] = 2 # Store the positions of the gates self.h_squares = [[0,2],[0,5],[2,0],[5,0],[2,7],[5,7],[7,2],[7,5]] self.x_squares = [[2,2],[2,5],[5,2],[5,5]] self.cx_squares = [[1,1],[1,6],[6,1],[6,6]] self.en_squares = [[0,0],[0,7],[7,0],[7,7]] # States corresponding to what the player chooses q0 = Statevector([1,0]) q1 = Statevector([0,1]) qp = Statevector([1/np.sqrt(2), 1/np.sqrt(2)]) qm = Statevector([1/np.sqrt(2), -1/np.sqrt(2)]) q075 = Statevector([np.sqrt(3)/2, -1/2]) q175 = Statevector([1/2, np.sqrt(3)/2]) self.state_dict = {1:q0, 2:q1, 3:qp, 4:qm, 5:q075, 6:q175}
def test_eval_observables(self, observables: ListOrDict[OperatorBase]): """Tests evaluator of auxiliary operators for algorithms.""" ansatz = EfficientSU2(2) parameters = np.array( [ 1.2, 4.2, 1.4, 2.0, 1.2, 4.2, 1.4, 2.0, 1.2, 4.2, 1.4, 2.0, 1.2, 4.2, 1.4, 2.0 ], dtype=float, ) bound_ansatz = ansatz.bind_parameters(parameters) expected_result = self.get_exact_expectation(bound_ansatz, observables) for backend_name in self.backend_names: shots = 4096 if backend_name == "qasm_simulator" else 1 decimal = (1 if backend_name == "qasm_simulator" else 6 ) # to accommodate for qasm being imperfect with self.subTest(msg=f"Test {backend_name} backend."): backend = BasicAer.get_backend(backend_name) quantum_instance = QuantumInstance( backend=backend, shots=shots, seed_simulator=self.seed, seed_transpiler=self.seed, ) expectation = ExpectationFactory.build( operator=self.h2_op, backend=quantum_instance, ) with self.subTest(msg="Test QuantumCircuit."): self._run_test( expected_result, bound_ansatz, decimal, expectation, observables, quantum_instance, ) with self.subTest(msg="Test Statevector."): statevector = Statevector(bound_ansatz) self._run_test( expected_result, statevector, decimal, expectation, observables, quantum_instance, )
def create_base_circuit(num_qubits): cr = ClassicalRegister(num_qubits, "c0") qr = QuantumRegister(num_qubits, "q0") base_circuit = QuantumCircuit(qr, cr) base_circuit.initialize( Statevector.from_label('1' * num_qubits).data, range(num_qubits)) #[base_circuit.initialize([0, 1], i) for i in range(num_qubits)]; return base_circuit
def evaluate_classically(self, solution: Union[np.array, QuantumCircuit]) -> float: """Evaluates the given observable on the solution to the linear system. Args: solution: The solution to the system as a numpy array or the circuit that prepares it. Returns: The value of the observable. """ # Check if it is QuantumCircuits and get the array from them if isinstance(solution, QuantumCircuit): solution = Statevector(solution).data return np.abs(np.mean(solution))
def getProbabilityOutput(circuit): #Calculate the measurement probability probabilities = Statevector.from_instruction(circuit).probabilities_dict() probabilityOutput = "Probability distribution: " #Format according to [q0, q1, q2], probabaility; ... for the qbits q0, q1 and q2 for probability in probabilities.items(): x, y = eval(probability.__str__()) probabilityOutput += "[" for c in str(x): probabilityOutput += c + ", " probabilityOutput = probabilityOutput[0:len(probabilityOutput) - 2] probabilityOutput += "] , " + str(round(y, 3)) + "; " return probabilityOutput
def test_construct_eigenstate_from_optpoint(self): """Test constructing the eigenstate from the optimal point, if the default ansatz is used.""" # use Hamiltonian yielding more than 11 parameters in the default ansatz hamiltonian = Z ^ Z ^ Z optimizer = SPSA(maxiter=1, learning_rate=0.01, perturbation=0.01) quantum_instance = QuantumInstance( backend=BasicAer.get_backend("statevector_simulator"), basis_gates=["u3", "cx"]) vqe = VQE(optimizer=optimizer, quantum_instance=quantum_instance) result = vqe.compute_minimum_eigenvalue(hamiltonian) optimal_circuit = vqe.ansatz.bind_parameters(result.optimal_point) self.assertTrue(Statevector(result.eigenstate).equiv(optimal_circuit))
def test_control_removal(self): """Should replace CX by X and CZ by Z.""" circuit = QuantumCircuit(2) circuit.x(0) circuit.cx(0, 1) expected = QuantumCircuit(2) expected.x(0) expected.x(1) stv = Statevector.from_label("0" * circuit.num_qubits) self.assertEqual(stv @ circuit, stv @ expected) pass_ = HoareOptimizer(size=5) result = pass_.run(circuit_to_dag(circuit)) self.assertEqual(result, circuit_to_dag(expected)) circuit = QuantumCircuit(2) circuit.h(0) circuit.x(1) circuit.cz(0, 1) circuit.h(0) expected = QuantumCircuit(2) expected.h(0) expected.x(1) expected.z(0) expected.h(0) stv = Statevector.from_label("0" * circuit.num_qubits) self.assertEqual(stv @ circuit, stv @ expected) pass_ = HoareOptimizer(size=5) result = pass_.run(circuit_to_dag(circuit)) self.assertEqual(result, circuit_to_dag(expected))
def test_coder_operators(self): """Test runtime encoder and decoder for operators.""" x = Parameter("x") y = x + 1 qc = QuantumCircuit(1) qc.h(0) coeffs = np.array([1, 2, 3, 4, 5, 6]) table = PauliTable.from_labels( ["III", "IXI", "IYY", "YIZ", "XYZ", "III"]) op = (2.0 * I ^ I) z2_symmetries = Z2Symmetries( [Pauli("IIZI"), Pauli("ZIII")], [Pauli("IIXI"), Pauli("XIII")], [1, 3], [-1, 1]) isqrt2 = 1 / np.sqrt(2) sparse = scipy.sparse.csr_matrix([[0, isqrt2, 0, isqrt2]]) subtests = ( PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[2]), coeff=3), PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[1]), coeff=y), PauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[1 + 2j]), coeff=3 - 2j), PauliSumOp.from_list([("II", -1.052373245772859), ("IZ", 0.39793742484318045)]), PauliSumOp(SparsePauliOp(table, coeffs), coeff=10), MatrixOp(primitive=np.array([[0, -1j], [1j, 0]]), coeff=x), PauliOp(primitive=Pauli("Y"), coeff=x), CircuitOp(qc, coeff=x), EvolvedOp(op, coeff=x), TaperedPauliSumOp(SparsePauliOp(Pauli("XYZX"), coeffs=[2]), z2_symmetries), StateFn(qc, coeff=x), CircuitStateFn(qc, is_measurement=True), DictStateFn("1" * 3, is_measurement=True), VectorStateFn(np.ones(2**3, dtype=complex)), OperatorStateFn(CircuitOp(QuantumCircuit(1))), SparseVectorStateFn(sparse), Statevector([1, 0]), CVaRMeasurement(Z, 0.2), ComposedOp([(X ^ Y ^ Z), (Z ^ X ^ Y ^ Z).to_matrix_op()]), SummedOp([X ^ X * 2, Y ^ Y], 2), TensoredOp([(X ^ Y), (Z ^ I)]), (Z ^ Z) ^ (I ^ 2), ) for op in subtests: with self.subTest(op=op): encoded = json.dumps(op, cls=RuntimeEncoder) self.assertIsInstance(encoded, str) decoded = json.loads(encoded, cls=RuntimeDecoder) self.assertEqual(op, decoded)
def solve( self, matrix: Union[np.ndarray, QuantumCircuit], vector: Union[np.ndarray, QuantumCircuit], observable: Optional[Union[LinearSystemObservable, BaseOperator, List[BaseOperator]]] = None, observable_circuit: Optional[Union[QuantumCircuit, List[QuantumCircuit]]] = None, post_processing: Optional[Callable[[Union[float, List[float]]], Union[float, List[float]]]] = None, ) -> LinearSolverResult: """Solve classically the linear system and compute the observable(s) Args: matrix: The matrix specifying the system, i.e. A in Ax=b. vector: The vector specifying the right hand side of the equation in Ax=b. observable: Optional information to be extracted from the solution. Default is the probability of success of the algorithm. observable_circuit: Optional circuit to be applied to the solution to extract information. Default is ``None``. post_processing: Optional function to compute the value of the observable. Default is the raw value of measuring the observable. Returns: The result of the linear system. """ # Check if either matrix or vector are QuantumCircuits and get the array from them if isinstance(vector, QuantumCircuit): vector = Statevector(vector).data if isinstance(matrix, QuantumCircuit): if hasattr(matrix, "matrix"): matrix = matrix.matrix else: matrix = Operator(matrix).data solution_vector = np.linalg.solve(matrix, vector) solution = LinearSolverResult() solution.state = solution_vector if observable is not None: if isinstance(observable, list): solution.observable = [] for obs in observable: solution.observable.append( obs.evaluate_classically(solution_vector)) else: solution.observable = observable.evaluate_classically( solution_vector) solution.euclidean_norm = np.linalg.norm(solution_vector) return solution
def test_endian(self, little_endian): """Test the outcome for different endianness.""" qform = QuadraticForm(2, linear=[0, 1], little_endian=little_endian) circuit = QuantumCircuit(4) circuit.x(1) circuit.compose(qform, inplace=True) # the result is x_0 linear_0 + x_1 linear_1 = 1 = '0b01' result = "01" # the state is encoded as |q(x)>|x>, |x> = |x_1 x_0> = |10> index = (result if little_endian else result[::-1]) + "10" ref = np.zeros(2 ** 4, dtype=complex) ref[int(index, 2)] = 1 self.assertTrue(Statevector.from_instruction(circuit).equiv(ref))
def test_fitter_string_input(self): q3 = QuantumRegister(3) bell = QuantumCircuit(q3) bell.h(q3[0]) bell.cx(q3[0], q3[1]) bell.cx(q3[1], q3[2]) qst = tomo.state_tomography_circuits(bell, q3) qst_names = [circ.name for circ in qst] job = qiskit.execute(qst, Aer.get_backend('qasm_simulator'), shots=5000) tomo_fit = tomo.StateTomographyFitter(job.result(), qst_names) rho = tomo_fit.fit(method=self.method) psi = Statevector.from_instruction(bell) F_bell = state_fidelity(psi, rho, validate=False) self.assertAlmostEqual(F_bell, 1, places=1)