-
Notifications
You must be signed in to change notification settings - Fork 119
Expand file tree
/
Copy pathjoin.py
More file actions
129 lines (104 loc) · 4.06 KB
/
Copy pathjoin.py
File metadata and controls
129 lines (104 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import warnings
from functools import cached_property
from typing import cast, Dict, List, Optional, Tuple, TYPE_CHECKING
import numpy as np
from attrs import field, frozen
from qualtran import (
Bloq,
bloq_example,
BloqDocSpec,
CompositeBloq,
ConnectionT,
DecomposeTypeError,
QAny,
QBit,
QDType,
QUInt,
Register,
Side,
Signature,
)
from qualtran.bloqs.bookkeeping._bookkeeping_bloq import _BookkeepingBloq
from qualtran.bloqs.bookkeeping.partition import LegacyPartitionWarning
from qualtran.drawing import directional_text_box, Text, WireSymbol
if TYPE_CHECKING:
import quimb.tensor as qtn
from numpy.typing import NDArray
from pennylane.operation import Operation
from pennylane.wires import Wires
from qualtran.cirq_interop import CirqQuregT
@frozen
class Join(_BookkeepingBloq):
"""Join an array of `QBit`s into one register of type `dtype`.
Args:
dtype: The quantum data type of the right (joined) register.
Registers:
reg: The register to be joined. On its left, it is an array of qubits. On the right, it is a register
of the given data type.
"""
dtype: QDType = field()
@cached_property
def signature(self) -> Signature:
return Signature(
[
Register('reg', QBit(), shape=(self.dtype.num_qubits,), side=Side.LEFT),
Register('reg', self.dtype, shape=tuple(), side=Side.RIGHT),
]
)
@dtype.validator
def _validate_dtype(self, attribute, value):
if value.is_symbolic():
raise ValueError(f"{self} cannot have a symbolic data type.")
def decompose_bloq(self) -> 'CompositeBloq':
raise DecomposeTypeError(f'{self} is atomic')
def adjoint(self) -> 'Bloq':
from qualtran.bloqs.bookkeeping.split import Split
return Split(dtype=self.dtype)
def as_cirq_op(self, qubit_manager, reg: 'CirqQuregT') -> Tuple[None, Dict[str, 'CirqQuregT']]:
return None, {'reg': reg.reshape(self.dtype.num_qubits)}
def as_pl_op(self, wires: 'Wires') -> 'Operation':
return None
def my_tensors(
self, incoming: Dict[str, 'ConnectionT'], outgoing: Dict[str, 'ConnectionT']
) -> List['qtn.Tensor']:
import quimb.tensor as qtn
eye = np.eye(2)
incoming = cast('NDArray', incoming['reg'])
outgoing = outgoing['reg']
return [
qtn.Tensor(data=eye, inds=[(outgoing, i), (incoming[i], 0)], tags=[str(self)])
for i in range(self.dtype.num_qubits)
]
def on_classical_vals(self, reg: 'NDArray[np.uint]') -> Dict[str, int]:
if isinstance(self.dtype, QAny):
warnings.warn(
"Doing classical operations with QAny is ambiguous, returning a QUInt for legacy purposes",
category=LegacyPartitionWarning,
)
return {'reg': QUInt(self.dtype.bitsize).from_bits(reg.tolist())}
return {'reg': self.dtype.from_bits(reg.tolist())}
def wire_symbol(self, reg: Optional[Register], idx: Tuple[int, ...] = tuple()) -> 'WireSymbol':
if reg is None:
return Text('')
if reg.shape:
text = f'[{", ".join(str(i) for i in idx)}]'
return directional_text_box(text, side=reg.side)
return directional_text_box(' ', side=reg.side)
@bloq_example
def _join() -> Join:
join = Join(dtype=QUInt(4))
return join
_JOIN_DOC = BloqDocSpec(bloq_cls=Join, examples=[_join], call_graph_example=None)