From 2457626a9879f95dc5327b3a6866ce86df174074 Mon Sep 17 00:00:00 2001 From: Animesh Sinha Date: Mon, 1 Jun 2020 12:58:59 +0530 Subject: [PATCH 1/8] Detecting multi-qubit in plot_state_histogram plot_state_histogram works with single qubit measurements, multi-qubit measurements are detected by string matching and a warning is raised. --- cirq/study/visualize.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cirq/study/visualize.py b/cirq/study/visualize.py index 65aaa0ab189..35c115f6568 100644 --- a/cirq/study/visualize.py +++ b/cirq/study/visualize.py @@ -17,6 +17,7 @@ import numpy as np from cirq.study import trial_result +import warnings def plot_state_histogram(result: trial_result.TrialResult) -> np.ndarray: @@ -40,7 +41,13 @@ def plot_state_histogram(result: trial_result.TrialResult) -> np.ndarray: import matplotlib.pyplot as plt num_qubits = len(result.measurements.keys()) - states = 2**num_qubits + + if all([',' not in key for key in result.measurements.keys()]): + warnings.warn('plot_state_histogram takes single Qubit measurements, ' + 'you have provided a multiple Qubit measurement. ' + 'Consider using measure_each instead of measure.') + + states = 2 ** num_qubits values = np.zeros(states) # measurements is a dict of {measurement gate key: From 5e3c4fc59e829c2f5e2847a36f59765236e2a84a Mon Sep 17 00:00:00 2001 From: Animesh Sinha Date: Mon, 1 Jun 2020 13:38:18 +0530 Subject: [PATCH 2/8] Formatting Changes Order of imports and spaces on a line, linter issues fixed. --- cirq/study/visualize.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cirq/study/visualize.py b/cirq/study/visualize.py index 35c115f6568..da54992d769 100644 --- a/cirq/study/visualize.py +++ b/cirq/study/visualize.py @@ -14,10 +14,11 @@ """Tool to visualize the results of a study.""" +import warnings + import numpy as np from cirq.study import trial_result -import warnings def plot_state_histogram(result: trial_result.TrialResult) -> np.ndarray: @@ -47,7 +48,7 @@ def plot_state_histogram(result: trial_result.TrialResult) -> np.ndarray: 'you have provided a multiple Qubit measurement. ' 'Consider using measure_each instead of measure.') - states = 2 ** num_qubits + states = 2**num_qubits values = np.zeros(states) # measurements is a dict of {measurement gate key: From 91dcde321a2c8562d1c70f8fe93f9ca530a49883 Mon Sep 17 00:00:00 2001 From: Animesh Sinha Date: Mon, 1 Jun 2020 14:55:42 +0530 Subject: [PATCH 3/8] Multi-qubit measurements supported H-stacking the different measurements to allow plot_state_histogram to support multi-qubit measurements intermixed with single-qubit. --- cirq/study/visualize.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/cirq/study/visualize.py b/cirq/study/visualize.py index da54992d769..9fcabc17d27 100644 --- a/cirq/study/visualize.py +++ b/cirq/study/visualize.py @@ -26,8 +26,6 @@ def plot_state_histogram(result: trial_result.TrialResult) -> np.ndarray: States is a bitstring representation of all the qubit states in a single result. - Currently this function assumes each measurement gate applies to only - a single qubit. Args: result: The trial results to plot. @@ -41,23 +39,18 @@ def plot_state_histogram(result: trial_result.TrialResult) -> np.ndarray: # This allows cirq to be usable without python3-tk. import matplotlib.pyplot as plt - num_qubits = len(result.measurements.keys()) - - if all([',' not in key for key in result.measurements.keys()]): - warnings.warn('plot_state_histogram takes single Qubit measurements, ' - 'you have provided a multiple Qubit measurement. ' - 'Consider using measure_each instead of measure.') + assert set([value.shape[0] for value in result.measurements.values()]), \ + 'Same number of measurement must be made on all qubits.' + num_qubits = sum([value.shape[1] for value in result.measurements.values()]) states = 2**num_qubits values = np.zeros(states) - # measurements is a dict of {measurement gate key: # array(repetitions, boolean result)} # Convert this to an array of repetitions, each with an array of booleans. # e.g. {q1: array([[True, True]]), q2: array([[False, False]])} # --> array([[True, False], [True, False]]) - measurement_by_result = np.array([ - v.transpose()[0] for k, v in result.measurements.items()]).transpose() + measurement_by_result = np.hstack(list(result.measurements.values())) for meas in measurement_by_result: # Convert each array of booleans to a string representation. From 11cb27f9ca28fb537199529c07d0f0acb95f4c95 Mon Sep 17 00:00:00 2001 From: Animesh Sinha Date: Mon, 1 Jun 2020 14:59:29 +0530 Subject: [PATCH 4/8] Removed unused import Removed import of warnings. --- cirq/study/visualize.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cirq/study/visualize.py b/cirq/study/visualize.py index 9fcabc17d27..9aa0dd9a7c8 100644 --- a/cirq/study/visualize.py +++ b/cirq/study/visualize.py @@ -14,8 +14,6 @@ """Tool to visualize the results of a study.""" -import warnings - import numpy as np from cirq.study import trial_result From c24471493c579b2d98b21962b4d32251b2090026 Mon Sep 17 00:00:00 2001 From: Animesh Sinha Date: Tue, 2 Jun 2020 17:19:46 +0530 Subject: [PATCH 5/8] Added Tests Removed a frivolous assertion and added tests for the plotting. --- cirq/study/visualize.py | 3 --- cirq/study/visualize_test.py | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/cirq/study/visualize.py b/cirq/study/visualize.py index 9aa0dd9a7c8..5cc94192988 100644 --- a/cirq/study/visualize.py +++ b/cirq/study/visualize.py @@ -37,10 +37,7 @@ def plot_state_histogram(result: trial_result.TrialResult) -> np.ndarray: # This allows cirq to be usable without python3-tk. import matplotlib.pyplot as plt - assert set([value.shape[0] for value in result.measurements.values()]), \ - 'Same number of measurement must be made on all qubits.' num_qubits = sum([value.shape[1] for value in result.measurements.values()]) - states = 2**num_qubits values = np.zeros(states) # measurements is a dict of {measurement gate key: diff --git a/cirq/study/visualize_test.py b/cirq/study/visualize_test.py index 8cd83e9caf9..b3882bf2edc 100644 --- a/cirq/study/visualize_test.py +++ b/cirq/study/visualize_test.py @@ -38,3 +38,40 @@ def test_plot_state_histogram(): expected_values = [0., 0., 0., 5.] np.testing.assert_equal(values_plotted, expected_values) + + +def test_plot_state_histogram_multi_1(): + qubits = cirq.LineQubit.range(3) + c1 = cirq.Circuit( + cirq.X.on_each(*qubits), + cirq.measure(*qubits), # One multi-qubit measurement + ) + r1 = cirq.sample(c1, repetitions=5) + values_plotted = visualize.plot_state_histogram(r1) + expected_values = [0, 0, 0, 0, 0, 0, 0, 5] + np.testing.assert_equal(values_plotted, expected_values) + + +def test_plot_state_histogram_multi_2(): + qubits = cirq.LineQubit.range(3) + c2 = cirq.Circuit( + cirq.X.on_each(*qubits), + cirq.measure_each(*qubits), # One multi-qubit measurement + ) + r2 = cirq.sample(c2, repetitions=5) + values_plotted = visualize.plot_state_histogram(r2) + expected_values = [0, 0, 0, 0, 0, 0, 0, 5] + np.testing.assert_equal(values_plotted, expected_values) + + +def test_plot_state_histogram_multi_3(): + qubits = cirq.LineQubit.range(3) + c3 = cirq.Circuit( + cirq.X.on_each(*qubits), + cirq.measure(*qubits[:2]), # One multi-qubit measurement + cirq.measure_each(*qubits[2:]), # One multi-qubit measurement + ) + r3 = cirq.sample(c3, repetitions=5) + values_plotted = visualize.plot_state_histogram(r3) + expected_values = [0, 0, 0, 0, 0, 0, 0, 5] + np.testing.assert_equal(values_plotted, expected_values) From 25996ba86a7dcfc5530bacd91fa81a594d594f3b Mon Sep 17 00:00:00 2001 From: Animesh Sinha Date: Wed, 3 Jun 2020 04:21:09 +0530 Subject: [PATCH 6/8] Bad Comments and Plots Suppressed plots to PDFs during testing, updated some copied comments. --- cirq/study/visualize_test.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cirq/study/visualize_test.py b/cirq/study/visualize_test.py index b3882bf2edc..7b573220c81 100644 --- a/cirq/study/visualize_test.py +++ b/cirq/study/visualize_test.py @@ -41,6 +41,7 @@ def test_plot_state_histogram(): def test_plot_state_histogram_multi_1(): + pl.switch_backend('PDF') qubits = cirq.LineQubit.range(3) c1 = cirq.Circuit( cirq.X.on_each(*qubits), @@ -53,10 +54,11 @@ def test_plot_state_histogram_multi_1(): def test_plot_state_histogram_multi_2(): + pl.switch_backend('PDF') qubits = cirq.LineQubit.range(3) c2 = cirq.Circuit( cirq.X.on_each(*qubits), - cirq.measure_each(*qubits), # One multi-qubit measurement + cirq.measure_each(*qubits), # Many single-qubit measurements ) r2 = cirq.sample(c2, repetitions=5) values_plotted = visualize.plot_state_histogram(r2) @@ -65,11 +67,12 @@ def test_plot_state_histogram_multi_2(): def test_plot_state_histogram_multi_3(): + pl.switch_backend('PDF') qubits = cirq.LineQubit.range(3) c3 = cirq.Circuit( cirq.X.on_each(*qubits), cirq.measure(*qubits[:2]), # One multi-qubit measurement - cirq.measure_each(*qubits[2:]), # One multi-qubit measurement + cirq.measure_each(*qubits[2:]), # One single-qubit measurement ) r3 = cirq.sample(c3, repetitions=5) values_plotted = visualize.plot_state_histogram(r3) From fe415aac6c04960c35e3d811131dd5c35de5771e Mon Sep 17 00:00:00 2001 From: Animesh Sinha Date: Mon, 8 Jun 2020 05:09:13 +0530 Subject: [PATCH 7/8] Endianness in tests Applying X on all but one of the qubits, also deleting a test. --- cirq/study/visualize_test.py | 37 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/cirq/study/visualize_test.py b/cirq/study/visualize_test.py index 7b573220c81..8b436d60203 100644 --- a/cirq/study/visualize_test.py +++ b/cirq/study/visualize_test.py @@ -42,39 +42,26 @@ def test_plot_state_histogram(): def test_plot_state_histogram_multi_1(): pl.switch_backend('PDF') - qubits = cirq.LineQubit.range(3) - c1 = cirq.Circuit( - cirq.X.on_each(*qubits), + qubits = cirq.LineQubit.range(4) + c = cirq.Circuit( + cirq.X.on_each(*qubits[1:]), cirq.measure(*qubits), # One multi-qubit measurement ) - r1 = cirq.sample(c1, repetitions=5) - values_plotted = visualize.plot_state_histogram(r1) - expected_values = [0, 0, 0, 0, 0, 0, 0, 5] + 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_plot_state_histogram_multi_2(): pl.switch_backend('PDF') - qubits = cirq.LineQubit.range(3) - c2 = cirq.Circuit( - cirq.X.on_each(*qubits), - cirq.measure_each(*qubits), # Many single-qubit measurements - ) - r2 = cirq.sample(c2, repetitions=5) - values_plotted = visualize.plot_state_histogram(r2) - expected_values = [0, 0, 0, 0, 0, 0, 0, 5] - np.testing.assert_equal(values_plotted, expected_values) - - -def test_plot_state_histogram_multi_3(): - pl.switch_backend('PDF') - qubits = cirq.LineQubit.range(3) - c3 = cirq.Circuit( - cirq.X.on_each(*qubits), + qubits = cirq.LineQubit.range(4) + c = cirq.Circuit( + cirq.X.on_each(*qubits[1:]), cirq.measure(*qubits[:2]), # One multi-qubit measurement cirq.measure_each(*qubits[2:]), # One single-qubit measurement ) - r3 = cirq.sample(c3, repetitions=5) - values_plotted = visualize.plot_state_histogram(r3) - expected_values = [0, 0, 0, 0, 0, 0, 0, 5] + 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) From c23595369e9a7ba708b914f6de3e661f6c84ae55 Mon Sep 17 00:00:00 2001 From: Animesh Sinha Date: Tue, 9 Jun 2020 12:37:25 +0530 Subject: [PATCH 8/8] Fixed comment Replaced single qubit measurement with multiple qubit. --- cirq/study/visualize_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cirq/study/visualize_test.py b/cirq/study/visualize_test.py index 8b436d60203..88f7920d4b9 100644 --- a/cirq/study/visualize_test.py +++ b/cirq/study/visualize_test.py @@ -59,7 +59,7 @@ def test_plot_state_histogram_multi_2(): c = cirq.Circuit( cirq.X.on_each(*qubits[1:]), cirq.measure(*qubits[:2]), # One multi-qubit measurement - cirq.measure_each(*qubits[2:]), # One single-qubit measurement + cirq.measure_each(*qubits[2:]), # Multiple single-qubit measurement ) r = cirq.sample(c, repetitions=5) values_plotted = visualize.plot_state_histogram(r)