Skip to content

Commit

Permalink
Merge pull request #167 from madcpf/board
Browse files Browse the repository at this point in the history
Add one function into QuantumWorld
  • Loading branch information
madcpf authored Nov 30, 2023
2 parents 6f1a18d + e7274bd commit abb7a0b
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
32 changes: 32 additions & 0 deletions unitary/alpha/quantum_world.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from unitary.alpha.quantum_object import QuantumObject
from unitary.alpha.sparse_vector_simulator import PostSelectOperation, SparseSimulator
from unitary.alpha.qudit_state_transform import qudit_to_qubit_unitary, num_bits
import numpy as np
import itertools


class QuantumWorld:
Expand Down Expand Up @@ -484,6 +486,36 @@ def get_histogram(
histogram[idx][cast(int, result[idx])] += 1
return histogram

def get_correlated_histogram(
self, objects: Optional[Sequence[QuantumObject]] = None, count: int = 100
) -> Dict[Tuple[int], int]:
"""Creates histogram of the whole quantum world (or `objects` if specified)
based on measurements (peeks) carried out. Comparing to get_histogram(),
this statistics contains entanglement information accross quantum objects.
Parameters:
objects: List of QuantumObjects
count: Number of measurements
Returns:
A dictionary, with the keys being tuples representing each possible state of
the whole quantum world (or, if `objects` is specified, the key is a tuple of
the results of each object in `objects` and in the order of `objects`), and
the values being the count of that state.
"""
if not objects:
objects = self.public_objects
peek_results = self.peek(objects=objects, convert_to_enum=False, count=count)
histogram = {}
for result in peek_results:
# Convert the list to tuple so that it could be the key of a dictionary.
key = tuple(result)
if key not in histogram:
histogram[key] = 1
else:
histogram[key] += 1
return histogram

def get_probabilities(
self, objects: Optional[Sequence[QuantumObject]] = None, count: int = 100
) -> List[Dict[int, float]]:
Expand Down
42 changes: 42 additions & 0 deletions unitary/alpha/quantum_world_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -656,13 +656,17 @@ def test_get_histogram_and_get_probabilities_one_binary_qobject(
)
histogram = world.get_histogram()
assert histogram == [{0: 0, 1: 100}]
histogram = world.get_correlated_histogram()
assert histogram == {(1,): 100}
probs = world.get_probabilities()
assert probs == [{0: 0.0, 1: 1.0}]
bin_probs = world.get_binary_probabilities()
assert bin_probs == [1.0]
alpha.Flip()(l1)
histogram = world.get_histogram()
assert histogram == [{0: 100, 1: 0}]
histogram = world.get_correlated_histogram()
assert histogram == {(0,): 100}
probs = world.get_probabilities()
assert probs == [{0: 1.0, 1: 0.0}]
bin_probs = world.get_binary_probabilities()
Expand All @@ -673,6 +677,10 @@ def test_get_histogram_and_get_probabilities_one_binary_qobject(
assert len(histogram[0]) == 2
assert histogram[0][0] > 10
assert histogram[0][1] > 10
histogram = world.get_correlated_histogram()
assert len(histogram) == 2
assert histogram[(0,)] > 10
assert histogram[(1,)] > 10
probs = world.get_probabilities()
assert len(probs) == 1
assert len(probs[0]) == 2
Expand Down Expand Up @@ -700,6 +708,8 @@ def test_get_histogram_and_get_probabilities_one_trinary_qobject(
)
histogram = world.get_histogram()
assert histogram == [{0: 0, 1: 100, 2: 0}]
histogram = world.get_correlated_histogram()
assert histogram == {(1,): 100}
probs = world.get_probabilities()
assert probs == [{0: 0.0, 1: 1.0, 2: 0.0}]
bin_probs = world.get_binary_probabilities()
Expand All @@ -723,13 +733,45 @@ def test_get_histogram_and_get_probabilities_two_qobjects(simulator, compile_to_
)
histogram = world.get_histogram()
assert histogram == [{0: 0, 1: 100}, {0: 0, 1: 100, 2: 0}]
histogram = world.get_correlated_histogram()
assert histogram == {(1, 1): 100}
probs = world.get_probabilities()
assert probs == [{0: 0.0, 1: 1.0}, {0: 0.0, 1: 1.0, 2: 0.0}]
bin_probs = world.get_binary_probabilities()
assert bin_probs == [1.0, 1.0]
histogram = world.get_histogram(objects=[l2], count=1000)
assert histogram == [{0: 0, 1: 1000, 2: 0}]
histogram = world.get_correlated_histogram(objects=[l2], count=1000)
assert histogram == {(1,): 1000}
probs = world.get_probabilities(objects=[l2], count=1000)
assert probs == [{0: 0.0, 1: 1.0, 2: 0.0}]
bin_probs = world.get_binary_probabilities(objects=[l2], count=1000)
assert bin_probs == [1.0]


@pytest.mark.parametrize(
("simulator", "compile_to_qubits"),
[
(cirq.Simulator, False),
(cirq.Simulator, True),
# Cannot use SparseSimulator without `compile_to_qubits` due to issue #78.
(alpha.SparseSimulator, True),
],
)
def test_get_correlated_histogram_with_entangled_qobjects(simulator, compile_to_qubits):
light1 = alpha.QuantumObject("l1", Light.GREEN)
light2 = alpha.QuantumObject("l2", Light.RED)
light3 = alpha.QuantumObject("l3", Light.RED)
light4 = alpha.QuantumObject("l4", Light.GREEN)
light5 = alpha.QuantumObject("l5", Light.RED)

world = alpha.QuantumWorld(
[light1, light2, light3, light4, light5],
sampler=simulator(),
compile_to_qubits=compile_to_qubits,
)
alpha.Split()(light1, light2, light3)
alpha.quantum_if(light2).equals(1).apply(alpha.Move())(light4, light5)

histogram = world.get_correlated_histogram()
assert histogram.keys() == {(0, 0, 1, 1, 0), (0, 1, 0, 0, 1)}

0 comments on commit abb7a0b

Please sign in to comment.