def test_sample(): q = cirq.NamedQubit('q') with pytest.raises(ValueError, match="no measurements"): cirq.sample(cirq.Circuit.from_ops(cirq.X(q))) # Unitary. results = cirq.sample(cirq.Circuit.from_ops(cirq.X(q), cirq.measure(q))) assert results.histogram(key=q) == collections.Counter({1: 1}) # Intermediate measurements. results = cirq.sample( cirq.Circuit.from_ops( cirq.measure(q, key='drop'), cirq.X(q), cirq.measure(q), )) assert results.histogram(key='drop') == collections.Counter({0: 1}) assert results.histogram(key=q) == collections.Counter({1: 1}) # Overdamped everywhere. results = cirq.sample(cirq.Circuit.from_ops( cirq.measure(q, key='drop'), cirq.X(q), cirq.measure(q), ), noise=cirq.ConstantQubitNoiseModel( cirq.amplitude_damp(1))) assert results.histogram(key='drop') == collections.Counter({0: 1}) assert results.histogram(key=q) == collections.Counter({0: 1})
def test_sample(): q = cirq.NamedQubit('q') # Unitary. results = cirq.sample(cirq.Circuit.from_ops(cirq.X(q), cirq.measure(q))) assert results.histogram(key=q) == collections.Counter({1: 1}) # Intermediate measurements. results = cirq.sample(cirq.Circuit.from_ops( cirq.measure(q, key='drop'), cirq.X(q), cirq.measure(q), )) assert results.histogram(key='drop') == collections.Counter({0: 1}) assert results.histogram(key=q) == collections.Counter({1: 1})
def run_estimate(unknown_gate, qnum, repetitions): """Construct the following phase estimator circuit and execute simulations. --------- ---H---------------------@------| |---M--- [m4]:lowest bit | | | ---H---------------@-----+------| |---M--- [m3] | | | QFT_inv | ---H---------@-----+-----+------| |---M--- [m2] | | | | | ---H---@-----+-----+-----+------| |---M--- [m1]:highest bit | | | | --------- -------U-----U^2---U^4---U^8---------------------- The measurement results M=[m1, m2,...] are translated to the estimated phase with the following formula: phi = m1*(1/2) + m2*(1/2)^2 + m3*(1/2)^3 + ... """ ancilla = cirq.LineQubit(-1) qubits = cirq.LineQubit.range(qnum) oracle_raised_to_power = [ unknown_gate.on(ancilla).controlled_by(qubits[i])**(2**i) for i in range(qnum) ] circuit = cirq.Circuit( cirq.H.on_each(*qubits), oracle_raised_to_power, cirq.qft(*qubits, without_reverse=True)**-1, cirq.measure(*qubits, key='phase'), ) return cirq.sample(circuit, repetitions=repetitions)
def experiment(qnum, repetitions=100): """Execute the phase estimator circuit with multiple settings and show results. """ def example_gate(phi): """An example unitary 1-qubit gate U with an eigen vector |0> and an eigen value exp(2*Pi*i*phi) """ gate = cirq.MatrixGate( matrix=np.array([[np.exp(np.pi * 2.0j * phi), 0], [0, 1]])) return gate print(f'Testing with {qnum} qubits.') errors = [] ancilla = cirq.LineQubit(qnum) qubits = cirq.LineQubit.range(qnum) oracle_raised_to_power = [ example_gate(sympy.Symbol('target')).on(ancilla).controlled_by( qubits[i])**(2**i) for i in range(qnum) ] circuit = cirq.Circuit( cirq.H.on_each(*qubits), oracle_raised_to_power, cirq.decompose(cirq.QFT(*qubits, without_reverse=True)**-1), cirq.measure(*qubits, key='phase')) for target in np.arange(0, 1, 0.1): result = cirq.sample(circuit, repetitions=repetitions) # return cirq.KnowledgeCompilationSimulator(circuit).run(circuit, repetitions=repetitions) mode = result.data['phase'].mode()[0] guess = mode / 2**qnum print(f'target={target:0.4f}, ' f'estimate={guess:0.4f}={mode}/{2**qnum}') errors.append((target - guess)**2) rms = np.sqrt(sum(errors) / len(errors)) print(f'RMS Error: {rms:0.4f}\n')
def test_repetitions(repetitions): a = cirq.LineQubit(0) c = cirq.Circuit(cirq.H(a), cirq.measure(a, key='m')) r = cirq.sample(c, repetitions=repetitions) samples = r.data['m'].to_numpy() assert samples.shape == (repetitions, ) assert np.issubdtype(samples.dtype, np.integer)
def estimate_probs(circuit, theta, n_shots): ''' Estimate all probabilities of the PQCs distribution. Args: circuit (list): instance of the cirq.circuits.circuit.Circuit class theta (float): parameters of the circuit. n_shots (int): number of shots. Returns: 1darray: output probabilites of the circuit. ''' n_qubits = len(circuit.all_qubits()) # Creating parameter resolve dict by adding state and theta. try: theta_mapping = [('theta_' + str(i), theta[i]) for i in range(len(theta))] except IndexError as error: print("Could not resolve theta symbol, array of wrong size.") resolve_dict = dict(theta_mapping) resolver = cirq.ParamResolver(resolve_dict) resolved_circuit = cirq.resolve_parameters(circuit, resolver) # Run the circuit. if n_shots == 0: final_state = resolved_circuit.final_state_vector() probs = np.array( [np.abs(final_state[i])**2 for i in range(len(final_state))]) else: results = cirq.sample(resolved_circuit, repetitions=n_shots) frequencies = results.histogram(key='m') probs = np.zeros(2**n_qubits) for key, value in frequencies.items(): probs[key] = value / n_shots return probs
def test_sample_seed_unitary(): q = cirq.NamedQubit('q') circuit = cirq.Circuit(cirq.X(q)**0.2, cirq.measure(q)) result = cirq.sample(circuit, repetitions=10, seed=1234) measurements = result.measurements['q'] assert np.all(measurements == [[False], [False], [False], [False], [False], [False], [False], [False], [True], [False]])
def test_sample_seed_non_unitary(): q = cirq.NamedQubit('q') circuit = cirq.Circuit(cirq.depolarize(0.5).on(q), cirq.measure(q)) result = cirq.sample(circuit, repetitions=10, seed=1234) assert np.all( result.measurements['q'] == [[False], [False], [False], [True], [True], [False], [False], [True], [True], [True]])
def test_sample_seed(): q = cirq.NamedQubit('q') circuit = cirq.Circuit.from_ops(cirq.X(q)**0.5, cirq.measure(q)) result = cirq.sample(circuit, repetitions=10, seed=1234) assert np.all( result.measurements['q'] == [[False], [True], [False], [True], [True], [False], [False], [True], [True], [True]])
def quantum_order_finder(x: int, n: int) -> Optional[int]: """Computes smallest positive r such that x**r mod n == 1. Args: x: integer whose order is to be computed, must be greater than one and belong to the multiplicative group of integers modulo n (which consists of positive integers relatively prime to n), n: modulus of the multiplicative group. Returns: Smallest positive integer r such that x**r == 1 mod n or None if the algorithm failed. The algorithm fails when the result of the Quantum Phase Estimation is inaccurate, zero or a reducible fraction. Raises: ValueError: When x is 1 or not an element of the multiplicative group of integers modulo n. """ if x < 2 or n <= x or math.gcd(x, n) > 1: raise ValueError(f'Invalid x={x} for modulus n={n}.') circuit = make_order_finding_circuit(x, n) result = cirq.sample(circuit) eigenphase = read_eigenphase(result) f = fractions.Fraction.from_float(eigenphase).limit_denominator(n) if f.numerator == 0: return None # coverage: ignore r = f.denominator if x**r % n != 1: return None # coverage: ignore return r
def get_noisy_trial_result( r_c: cirq.circuits.circuit, r: cirq.study.resolver, max_iter: int, noise_model: 'cirq.NOISE_MODEL_LIKE' = None) -> cirq.TrialResult: return cirq.sample(program=r_c, noise=noise_model, param_resolver=r, repetitions=max_iter) # Probabilistic result
def test_get_state_histogram_multi_1(): qubits = cirq.LineQubit.range(4) c = cirq.Circuit( cirq.X.on_each(*qubits[1:]), cirq.measure(*qubits) # One multi-qubit measurement ) r = cirq.sample(c, repetitions=5) values_to_plot = state_histogram.get_state_histogram(r) expected_values = [0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0] np.testing.assert_equal(values_to_plot, expected_values)
def test_plot_state_histogram_multi_1(): pl.switch_backend('PDF') qubits = cirq.LineQubit.range(4) c = cirq.Circuit( cirq.X.on_each(*qubits[1:]), cirq.measure(*qubits), # One multi-qubit measurement ) r = cirq.sample(c, repetitions=5) values_plotted = visualize.plot_state_histogram(r) expected_values = [0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0] np.testing.assert_equal(values_plotted, expected_values)
def test_verify_unique_measurement_keys(): q = cirq.LineQubit.range(2) circuit = cirq.Circuit() circuit.append([ cirq.measure(q[0], key='a'), cirq.measure(q[1], key='a'), cirq.measure(q[0], key='b'), cirq.measure(q[1], key='b') ]) with pytest.raises(ValueError, match='Measurement key a,b repeated'): _ = cirq.sample(circuit)
def sample_noisy_bitstrings( circuit: cirq.Circuit, qubit_order: Sequence[cirq.Qid], depolarization: float, repetitions: int ) -> np.ndarray: assert 0 <= depolarization <= 1 dim = np.prod(circuit.qid_shape(), dtype=np.int64) n_incoherent = int(depolarization * repetitions) n_coherent = repetitions - n_incoherent incoherent_samples = np.random.randint(dim, size=n_incoherent) circuit_with_measurements = cirq.Circuit(circuit, cirq.measure(*qubit_order, key='m')) r = cirq.sample(circuit_with_measurements, repetitions=n_coherent) coherent_samples = r.data['m'].to_numpy() return np.concatenate((coherent_samples, incoherent_samples))
def test_sample_repeated_measurement_keys(): q = cirq.LineQubit.range(2) circuit = cirq.Circuit() circuit.append([ cirq.measure(q[0], key='a'), cirq.measure(q[1], key='a'), cirq.measure(q[0], key='b'), cirq.measure(q[1], key='b'), ]) result = cirq.sample(circuit) assert len(result.records['a']) == 1 assert len(result.records['b']) == 1 assert len(result.records['a'][0]) == 2 assert len(result.records['b'][0]) == 2
def test_plot_state_histogram_result(): qubits = cirq.LineQubit.range(4) c = cirq.Circuit( cirq.X.on_each(*qubits[1:]), cirq.measure(*qubits), # One multi-qubit measurement ) r = cirq.sample(c, repetitions=5) expected_values = [0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0] _, (ax1, ax2) = plt.subplots(1, 2) state_histogram.plot_state_histogram(r, ax1) state_histogram.plot_state_histogram(expected_values, ax2) for r1, r2 in zip(ax1.get_children(), ax2.get_children()): if isinstance(r1, mpl.patches.Rectangle) and isinstance(r2, mpl.patches.Rectangle): assert str(r1) == str(r2)
def noisy_circuit_demo(amplitude_damp): """Demonstrates a noisy circuit simulation. """ # q = cirq.NamedQubit('q') q = cirq.LineQubit(0) dm_circuit = cirq.Circuit(cirq.X(q), ) dm_result = cirq.DensityMatrixSimulator(noise=cirq.ConstantQubitNoiseModel( cirq.amplitude_damp(amplitude_damp))).simulate(program=dm_circuit) kc_circuit = cirq.Circuit(cirq.amplitude_damp(amplitude_damp)(q), ) kc_result = cirq.KnowledgeCompilationSimulator( kc_circuit, initial_state=1, intermediate=False).simulate(kc_circuit) print("dm_result.final_density_matrix") print(dm_result.final_density_matrix) print("kc_result.final_density_matrix") print(kc_result.final_density_matrix) np.testing.assert_almost_equal(dm_result.final_density_matrix, kc_result.final_density_matrix) dm_circuit.append(cirq.measure(q, key='after_not_gate')) kc_circuit.append(cirq.measure(q, key='after_not_gate')) dm_results = cirq.sample(program=dm_circuit, noise=cirq.ConstantQubitNoiseModel( cirq.amplitude_damp(amplitude_damp)), repetitions=10000) kc_simulator = cirq.KnowledgeCompilationSimulator(kc_circuit, initial_state=1, intermediate=False) kc_results = kc_simulator.run(kc_circuit, repetitions=10000) print( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ) print("ConstantQubitNoiseModel with amplitude damping of rate", cirq.amplitude_damp(amplitude_damp)) print( 'DENSITY_MATRIX_SIMULATOR: Sampling of qubit "q" after application of X gate:' ) print(dm_results.histogram(key='after_not_gate')) print( 'KNOWLEDGE_COMPILATION_SIMULATOR: Sampling of qubit "q" after application of X gate:' ) print(kc_results.histogram(key='after_not_gate')) print( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" )
def test_plot_state_histogram_collection(): qubits = cirq.LineQubit.range(4) c = cirq.Circuit( cirq.X.on_each(*qubits[1:]), cirq.measure(*qubits), # One multi-qubit measurement ) r = cirq.sample(c, repetitions=5) _, (ax1, ax2) = plt.subplots(1, 2) state_histogram.plot_state_histogram(r.histogram(key='0,1,2,3'), ax1) expected_values = [5] tick_label = ['7'] state_histogram.plot_state_histogram(expected_values, ax2, tick_label=tick_label, xlabel=None) for r1, r2 in zip(ax1.get_children(), ax2.get_children()): if isinstance(r1, mpl.patches.Rectangle) and isinstance(r2, mpl.patches.Rectangle): assert str(r1) == str(r2)
def sample_noisy_bitstrings(circuit: cirq.Circuit, qubit_order: Sequence[cirq.Qid], depolarization: float, repetitions: int) -> np.ndarray: assert 0 <= depolarization <= 1 dim = np.product(circuit.qid_shape()) n_incoherent = int(depolarization * repetitions) n_coherent = repetitions - n_incoherent incoherent_samples = np.random.randint(dim, size=n_incoherent) circuit_with_measurements = cirq.Circuit.from_ops( circuit, cirq.measure(*qubit_order, key='m')) # TODO(viathor): Remove conditional after #2114. if n_coherent > 0: r = cirq.sample(circuit_with_measurements, repetitions=n_coherent) coherent_samples = r.data['m'].to_numpy() return np.concatenate((coherent_samples, incoherent_samples)) return incoherent_samples
def noisy_circuit_demo(amplitude_damp): """Demonstrates a noisy circuit simulation. """ q = cirq.NamedQubit('q') circuit = cirq.Circuit.from_ops( cirq.measure(q, key='initial_state'), cirq.X(q), cirq.measure(q, key='after_not_gate'), ) results = cirq.sample(program=circuit, noise=cirq.ConstantQubitNoiseModel( cirq.amplitude_damp(amplitude_damp)), repetitions=100) print("ConstantQubitNoiseModel with amplitude damping of rate", cirq.amplitude_damp(amplitude_damp)) print('Sampling of initial state of qubit "q":') print(results.histogram(key='initial_state')) print('Sampling of qubit "q" after application of X gate:') print(results.histogram(key='after_not_gate'))
def do_sample(self, samples, circuit, *args, **kwargs) -> QubitWaveFunction: """ Helper function, sampling an individual circuit. Parameters ---------- samples: int: the number of samples of measurement to make. circuit: the circuit to sample. args kwargs Returns ------- QubitWaveFunction: the result of sampled measurement, as a tequila wavefunction. """ return self.convert_measurements(cirq.sample(program=circuit, param_resolver=self.resolver, repetitions=samples))
def quantum_order_finder(x: int, n: int) -> Optional[int]: """Computes smallest positive r such that x**r mod n == 1. Args: x: integer whose order is to be computed, must be greater than one and belong to the multiplicative group of integers modulo n (which consists of positive integers relatively prime to n), n: modulus of the multiplicative group. """ # Check that the integer x is a valid element of the multiplicative group # modulo n if x < 2 or n <= x or math.gcd(x, n) > 1: raise ValueError(f'Invalid x={x} for modulus n={n}.') # Create the order finding circuit circuit = make_order_finding_circuit(x, n) # Sample from the order finding circuit measurement = cirq.sample(circuit) # Return the processed measurement result return process_measurement(measurement, x, n)
def do_sample(self, samples, circuit, *args, **kwargs) -> QubitWaveFunction: return self.convert_measurements( cirq.sample(program=circuit, param_resolver=self.resolver, repetitions=samples))
# Two qubit registers qreg1 = cirq.LineQubit.range(2) qreg2 = cirq.LineQubit.range(2, 4) # Define the circuit circ = cirq.Circuit(cirq.ops.X.on(qreg1[0]), cirq.ops.X.on(qreg2[1]), Adder(input_register=qreg1, target_register=qreg2), cirq.measure_each(*qreg1), cirq.measure_each(*qreg2)) # Display it print("Circuit:\n") print(circ) # Print the measurement outcomes print("\n\nMeasurement outcomes:\n") print(cirq.sample(circ, repetitions=5).data) """Example of the unitary of an Adder operation.""" cirq.unitary(Adder(target_register=cirq.LineQubit.range(2), input_register=1)).astype(np.int32) """Defines the modular exponential operation used in Shor's algorithm.""" class ModularExp(cirq.ArithmeticOperation): """Quantum modular exponentiation. This class represents the unitary which multiplies base raised to exponent into the target modulo the given modulus. More precisely, it represents the unitary V which computes modular exponentiation x**e mod n: V|y⟩|e⟩ = |y * x**e mod n⟩ |e⟩ 0 <= y < n V|y⟩|e⟩ = |y⟩ |e⟩ n <= y