|
1 | | -# Copyright 2024-2026 Benjamin MacLellan |
2 | | - |
3 | | -# Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | -# you may not use this file except in compliance with the License. |
5 | | -# You may obtain a copy of the License at |
6 | | - |
7 | | -# http://www.apache.org/licenses/LICENSE-2.0 |
8 | | - |
9 | | -# Unless required by applicable law or agreed to in writing, software |
10 | | -# distributed under the License is distributed on an "AS IS" BASIS, |
11 | | -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | -# See the License for the specific language governing permissions and |
13 | | -# limitations under the License. |
14 | | - |
15 | | -# %% |
16 | | - |
17 | | -from beartype import beartype |
18 | | - |
19 | | -from squint.ops.base import ( |
20 | | - Block, |
21 | | -) |
22 | | - |
23 | | - |
24 | | -class Circuit(Block): |
25 | | - r""" |
26 | | - The `Circuit` object is a symbolic representation of a quantum circuit for qubits, qudits, or for an infinite-dimensional Fock space. |
27 | | - The circuit is composed of a sequence of quantum operators on `wires` which define the evolution of the quantum |
28 | | -
|
29 | | - Attributes: |
30 | | - ops (dict[Union[str, int], AbstractOp]): A dictionary of ops (dictionary value) with an assigned label (dictionary key). |
31 | | -
|
32 | | - Example: |
33 | | - ```python |
34 | | - circuit = Circuit(backend='pure') |
35 | | - circuit.add(DiscreteVariableState(wires=(0,))) |
36 | | - circuit.add(HGate(wires=(0,))) |
37 | | - ``` |
38 | | - """ |
39 | | - |
40 | | - @beartype |
41 | | - @classmethod |
42 | | - def from_block( |
43 | | - cls, |
44 | | - block: Block, |
45 | | - ): |
46 | | - """Promote a Block to a Circuit""" |
47 | | - self = cls() |
48 | | - self.ops = block.ops |
49 | | - return self |
| 1 | +# # Copyright 2024-2026 Benjamin MacLellan |
| 2 | + |
| 3 | +# # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +# # you may not use this file except in compliance with the License. |
| 5 | +# # You may obtain a copy of the License at |
| 6 | + |
| 7 | +# # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | + |
| 9 | +# # Unless required by applicable law or agreed to in writing, software |
| 10 | +# # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +# # See the License for the specific language governing permissions and |
| 13 | +# # limitations under the License. |
| 14 | + |
| 15 | +# # %% |
| 16 | +# import equinox as eqx |
| 17 | +# from beartype import beartype |
| 18 | +# import functools |
| 19 | +# import itertools |
| 20 | +# from collections import OrderedDict |
| 21 | +# from typing import Optional, Union |
| 22 | + |
| 23 | +# import equinox as eqx |
| 24 | +# import jax.numpy as jnp |
| 25 | +# import scipy as sp |
| 26 | +# from beartype import beartype |
| 27 | +# from beartype.door import is_bearable |
| 28 | +# from beartype.typing import Callable, Sequence |
| 29 | +# from ordered_set import OrderedSet |
| 30 | + |
| 31 | +# from squint.ops.gellmann import gellmann |
| 32 | + |
| 33 | +# _wire_id = itertools.count(1) |
| 34 | + |
| 35 | +# # from squint.ops.base import ( |
| 36 | +# # Block, |
| 37 | +# # ) |
| 38 | + |
| 39 | + |
| 40 | +# class Circuit(eqx.Module): |
| 41 | +# """ |
| 42 | +# A block operation that groups a sequence of quantum operations. |
| 43 | + |
| 44 | +# Blocks allow organizing multiple operations into a single logical unit. |
| 45 | +# They can be nested within circuits or other blocks, and support the same |
| 46 | +# `add` and `unwrap` interface as Circuit. Unlike Circuit, Block does not |
| 47 | +# specify a backend and is purely for organizational purposes. |
| 48 | + |
| 49 | +# Attributes: |
| 50 | +# ops (OrderedDict): Ordered dictionary mapping keys to operations or nested blocks. |
| 51 | + |
| 52 | +# Example: |
| 53 | +# ```python |
| 54 | +# from squint.ops.base import Block, Wire |
| 55 | +# from squint.ops.dv import RXGate, RYGate |
| 56 | + |
| 57 | +# wire = Wire(dim=2, idx=0) |
| 58 | +# block = Block() |
| 59 | +# block.add(RXGate(wires=(wire,), phi=0.1), "rx") |
| 60 | +# block.add(RYGate(wires=(wire,), phi=0.2), "ry") |
| 61 | + |
| 62 | +# # Use in a circuit |
| 63 | +# circuit.add(block, "rotation_block") |
| 64 | +# ``` |
| 65 | +# """ |
| 66 | + |
| 67 | +# ops: OrderedDict[Union[str, int], Union[AbstractOp, "Circuit"]] |
| 68 | +# # ops: dict[Union[str, int], Union[AbstractOp, "Block"]] |
| 69 | + |
| 70 | +# @beartype |
| 71 | +# def __init__( |
| 72 | +# self, |
| 73 | +# ops: dict | OrderedDict = {} |
| 74 | +# # ops: OrderedDict = OrderedDict() |
| 75 | +# ): |
| 76 | +# """ |
| 77 | +# Initialize an empty Block. |
| 78 | + |
| 79 | +# Creates a new Block with no operations. Operations can be added |
| 80 | +# using the `add` method. |
| 81 | +# """ |
| 82 | +# self.ops = OrderedDict(ops) |
| 83 | + |
| 84 | +# @property |
| 85 | +# def wires(self) -> Sequence[Wire]: |
| 86 | +# """ |
| 87 | +# Get all wires used by operations in this block. |
| 88 | + |
| 89 | +# Returns: |
| 90 | +# set[Wire]: Set of all Wire objects that operations in this block act on. |
| 91 | +# """ |
| 92 | +# # BUG: this line caused a bug with undefined wire order |
| 93 | +# # return set(sum((op.wires for op in self.unwrap()), ())) |
| 94 | +# return OrderedSet( |
| 95 | +# sorted( |
| 96 | +# dict.fromkeys( |
| 97 | +# itertools.chain.from_iterable(op.wires for op in self.unwrap()) |
| 98 | +# ), |
| 99 | +# key=wire_sort_key, |
| 100 | +# ) |
| 101 | +# ) |
| 102 | + |
| 103 | +# @beartype |
| 104 | +# def add(self, op: Union[AbstractOp, "Circuit"], key: str = None) -> None: |
| 105 | +# """ |
| 106 | +# Add an operator to the block. |
| 107 | + |
| 108 | +# Operators are added sequentially. When this block is used in a circuit, |
| 109 | +# the operations will be applied in the order they were added. |
| 110 | + |
| 111 | +# Args: |
| 112 | +# op (AbstractOp | Block): The operator or nested block to add. |
| 113 | +# key (str, optional): A string key for indexing into the block's ops |
| 114 | +# dictionary. If None, an integer counter is used as the key. |
| 115 | +# """ |
| 116 | + |
| 117 | +# if key is None: |
| 118 | +# key = len(self.ops) |
| 119 | +# self.ops[key] = op |
| 120 | + |
| 121 | +# # def unwrap(self) -> tuple[AbstractOp]: |
| 122 | +# # """ |
| 123 | +# # Unwrap all operators in the block into a flat tuple. |
| 124 | + |
| 125 | +# # Recursively calls `unwrap()` on all contained operations and nested |
| 126 | +# # blocks to produce a flat sequence of atomic operations. |
| 127 | + |
| 128 | +# # Returns: |
| 129 | +# # tuple[AbstractOp]: Flattened tuple of all operations in order. |
| 130 | +# # """ |
| 131 | +# # return tuple( |
| 132 | +# # op for op_wrapped in self.ops.values() for op in op_wrapped.unwrap() |
| 133 | +# # ) |
| 134 | +# # # return Block( |
| 135 | +# # # ops= |
| 136 | +# # # {k: op for k, op_wrapped in self.ops.values() for op in op_wrapped.unwrap() |
| 137 | +# # # ) |
| 138 | + |
| 139 | + |
| 140 | + |
| 141 | +# # class Circuit(Block): |
| 142 | +# # r""" |
| 143 | +# # The `Circuit` object is a symbolic representation of a quantum circuit for qubits, qudits, or for an infinite-dimensional Fock space. |
| 144 | +# # The circuit is composed of a sequence of quantum operators on `wires` which define the evolution of the quantum |
| 145 | + |
| 146 | +# # Attributes: |
| 147 | +# # ops (dict[Union[str, int], AbstractOp]): A dictionary of ops (dictionary value) with an assigned label (dictionary key). |
| 148 | + |
| 149 | +# # Example: |
| 150 | +# # ```python |
| 151 | +# # circuit = Circuit(backend='pure') |
| 152 | +# # circuit.add(DiscreteVariableState(wires=(0,))) |
| 153 | +# # circuit.add(HGate(wires=(0,))) |
| 154 | +# # ``` |
| 155 | +# # """ |
| 156 | + |
| 157 | +# # @beartype |
| 158 | +# # @classmethod |
| 159 | +# # def from_block( |
| 160 | +# # cls, |
| 161 | +# # block: Block, |
| 162 | +# # ): |
| 163 | +# # """Promote a Block to a Circuit""" |
| 164 | +# # self = cls() |
| 165 | +# # self.ops = block.ops |
| 166 | +# # return self |
0 commit comments