-
Notifications
You must be signed in to change notification settings - Fork 1
Implement SimulatorBackend and Statevec #62
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
Merged
Changes from all commits
Commits
Show all changes
81 commits
Select commit
Hold shift + click to select a range
ed8b097
add is_hermitian
masa10-f b1f2674
add flip and conjugate method in MeasBasis
masa10-f cccca8b
implement simulator_backend
masa10-f 61085bb
fix docstring for sphinx build
masa10-f c2ba75b
implement statevec
masa10-f c548a35
resove numpy error
masa10-f 91100e3
fix pyright error
masa10-f b25aa86
update sphinx docs
masa10-f 55438dc
add unittest for statevec
masa10-f e19e123
safe type casting
masa10-f 2050db7
use abc.abstractmethod
masa10-f bfded20
fix mypy error
masa10-f 941422e
fix sphinx build error
masa10-f 50df50c
fix test
masa10-f e6f7812
update docs of matrix
masa10-f 9e8acd7
use ArrayLike in the input of StateVector.__init__()
masa10-f 2f4d149
remove internal _num_qubits
masa10-f 2087a0a
rename to copy
masa10-f 4d207ad
improve the performance of `evolve`
masa10-f 4535f93
update test for evolve method
masa10-f 777af77
update test comment
masa10-f f22b1a8
avoide unnecessary copy in measure
masa10-f 7404c0f
optimize add_node
masa10-f c280092
fix interface of entangle
masa10-f 0963f8a
make tensor_product a staticmethod
masa10-f 5a60625
remove is_isolated
masa10-f 39ff091
improve the efficiency of expectation
masa10-f 3fd559a
fix mypy errors
masa10-f 9d73962
manage qubit order for performance
masa10-f bbcf2d5
add test for reorder operations
masa10-f b50dd2b
add more test
masa10-f a116d57
fix the interface of StateVector
masa10-f 5a5f812
possess the state as a tensor object inside the class
masa10-f 2876673
format
masa10-f 33ed8f3
fix conjugate of Axis.Y
masa10-f edc6ab3
add missing import
masa10-f ab06500
fix StateVector.__init__
masa10-f d376646
fix copy method
masa10-f 94e2df5
fix docstring
masa10-f a74ddcc
Merge branch 'master' into statevec
masa10-f f647f2f
use ndim
masa10-f b3cc661
return tensor instead of flatten vector
masa10-f 118e4f9
remove property decorator from state
masa10-f ff77316
improve copy method
masa10-f 94a5e8e
use math.sqrt
masa10-f c8ccdf7
fix copy control
masa10-f 36f54bc
update test
masa10-f e226a84
fix ruff error
masa10-f e3773e1
Merge branch 'master' into statevec
masa10-f eca516b
implement QubitIndexManager
masa10-f d01e907
update statevec
masa10-f 2a2f408
update docstring
masa10-f 6e3dd06
fix mypy errors
masa10-f 28f0ea1
add unittest for QubitIndexManager
masa10-f 5efe303
use default instead of if branch
masa10-f d920b16
improve match func
masa10-f f0f9aae
improve performance of recovery_permutation
masa10-f 53d8aee
rename
masa10-f 80fe758
implement internal_to_external
masa10-f 77599e0
enforce sequential index
masa10-f 1927105
add num_qubits property
masa10-f f22dee3
cast into set
masa10-f 8db89fd
use ravel instead of flatten
masa10-f 1efc02a
remove redundant ravel
masa10-f e259fe1
modify the type of copy argument
masa10-f 7acb6f6
use bit_count to calculate num_qubits
masa10-f 7dd89c0
use tensordot
masa10-f b3a877a
fix pyright error
masa10-f 5bd9c19
avoid astype
masa10-f 440a356
use bit_length instead of bit_count
masa10-f 2303878
try to fix type error
masa10-f 855b133
Merge branch 'statevec' of github.com:TeamGraphix/graphix-zx into sta…
masa10-f c3e7fc8
patch for size=0 case
masa10-f a41cb64
allow __array__ and __asarray__
masa10-f 97d536f
implement __array__ and __asarray__
masa10-f d348b97
remove redundant tuple casting
masa10-f cf04fdf
adopt the suggested change
masa10-f 1552fec
specify dtype
masa10-f 540318a
remove __asarray__
masa10-f c9a7e3e
add copy argument
masa10-f d72594b
add test for __array__
masa10-f File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,8 @@ Module reference | |
| :maxdepth: 2 | ||
|
|
||
| common | ||
| simulator_backend | ||
| statevec | ||
| euler | ||
| matrix | ||
| graphstate | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Simulator Backend | ||
| ================= | ||
|
|
||
| .. automodule:: graphix_zx.simulator_backend | ||
| :members: | ||
| :undoc-members: | ||
| :show-inheritance: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| State Vector | ||
| ============ | ||
|
|
||
| .. automodule:: graphix_zx.statevec | ||
| :members: | ||
| :undoc-members: | ||
| :show-inheritance: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,205 @@ | ||
| """The base class for simulator backends. | ||
|
|
||
| This module provides: | ||
|
|
||
| - `QubitIndexManager`: Manages the mapping of external qubit indices to internal indices | ||
| - `BaseSimulatorBackend`: Abstract base class for simulator backends. | ||
|
|
||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import abc | ||
| import itertools | ||
| import typing | ||
| from abc import ABC | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| if TYPE_CHECKING: | ||
| from collections.abc import Sequence | ||
|
|
||
| import numpy as np | ||
| from numpy.typing import NDArray | ||
|
|
||
| from graphix_zx.common import MeasBasis | ||
|
|
||
|
|
||
| class QubitIndexManager: | ||
| """Manages the mapping of external qubit indices to internal indices.""" | ||
|
|
||
| def __init__(self, num_qubits: int) -> None: | ||
| """Initialize the QubitIndexManager with a list of initial indices.""" | ||
| self.__indices = list(range(num_qubits)) | ||
|
|
||
| @property | ||
| def num_qubits(self) -> int: | ||
| """Get the number of qubits managed by this manager. | ||
|
|
||
| Returns | ||
| ------- | ||
| `int` | ||
| The number of qubits. | ||
| """ | ||
| return len(self.__indices) | ||
|
|
||
| def add_qubits(self, num_qubits: int) -> None: | ||
| """Add a specified number of qubits to the index manager. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| num_qubits : `int` | ||
| The number of qubits to add. | ||
| """ | ||
| current_max = max(self.__indices, default=-1) | ||
| self.__indices.extend(range(current_max + 1, current_max + 1 + num_qubits)) | ||
|
|
||
| def remove_qubit(self, qubit: int) -> None: | ||
| r"""Remove specified qubit from the index manager. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| qubit : `int` | ||
| The qubit to remove. | ||
| """ | ||
| self.__indices = [q if q < qubit else q - 1 for q in self.__indices if q != qubit] | ||
|
|
||
| def match(self, order: Sequence[int]) -> bool: | ||
| r"""Check if the current indices match the given order. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| order : `collections.abc.Sequence`\[`int`\] | ||
| A sequence of indices to compare against the current indices. | ||
|
|
||
| Returns | ||
| ------- | ||
| `bool` | ||
| True if the current indices match the given order, False otherwise. | ||
| """ | ||
| return all(lhs == rhs for lhs, rhs in itertools.zip_longest(self.__indices, order, fillvalue=None)) | ||
|
|
||
| def reorder(self, permutation: Sequence[int]) -> None: | ||
| r"""Reorder the indices based on a given permutation. | ||
|
|
||
| if permutation is [2, 0, 1], then | ||
| # [q0, q1, q2] -> [q1, q2, q0] | ||
|
|
||
| Parameters | ||
| ---------- | ||
| permutation : `collections.abc.Sequence`\[`int`\] | ||
| A sequence of indices that defines the new order of the indices. | ||
|
|
||
| Raises | ||
| ------ | ||
| ValueError | ||
| If the length of the permutation does not match the number of indices. | ||
| """ | ||
| if len(permutation) != len(self.__indices): | ||
| msg = "Permutation length must match the number of indices." | ||
| raise ValueError(msg) | ||
| self.__indices = [self.__indices[i] for i in permutation] | ||
|
|
||
| def inverse_permutation(self) -> list[int]: | ||
| r"""Get the permutation that would recover the original order of indices. | ||
|
|
||
| Returns | ||
| ------- | ||
| `list`\[`int`\] | ||
| A sequence of indices that maps the current order back to the original order. | ||
| """ | ||
| inverse_perm = [0] * len(self.__indices) | ||
| for i, index in enumerate(self.__indices): | ||
| inverse_perm[index] = i | ||
| return inverse_perm | ||
|
|
||
| @typing.overload | ||
| def external_to_internal(self, external_qubits: int) -> int: ... | ||
|
|
||
| @typing.overload | ||
| def external_to_internal(self, external_qubits: Sequence[int]) -> tuple[int, ...]: ... | ||
|
|
||
| def external_to_internal(self, external_qubits: int | Sequence[int]) -> int | tuple[int, ...]: | ||
| r"""Convert external qubit indices to internal indices. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| external_qubits : `int` | `collections.abc.Sequence`\[`int`\] | ||
| A sequence of external qubit indices. | ||
|
|
||
| Returns | ||
| ------- | ||
| `int` | `tuple`\[`int`, ...\] | ||
| A list of internal qubit indices corresponding to the external ones. | ||
| """ | ||
| if isinstance(external_qubits, int): | ||
| return self.__indices[external_qubits] | ||
| return tuple(self.__indices[q] for q in external_qubits) | ||
|
|
||
| @typing.overload | ||
| def internal_to_external(self, internal_qubits: int) -> int: ... | ||
|
|
||
| @typing.overload | ||
| def internal_to_external(self, internal_qubits: Sequence[int]) -> tuple[int, ...]: ... | ||
|
|
||
| def internal_to_external(self, internal_qubits: int | Sequence[int]) -> int | tuple[int, ...]: | ||
| r"""Convert internal qubit indices to external indices. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| internal_qubits : `int` | `collections.abc.Sequence`\[`int`\] | ||
| A sequence of internal qubit indices. | ||
|
|
||
| Returns | ||
| ------- | ||
| `int` | `tuple`\[`int`, ...\] | ||
| A list of external qubit indices corresponding to the internal ones. | ||
| """ | ||
| inverse_perm = self.inverse_permutation() | ||
| if isinstance(internal_qubits, int): | ||
| return inverse_perm[internal_qubits] | ||
| return tuple(inverse_perm[q] for q in internal_qubits) | ||
|
|
||
|
|
||
| # backend for all simulator backends | ||
| class BaseSimulatorBackend(ABC): | ||
| """Base class for simulator backends.""" | ||
|
|
||
| @property | ||
| @abc.abstractmethod | ||
| def num_qubits(self) -> int: | ||
| """Get the number of qubits in the state. | ||
|
|
||
| Returns | ||
| ------- | ||
| `int` | ||
| The number of qubits in the state. | ||
| """ | ||
| raise NotImplementedError | ||
|
|
||
| @abc.abstractmethod | ||
| def evolve(self, operator: NDArray[np.complex128], qubits: int | Sequence[int]) -> None: | ||
| r"""Evolve the state by applying an operator to a subset of qubits. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| operator : `numpy.typing.NDArray`\[`numpy.complex128`\] | ||
| The operator to apply. | ||
| qubits : `int` | `collections.abc.Sequence`\[`int`\] | ||
| The qubits to apply the operator to. | ||
| """ | ||
| raise NotImplementedError | ||
|
|
||
| @abc.abstractmethod | ||
| def measure(self, qubit: int, meas_basis: MeasBasis, result: int) -> None: | ||
| """Measure a qubit in a given measurement basis. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| qubit : `int` | ||
| The qubit to measure. | ||
| meas_basis : `MeasBasis` | ||
| The measurement basis to use. | ||
| result : `int` | ||
| The measurement result. | ||
| """ | ||
| raise NotImplementedError | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.