Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qutrit mixed apply operation #5032

Merged
merged 111 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
c54dcf7
Barebones of initialize state
Gabriel-Bottrill Nov 9, 2023
eb801dd
ideas for abstracting for mixed
Gabriel-Bottrill Nov 10, 2023
d35a33c
Finished qutrit mixed code
Gabriel-Bottrill Nov 10, 2023
4f04478
Black on qutrit_mixed
Gabriel-Bottrill Nov 10, 2023
167c10b
Added input check
Gabriel-Bottrill Nov 11, 2023
20e4e11
added some test stubs
Gabriel-Bottrill Nov 11, 2023
9349713
close
Gabriel-Bottrill Nov 18, 2023
e909175
Merge branch 'master' into qutrit_mixed_initialization
Gabriel-Bottrill Nov 21, 2023
84de122
Finalized tests
Gabriel-Bottrill Nov 21, 2023
6ee7993
dded docstring
Gabriel-Bottrill Nov 21, 2023
90101c9
Reformatted file
Gabriel-Bottrill Nov 21, 2023
d9473fd
Fixed import order
Gabriel-Bottrill Nov 21, 2023
acb88f0
fixed pylint and reformatted
Gabriel-Bottrill Nov 21, 2023
19afcd2
Changed file name
Gabriel-Bottrill Nov 21, 2023
4deca53
added test for Wires
Gabriel-Bottrill Nov 21, 2023
f010113
fixed qml.Wires to qml.wires.Wires
Gabriel-Bottrill Nov 21, 2023
505ff1b
Fixed wires to convert to array
Gabriel-Bottrill Nov 23, 2023
ffba085
Merge branch 'qutrit_mixed_initialization' of github.com:QSAR-UBC/pen…
Gabriel-Bottrill Nov 23, 2023
be7c1f1
refomatted black
Gabriel-Bottrill Nov 23, 2023
981f5f0
Merge branch 'master' into qutrit_mixed_initialization
Gabriel-Bottrill Nov 23, 2023
82b49f8
Merge branch 'master' into qutrit_mixed_initialization
Gabriel-Bottrill Nov 27, 2023
e0d456c
Update pennylane/devices/qutrit_mixed/initialize_state.py
Gabriel-Bottrill Nov 28, 2023
644c173
Fix comments
Gabriel-Bottrill Nov 28, 2023
8a73ccf
removed print
Gabriel-Bottrill Nov 28, 2023
58fb4f4
fixed basis state comment
Gabriel-Bottrill Nov 28, 2023
b20578d
Fixed wires and doc-strings
Gabriel-Bottrill Nov 28, 2023
2fcf17e
Fixed basis states from change to list
Gabriel-Bottrill Nov 28, 2023
e3212ed
fixed num wires, working on operation batched
Gabriel-Bottrill Dec 5, 2023
c657719
Fixed selection in default
Gabriel-Bottrill Dec 5, 2023
bffd530
Added stub for TAdd
Gabriel-Bottrill Dec 5, 2023
08cbb58
Added stubs for tests to add
Gabriel-Bottrill Dec 5, 2023
e4b826a
Continued implementation of broadcasting
Gabriel-Bottrill Dec 12, 2023
5fe57dc
Continued implementing tests
Gabriel-Bottrill Dec 12, 2023
cb0bf3b
Added support for operation batching, continued work on tests
Gabriel-Bottrill Dec 20, 2023
15f83e0
Added broadcasting, channel, and more tests. Fixed some bugs in apply_op
Gabriel-Bottrill Jan 5, 2024
3ff3959
fixed tensordot method, work on tests
Gabriel-Bottrill Jan 5, 2024
4909fbd
Merged Pennylane
Gabriel-Bottrill Jan 5, 2024
dc0ddb0
Added THadamard test
Gabriel-Bottrill Jan 5, 2024
9484c35
fixed einsum throwing error on broadcast, still incorrect return
Gabriel-Bottrill Jan 5, 2024
0aa07b2
Fixed broadcasting for einsum, removed broadcasting from tensordot
Gabriel-Bottrill Jan 9, 2024
90dc4ee
Tests for broadcasting fixed
Gabriel-Bottrill Jan 9, 2024
c71996a
Removed comments and unecessary tests
Gabriel-Bottrill Jan 10, 2024
d1c2dc1
Merge branch 'master' into qutrit_mixed_apply_operation
Gabriel-Bottrill Jan 10, 2024
48e75ea
Fixed ml_framework for Channel tests
Gabriel-Bottrill Jan 10, 2024
19cfa89
Merge branch 'qutrit_mixed_apply_operation' of github.com:QSAR-UBC/pe…
Gabriel-Bottrill Jan 10, 2024
1ee2067
Fixed codefactor, updated apply_snapshot
Gabriel-Bottrill Jan 10, 2024
901bd3e
Fix interface issure in tests
Gabriel-Bottrill Jan 10, 2024
c8ee90c
Fixed pylint issues
Gabriel-Bottrill Jan 10, 2024
9169895
Removed unused function
Gabriel-Bottrill Jan 10, 2024
05ee297
Removed accadental addition
Gabriel-Bottrill Jan 10, 2024
2a5cd34
Fixed import order for pylint
Gabriel-Bottrill Jan 10, 2024
77af2f9
Fixed conjugate for torch
Gabriel-Bottrill Jan 10, 2024
f0780ee
updated changelog to include qutrit_mixed apply_operation
Gabriel-Bottrill Jan 10, 2024
17d06a5
Increased code coverage
Gabriel-Bottrill Jan 10, 2024
8f3a4cb
Update doc/releases/changelog-dev.md
Gabriel-Bottrill Jan 10, 2024
242934e
Merge branch 'master' into qutrit_mixed_apply_operation
Gabriel-Bottrill Jan 11, 2024
707a4aa
Removed random value generation in tests
Gabriel-Bottrill Jan 11, 2024
f1dd22c
Fixed loading issues
Gabriel-Bottrill Jan 12, 2024
eeaaded
Removed tensordot from commit
Gabriel-Bottrill Jan 12, 2024
dd456b7
mend
Gabriel-Bottrill Jan 12, 2024
abb0efc
Seperated einsum indices collection as it is useful for a later PR
Gabriel-Bottrill Jan 12, 2024
24c6354
fixed code issues
Gabriel-Bottrill Jan 12, 2024
dd18998
remove unused import
Gabriel-Bottrill Jan 12, 2024
fb919e0
Fix naming mistake
Gabriel-Bottrill Jan 12, 2024
6d53020
Remove accedental refactor
Gabriel-Bottrill Jan 12, 2024
3884e7f
replaced qudit_dim with QUDIT_DIM
Gabriel-Bottrill Jan 12, 2024
3f1acd6
Fixed docstrings and added a NotImplementedError
Gabriel-Bottrill Jan 12, 2024
b9c5f8b
Moved state prep to conftest file to be fixtures
Gabriel-Bottrill Jan 13, 2024
e1f0a56
Merge branch 'qutrit_mixed_apply_operation' of github.com:QSAR-UBC/pe…
Gabriel-Bottrill Jan 13, 2024
78418a6
Fix name of class qubit->qutrit
Gabriel-Bottrill Jan 13, 2024
0e287d1
removed special cases from tests
Gabriel-Bottrill Jan 13, 2024
06a857f
Fixed conflict
Gabriel-Bottrill Jan 13, 2024
72eb40e
Changed einsum indices abstraction to be more abstract for future use
Gabriel-Bottrill Jan 13, 2024
f5bb609
Merge branch 'master' into qutrit_mixed_apply_operation
Gabriel-Bottrill Jan 13, 2024
cfddb59
Fixed pylint issues
Gabriel-Bottrill Jan 13, 2024
ba155f2
Merge branch 'qutrit_mixed_apply_operation' of github.com:QSAR-UBC/pe…
Gabriel-Bottrill Jan 13, 2024
505c6d1
Refactor
Gabriel-Bottrill Jan 13, 2024
60434da
Fixed docstrings of helper functions
Gabriel-Bottrill Jan 13, 2024
10c8408
Fixed pylint issues
Gabriel-Bottrill Jan 13, 2024
cfb1bf6
Fixed indent that caused tests to fail
Gabriel-Bottrill Jan 13, 2024
72e0973
Added comma to fix broken changelog
Gabriel-Bottrill Jan 15, 2024
8dd97ab
Merge branch 'master' into qutrit_mixed_apply_operation
Gabriel-Bottrill Jan 15, 2024
7645f37
Added test for snapshot with measurement
Gabriel-Bottrill Jan 15, 2024
be2ac14
Moved map indices to private function in apply_operation
Gabriel-Bottrill Jan 16, 2024
174f2b3
Merge branch 'qutrit_mixed_apply_operation' of github.com:QSAR-UBC/pe…
Gabriel-Bottrill Jan 16, 2024
d2d4aa2
changed test name
Gabriel-Bottrill Jan 16, 2024
64c4fe1
fixed docstring
Gabriel-Bottrill Jan 16, 2024
8c4b220
changed to local random number generator
Gabriel-Bottrill Jan 16, 2024
e4cf311
Fixed docstring
Gabriel-Bottrill Jan 17, 2024
736cfa8
swapped np to math
Gabriel-Bottrill Jan 17, 2024
9d62090
changed np to math
Gabriel-Bottrill Jan 17, 2024
cbf29bd
Merge branch 'master' into qutrit_mixed_apply_operation
Gabriel-Bottrill Jan 17, 2024
98e9af5
Simplified getting Kraus transforms
Gabriel-Bottrill Jan 17, 2024
6df023a
Fixed failing tests from incorrect call to unitary_group.rvs
Gabriel-Bottrill Jan 17, 2024
a2008fd
Merge branch 'master' into qutrit_mixed_apply_operation
glassnotes Jan 17, 2024
5d442a6
Merge branch 'master' into qutrit_mixed_apply_operation
glassnotes Jan 17, 2024
ebd930f
restructured helper functions
Gabriel-Bottrill Jan 17, 2024
fa258e0
Added tests for different wires, refactored to abstract test function…
Gabriel-Bottrill Jan 18, 2024
544b4a6
Fixed what to sum channels over
Gabriel-Bottrill Jan 18, 2024
e58a5cf
Fixed channels tests
Gabriel-Bottrill Jan 18, 2024
66f3b2c
Fixed operator test
Gabriel-Bottrill Jan 18, 2024
8a70f05
Update pennylane/devices/qutrit_mixed/apply_operation.py
Gabriel-Bottrill Jan 23, 2024
9b6cd7a
change variable name
Gabriel-Bottrill Jan 23, 2024
80dee63
Update tests/devices/qutrit_mixed/test_qutrit_mixed_apply_operation.py
Gabriel-Bottrill Jan 23, 2024
d48210b
removed TODO for channels
Gabriel-Bottrill Jan 23, 2024
0fdad85
Merge branch 'master' into qutrit_mixed_apply_operation
Gabriel-Bottrill Jan 23, 2024
f14d5ae
Merge branch 'master' into qutrit_mixed_apply_operation
Gabriel-Bottrill Jan 23, 2024
12e2475
Merge branch 'master' into qutrit_mixed_apply_operation
Gabriel-Bottrill Jan 23, 2024
b9f574b
Forced failing tests to use x64
Gabriel-Bottrill Jan 23, 2024
bc47f12
Merge branch 'master' into qutrit_mixed_apply_operation
glassnotes Jan 29, 2024
22f8fae
Merge branch 'master' into qutrit_mixed_apply_operation
Gabriel-Bottrill Jan 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 32 additions & 48 deletions pennylane/devices/qutrit_mixed/apply_operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,28 @@
alphabet_array = np.array(list(alphabet))


def _map_indices_apply_channel(**kwargs):
"""Map indices to einsum string
Args:
**kwargs (dict): Stores indices calculated in `get_einsum_mapping`

Returns:
String of einsum indices to complete einsum calculations
"""
op_1_indices = f"{kwargs['kraus_index']}{kwargs['new_row_indices']}{kwargs['row_indices']}"
op_2_indices = f"{kwargs['kraus_index']}{kwargs['col_indices']}{kwargs['new_col_indices']}"

new_state_indices = get_new_state_einsum_indices(
old_indices=kwargs["col_indices"] + kwargs["row_indices"],
new_indices=kwargs["new_col_indices"] + kwargs["new_row_indices"],
state_indices=kwargs["state_indices"],
)
# index mapping for einsum, e.g., '...iga,...abcdef,...idh->...gbchef'
return (
f"...{op_1_indices},...{kwargs['state_indices']},...{op_2_indices}->...{new_state_indices}"
)


def apply_operation_einsum(op: qml.operation.Operator, state, is_state_batched: bool = False):
r"""Apply a quantum channel specified by a list of Kraus operators to subsystems of the
quantum state. For a unitary gate, there is a single Kraus operator.
Expand All @@ -37,15 +59,18 @@ def apply_operation_einsum(op: qml.operation.Operator, state, is_state_batched:
Returns:
array[complex]: output_state
"""
einsum_indices = get_einsum_mapping(op, state, _map_indices, is_state_batched)
einsum_indices = get_einsum_mapping(op, state, _map_indices_apply_channel, is_state_batched)

num_ch_wires = len(op.wires)
kraus = _get_kraus(op)

# This could be pulled into separate function if tensordot is added
if isinstance(op, Channel):
kraus = op.kraus_matrices()
else:
kraus = [op.matrix()]

# Shape kraus operators
kraus_shape = [len(kraus)] + [QUDIT_DIM] * num_ch_wires * 2
# Compute K^T, will be list of lists if broadcasting
kraus_transpose = []
if not isinstance(op, Channel):
# TODO Channels broadcasting doesn't seem to be implemented for qubits, should they be for qutrit?
Gabriel-Bottrill marked this conversation as resolved.
Show resolved Hide resolved
mat = op.matrix()
Expand All @@ -56,13 +81,9 @@ def apply_operation_einsum(op: qml.operation.Operator, state, is_state_batched:
kraus_shape = [batch_size] + kraus_shape
if op.batch_size is None:
op._batch_size = batch_size # pylint:disable=protected-access
for op_mats in kraus:
kraus_transpose.append([math.transpose(k) for k in op_mats])
if not kraus_transpose:
kraus_transpose = [math.transpose(k) for k in kraus]

kraus = math.stack(kraus)
kraus_transpose = math.stack(kraus_transpose)
kraus_transpose = math.stack(math.moveaxis(kraus, source=-1, destination=-2))
# Torch throws error if math.conj is used before stack
kraus_dagger = math.conj(kraus_transpose)

Expand All @@ -72,28 +93,6 @@ def apply_operation_einsum(op: qml.operation.Operator, state, is_state_batched:
return math.einsum(einsum_indices, kraus, state, kraus_dagger)


def _map_indices(**kwargs):
"""map indices to einsum string
Args:
**kwargs (dict): Stores indices calculated in `get_einsum_mapping`

Returns:
String of einsum indices to complete einsum calculations
"""
op_1_indices = f"{kwargs['kraus_index']}{kwargs['new_row_indices']}{kwargs['row_indices']}"
op_2_indices = f"{kwargs['kraus_index']}{kwargs['col_indices']}{kwargs['new_col_indices']}"

new_state_indices = get_new_state_einsum_indices(
old_indices=kwargs["col_indices"] + kwargs["row_indices"],
new_indices=kwargs["new_col_indices"] + kwargs["new_row_indices"],
state_indices=kwargs["state_indices"],
)
# index mapping for einsum, e.g., '...iga,...abcdef,...idh->...gbchef'
return (
f"...{op_1_indices},...{kwargs['state_indices']},...{op_2_indices}->...{new_state_indices}"
)


@singledispatch
def apply_operation(
op: qml.operation.Operator, state, is_state_batched: bool = False, debugger=None
Gabriel-Bottrill marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -169,10 +168,10 @@ def apply_snapshot(op: qml.Snapshot, state, is_state_batched: bool = False, debu
# TODO replace with: measure once added
raise NotImplementedError # TODO
if is_state_batched:
dim = int(np.sqrt(math.size(state[0])))
dim = int(math.sqrt(math.size(state[0])))
flat_shape = [math.shape(state)[0], dim, dim]
else:
dim = int(np.sqrt(math.size(state)))
dim = int(math.sqrt(math.size(state)))
flat_shape = [dim, dim]

snapshot = math.reshape(state, flat_shape)
Expand All @@ -184,18 +183,3 @@ def apply_snapshot(op: qml.Snapshot, state, is_state_batched: bool = False, debu


# TODO add special case speedups
Gabriel-Bottrill marked this conversation as resolved.
Show resolved Hide resolved


def _get_kraus(operation): # pylint: disable=no-self-use
"""Return the Kraus operators representing the operation.

Args:
operation (.Operation): a PennyLane operation

Returns:
list[array[complex]]: Returns a list of 2D matrices representing the Kraus operators. If
the operation is unitary, returns a single Kraus operator.
"""
if isinstance(operation, Channel):
return operation.kraus_matrices()
return [operation.matrix()]
2 changes: 1 addition & 1 deletion pennylane/devices/qutrit_mixed/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ def get_einsum_mapping(
Args:
op (Operator): Operator to apply to the quantum state
state (array[complex]): Input quantum state
is_state_batched (bool): Boolean representing whether the state is batched or not
map_indices (function): Maps the calculated indices to an einsum indices string
is_state_batched (bool): Boolean representing whether the state is batched or not

Returns:
str: indices mapping that defines the einsum
Expand Down
8 changes: 3 additions & 5 deletions tests/devices/qutrit_mixed/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@
from scipy.stats import unitary_group
import pytest

SEED = 4774


def get_random_mixed_state(num_qutrits):
dim = 3**num_qutrits

np.random.seed(seed=SEED)
basis = unitary_group.rvs(dim)
Schmidt_weights = np.random.dirichlet(np.ones(dim), size=1).astype(complex)[0]
rng = np.random.default_rng(seed=4774)
basis = unitary_group(dim=dim, seed=584545).rvs()
Schmidt_weights = rng.dirichlet(np.ones(dim), size=1).astype(complex)[0]
mixed_state = np.zeros((dim, dim)).astype(complex)
for i in range(dim):
mixed_state += Schmidt_weights[i] * np.outer(np.conj(basis[i]), basis[i])
Expand Down
Loading
Loading