def grover(q, constant_1, constant_2, rot, h, grover_it, nshots=100): """Run the full Grover's search algorithm to find a preimage of a hash function. Args: q (int): number of qubits of a site in the permutation matrix. constant_1 (int): constant that defines the hash construction. constant_2 (int): constant that defines the hash construction. rot (list): characterization of the rotation part of the algorithm. h (str): hash value that one wants to find preimages of. grover_it (int): number of Grover steps to be performed. Returns: result (dict): counts of the output generated by the algorithm """ A, B, C, D, x, ancilla, circuit, qubits = create_qc(q) c1, c2, c3, c4 = initial_step(q, constant_1, constant_2, rot) c = [] c.append(c1) c.append(c2) c.append(c3) c.append(c4) circuit.add(start_grover(A + B, ancilla)) for i in range(grover_it): circuit = grover_step(q, c, circuit, A, B, C, D, x, ancilla, h, rot) circuit.add(gates.M(*(A + B), register_name='preimages')) result = circuit(nshots=nshots) return result.frequencies(binary=True)
def test_thermal_relaxation_channel_repeated(backend): initial_state = random_state(5) c = Circuit(5) c.add(gates.ThermalRelaxationChannel(4, t1=1.0, t2=0.6, time=0.8, excited_population=0.8, seed=123)) final_state = c(K.cast(np.copy(initial_state)), nshots=30) pz, p0, p1 = c.queue[0].calculate_probabilities(1.0, 0.6, 0.8, 0.8) np.random.seed(123) target_state = [] collapse = gates.M(4, collapse=True) collapse.nqubits = 5 zgate, xgate = gates.Z(4), gates.X(4) for _ in range(30): state = K.cast(np.copy(initial_state)) if np.random.random() < pz: state = zgate(state) if np.random.random() < p0: state = K.state_vector_collapse(collapse, state, [0]) if np.random.random() < p1: state = K.state_vector_collapse(collapse, state, [0]) state = xgate(state) target_state.append(K.copy(state)) target_state = K.stack(target_state) K.assert_allclose(final_state, target_state)
def test_circuit_with_unmeasured_qubits(backend, accelerators): original_backend = qibo.get_backend() qibo.set_backend(backend) c = models.Circuit(5, accelerators) c.add(gates.X(4)) c.add(gates.X(2)) c.add(gates.M(0, 2)) c.add(gates.X(3)) c.add(gates.M(1, 4)) result = c(nshots=100) target_binary_samples = np.zeros((100, 4)) target_binary_samples[:, 1] = 1 target_binary_samples[:, 3] = 1 assert_result(result, 5 * np.ones(100), target_binary_samples, {5: 100}, {"0101": 100}) qibo.set_backend(original_backend)
def test_copy_measurements(accelerators): """Check that ``circuit.copy()`` properly copies measurements.""" c1 = models.Circuit(6, accelerators) c1.add([gates.X(0), gates.X(1), gates.X(3)]) c1.add(gates.M(5, 1, 3, register_name="a")) c1.add(gates.M(2, 0, register_name="b")) c2 = c1.copy() r1 = c1(nshots=100) r2 = c2(nshots=100) np.testing.assert_allclose(r1.samples().numpy(), r2.samples().numpy()) rg1 = r1.frequencies(registers=True) rg2 = r2.frequencies(registers=True) assert rg1.keys() == rg2.keys() for k in rg1.keys(): assert rg1[k] == rg2[k]
def test_multiple_measurement_gates_circuit(): """Check multiple gates with multiple qubits each in the same circuit.""" c = models.Circuit(4) c.add(gates.X(1)) c.add(gates.X(2)) c.add(gates.M(0, 1)) c.add(gates.M(2)) c.add(gates.X(3)) result = c(nshots=100) target_binary_samples = np.ones((100, 3)) target_binary_samples[:, 0] = 0 assert_results(result, decimal_samples=3 * np.ones((100, )), binary_samples=target_binary_samples, decimal_frequencies={3: 100}, binary_frequencies={"011": 100})
def test_measurement_qubit_order_simple(backend, registers): original_backend = qibo.get_backend() qibo.set_backend(backend) c = models.Circuit(2) c.add(gates.X(0)) if registers: c.add(gates.M(1, 0)) else: c.add(gates.M(1)) c.add(gates.M(0)) result = c(nshots=100) target_binary_samples = np.zeros((100, 2)) target_binary_samples[:, 1] = 1 assert_result(result, np.ones(100), target_binary_samples, {1: 100}, {"01": 100}) qibo.set_backend(original_backend)
def test_multiple_qubit_measurement_gate(backend): state = np.zeros(4) state[2] = 1 result = gates.M(0, 1)(K.cast(state), nshots=100) target_binary_samples = np.zeros((100, 2)) target_binary_samples[:, 0] = 1 assert_result(result, 2 * np.ones((100, )), target_binary_samples, {2: 100}, {"10": 100})
def test_gate_after_measurement_error(backend, accelerators): c = models.Circuit(4, accelerators) c.add(gates.X(0)) c.add(gates.M(0)) c.add(gates.X(1)) # TODO: Change this to NotImplementedError with pytest.raises(ValueError): c.add(gates.H(0))
def test_measurement_circuit(backend, accelerators): c = models.Circuit(4, accelerators) c.add(gates.X(0)) c.add(gates.M(0)) result = c(nshots=100) assert_result(result, np.ones((100,)), np.ones((100, 1)), {1: 100}, {"1": 100})
def test_measurement_collapse_errors(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) gate = gates.M(0, 1, collapse=True) state = np.ones(4) / 4 with pytest.raises(ValueError): state = gate(state, nshots=100) qibo.set_backend(original_backend)
def test_circuit_addition_with_measurements_in_both_circuits( backend, accelerators): original_backend = qibo.get_backend() qibo.set_backend(backend) c1 = models.Circuit(4, accelerators) c1.add(gates.H(0)) c1.add(gates.H(1)) c1.add(gates.M(1, register_name="a")) c2 = models.Circuit(4, accelerators) c2.add(gates.X(0)) c2.add(gates.M(0, register_name="b")) c = c1 + c2 assert len(c.measurement_gate.target_qubits) == 2 assert c.measurement_tuples == {"a": (1, ), "b": (0, )} qibo.set_backend(original_backend)
def test_circuit_with_unmeasured_qubits(accelerators): """Check that unmeasured qubits are not taken into account.""" c = models.Circuit(5, accelerators) c.add(gates.X(4)) c.add(gates.X(2)) c.add(gates.M(0, 2)) c.add(gates.X(3)) c.add(gates.M(1, 4)) result = c(nshots=100) target_binary_samples = np.zeros((100, 4)) target_binary_samples[:, 1] = 1 target_binary_samples[:, 3] = 1 assert_results(result, decimal_samples=5 * np.ones((100, )), binary_samples=target_binary_samples, decimal_frequencies={5: 100}, binary_frequencies={"0101": 100})
def test_final_state(accelerators): """Check that final state is logged correctly when using measurements.""" c = models.Circuit(4, accelerators) c.add(gates.X(1)) c.add(gates.X(2)) c.add(gates.M(0, 1)) c.add(gates.M(2)) c.add(gates.X(3)) result = c(nshots=100) logged_final_state = c.final_state.numpy() c = models.Circuit(4, accelerators) c.add(gates.X(1)) c.add(gates.X(2)) c.add(gates.X(3)) target_state = c().numpy() np.testing.assert_allclose(logged_final_state, target_state)
def test_gate_after_measurement_error(accelerators): """Check that reusing measured qubits is not allowed.""" c = models.Circuit(2, accelerators) c.add(gates.X(0)) c.add(gates.M(0)) c.add(gates.X(1)) # TODO: Change this to NotImplementedError with pytest.raises(ValueError): c.add(gates.H(0))
def test_gate_after_measurement_with_addition_error(backend, accelerators): original_backend = qibo.get_backend() qibo.set_backend(backend) c = models.Circuit(4, accelerators) c.add(gates.H(0)) c.add(gates.M(1)) # Try to add gate to qubit that is already measured c2 = models.Circuit(4, accelerators) c2.add(gates.H(1)) with pytest.raises(ValueError): c += c2 # Try to add measurement to qubit that is already measured c2 = models.Circuit(4, accelerators) c2.add(gates.M(1, register_name="a")) with pytest.raises(ValueError): c += c2 qibo.set_backend(original_backend)
def test_state_probabilities_errors(): from qibo import gates state = states.VectorState.zero_state(3) mgate = gates.M(0) qubits = [0] with pytest.raises(ValueError): probs = state.probabilities() with pytest.raises(ValueError): probs = state.probabilities(qubits, mgate)
def test_measurement_gate(backend, n, nshots): original_backend = qibo.get_backend() qibo.set_backend(backend) state = np.zeros(4) state[-n] = 1 result = gates.M(0)(state, nshots=nshots) assert_result(result, n * np.ones(nshots), n * np.ones((nshots, 1)), {n: nshots}, {str(n): nshots}) qibo.set_backend(original_backend)
def test_state_probabilities(backend, state_type, use_gate): state = getattr(states, state_type).plus_state(4) if use_gate: from qibo import gates mgate = gates.M(0, 1) probs = state.probabilities(measurement_gate=mgate) else: probs = state.probabilities(qubits=[0, 1]) target_probs = np.ones((2, 2)) / 4 K.assert_allclose(probs, target_probs)
def test_measurement_result_parameters_multiple_qubits(backend): initial_state = random_state(4) K.set_seed(123) c = models.Circuit(4) output = c.add(gates.M(0, 1, 2, collapse=True)) c.add(gates.RY(1, theta=np.pi * output[0] / 5)) c.add(gates.RX(3, theta=np.pi * output[2] / 3)) result = c(initial_state=np.copy(initial_state)) K.set_seed(123) collapse = gates.M(0, 1, 2, collapse=True) target_state = collapse(K.cast(np.copy(initial_state))) # not including in coverage because outcomes are probabilistic and may # not occur for the CI run if int(collapse.result.outcome(0)): # pragma: no cover target_state = gates.RY(1, theta=np.pi / 5)(target_state) if int(collapse.result.outcome(2)): # pragma: no cover target_state = gates.RX(3, theta=np.pi / 3)(target_state) K.assert_allclose(result, target_state)
def test_measurement_result_parameters_random(backend, accelerators): test_device = K.cpu_devices[0] if accelerators else K.default_device initial_state = random_state(4) set_device_seed(123, accelerators) c = models.Circuit(4, accelerators) output = c.add(gates.M(1, collapse=True)) c.add(gates.RY(0, theta=np.pi * output / 5)) c.add(gates.RX(2, theta=np.pi * output / 4)) result = c(initial_state=np.copy(initial_state)) assert len(output.frequencies()) == 1 set_device_seed(123, accelerators) with K.device(test_device): collapse = gates.M(1, collapse=True) target_state = collapse(K.cast(np.copy(initial_state))) if int(collapse.result.outcome()): target_state = gates.RY(0, theta=np.pi / 5)(target_state) target_state = gates.RX(2, theta=np.pi / 4)(target_state) K.assert_allclose(result, target_state)
def test_measurement_compiled_circuit(backend): from qibo import K if K.is_custom: # use native gates because custom gates do not support compilation pytest.skip("Custom backend does not support compilation.") c = models.Circuit(2) c.add(gates.X(0)) c.add(gates.M(0)) c.add(gates.M(1)) c.compile() result = c(nshots=100) target_binary_samples = np.zeros((100, 2)) target_binary_samples[:, 0] = 1 assert_result(result, 2 * np.ones((100, )), target_binary_samples, {2: 100}, {"10": 100}) target_state = np.zeros_like(c.final_state) target_state[2] = 1 K.assert_allclose(c.final_state, target_state)
def test_post_measurement_bitflips_on_circuit(backend, accelerators, i, probs): """Check bitflip errors on circuit measurements.""" K.set_seed(123) c = models.Circuit(5, accelerators=accelerators) c.add([gates.X(0), gates.X(2), gates.X(3)]) c.add(gates.M(0, 1, p0={0: probs[0], 1: probs[1]})) c.add(gates.M(3, p0=probs[2])) result = c(nshots=30).frequencies(binary=False) if K.name == "qibojit" and K.op.get_backend() == "cupy": # pragma: no cover # cupy is not tested by CI! targets = [{5: 30}, {5: 12, 7: 7, 6: 5, 4: 3, 1: 2, 2: 1}, {2: 10, 6: 5, 5: 4, 0: 3, 7: 3, 1: 2, 3: 2, 4: 1}] elif K.name == "numpy" or K.name == "qibojit": targets = [{5: 30}, {5: 18, 4: 5, 7: 4, 1: 2, 6: 1}, {4: 8, 2: 6, 5: 5, 1: 3, 3: 3, 6: 2, 7: 2, 0: 1}] else: targets = [{5: 30}, {5: 16, 7: 10, 6: 2, 3: 1, 4: 1}, {3: 6, 5: 6, 7: 5, 2: 4, 4: 3, 0: 2, 1: 2, 6: 2}] assert result == targets[i]
def test_measurement_gate2(): """Check that measurement gate works when called on the state |11>.""" state = np.zeros(4) state[-1] = 1 result = gates.M(1)(state, nshots=100) assert_results(result, decimal_samples=np.ones((100, )), binary_samples=np.ones((100, 1)), decimal_frequencies={1: 100}, binary_frequencies={"1": 100})
def test_measurement_circuit(backend, accelerators): original_backend = qibo.get_backend() qibo.set_backend(backend) c = models.Circuit(4, accelerators) c.add(gates.X(0)) c.add(gates.M(0)) result = c(nshots=100) assert_result(result, np.ones((100, )), np.ones((100, 1)), {1: 100}, {"1": 100}) qibo.set_backend(original_backend)
def test_circuit_copy_with_measurements(backend, accelerators): original_backend = qibo.get_backend() qibo.set_backend(backend) c1 = models.Circuit(6, accelerators) c1.add([gates.X(0), gates.X(1), gates.X(3)]) c1.add(gates.M(5, 1, 3, register_name="a")) c1.add(gates.M(2, 0, register_name="b")) c2 = c1.copy() r1 = c1(nshots=100) r2 = c2(nshots=100) np.testing.assert_allclose(r1.samples(), r2.samples()) rg1 = r1.frequencies(registers=True) rg2 = r2.frequencies(registers=True) assert rg1.keys() == rg2.keys() for k in rg1.keys(): assert rg1[k] == rg2[k] qibo.set_backend(original_backend)
def measure_payoff(q, ancilla): """Measurement gates needed to measure the expected payoff and perform post-selection Args: q (list): quantum register encoding the asset's price in the unary bases. ancilla (int): qubit that encodes the payoff of the options. Returns: generator that yields the measurement gates to recover the expected payoff. """ yield gates.M(*(q + [ancilla]), register_name='payoff')
def test_pauli_error(backend, density_matrix, nshots): pauli = PauliError(0, 0.2, 0.3) noise = NoiseModel() noise.add(pauli, gates.X, 1) noise.add(pauli, gates.CNOT) noise.add(pauli, gates.Z, (0,1)) circuit = Circuit(3, density_matrix=density_matrix) circuit.add(gates.CNOT(0,1)) circuit.add(gates.Z(1)) circuit.add(gates.X(1)) circuit.add(gates.X(2)) circuit.add(gates.Z(2)) circuit.add(gates.M(0, 1, 2)) target_circuit = Circuit(3, density_matrix=density_matrix) target_circuit.add(gates.CNOT(0,1)) target_circuit.add(gates.PauliNoiseChannel(0, 0, 0.2, 0.3)) target_circuit.add(gates.PauliNoiseChannel(1, 0, 0.2, 0.3)) target_circuit.add(gates.Z(1)) target_circuit.add(gates.PauliNoiseChannel(1, 0, 0.2, 0.3)) target_circuit.add(gates.X(1)) target_circuit.add(gates.PauliNoiseChannel(1, 0, 0.2, 0.3)) target_circuit.add(gates.X(2)) target_circuit.add(gates.Z(2)) target_circuit.add(gates.M(0, 1, 2)) initial_psi = random_density_matrix(3) if density_matrix else random_state(3) np.random.seed(123) K.set_seed(123) final_state = noise.apply(circuit)(initial_state=np.copy(initial_psi), nshots=nshots) final_state_samples = final_state.samples() if nshots else None np.random.seed(123) K.set_seed(123) target_final_state = target_circuit(initial_state=np.copy(initial_psi), nshots=nshots) target_final_state_samples = target_final_state.samples() if nshots else None if nshots is None: K.assert_allclose(final_state, target_final_state) else: K.assert_allclose(final_state_samples, target_final_state_samples)
def test_construct_unitary_errors(backend): qibo.set_backend(backend) gate = gates.M(0) with pytest.raises(ValueError): matrix = gate.unitary pairs = list((i, i + 1) for i in range(0, 5, 2)) theta = 2 * np.pi * np.random.random(6) gate = gates.VariationalLayer(range(6), pairs, gates.RY, gates.CZ, theta) with pytest.raises(ValueError): matrix = gate.unitary
def test_measurement_gate_errors(backend): gate = gates.M(0) # attempting to use `controlled_by` with pytest.raises(NotImplementedError): gate.controlled_by(1) # attempting to construct unitary with pytest.raises(ValueError): matrix = gate.matrix # calling on bad state with pytest.raises(TypeError): gate("test", 100)
def test_circuit_addition_with_measurements(backend): c = models.Circuit(2) c.add(gates.H(0)) c.add(gates.H(1)) meas_c = models.Circuit(2) c.add(gates.M(0, 1)) c += meas_c assert len(c.measurement_gate.target_qubits) == 2 assert c.measurement_tuples == {"register0": (0, 1)}