Skip to content

Commit 2b305df

Browse files
authored
Merge pull request #205 from BQSKit/more-small-updates
More small updates
2 parents 839e0e3 + b9ba3b4 commit 2b305df

File tree

4 files changed

+74
-6
lines changed

4 files changed

+74
-6
lines changed

bqskit/ir/gates/composed/embedded.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ class EmbeddedGate(ComposedGate, DifferentiableUnitary):
5050
5151
This concept can be generalized to multiple qudits and even
5252
mixed-radix systems.
53+
54+
Note:
55+
- Global phase inconsistencies in gates will become local phase
56+
inconsistencies in the embedded gate. For example, if the
57+
global phase difference between the U1Gate and the RZGate
58+
will become local phase differences in the corresponding
59+
subspaces when embedded into a higher-dimensional qudit.
5360
"""
5461

5562
def __init__(
@@ -201,7 +208,7 @@ def __init__(
201208
self.gate = gate
202209
self.level_maps = tuple([tuple(list(lmap)) for lmap in level_maps])
203210
self._num_qudits = gate._num_qudits
204-
self._name = 'Embedded(%s)' % self.gate.name # TODO: include radixes and level maps # noqa: E501
211+
self._name = f'Embedded({self.gate.name}){self.level_maps}'
205212
self._num_params = self.gate._num_params
206213
self._radixes = tuple(radixes)
207214
self._dim = int(np.prod(self.radixes))

bqskit/ir/gates/parameterized/rz.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ class RZGate(QubitGate, DifferentiableUnitary, CachedClass):
2020
.. math::
2121
2222
\\begin{pmatrix}
23-
\\exp({i\\frac{\\theta}{2}}) & 0 \\\\
24-
0 & \\exp({-i\\frac{\\theta}{2}}) \\\\
23+
\\exp({-i\\frac{\\theta}{2}}) & 0 \\\\
24+
0 & \\exp({i\\frac{\\theta}{2}}) \\\\
2525
\\end{pmatrix}
2626
"""
2727

bqskit/ir/opt/instantiaters/minimization.py

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@
1313
from bqskit.ir.opt.instantiater import Instantiater
1414
from bqskit.ir.opt.minimizer import Minimizer
1515
from bqskit.ir.opt.minimizers.ceres import CeresMinimizer
16+
from bqskit.ir.opt.multistartgens.random import RandomStartGenerator
17+
from bqskit.qis.state.state import StateLike
1618
from bqskit.qis.state.state import StateVector
17-
from bqskit.qis.state.system import StateSystem
18-
from bqskit.qis.unitary.unitarymatrix import UnitaryMatrix
1919

2020
if TYPE_CHECKING:
2121
from bqskit.ir.circuit import Circuit
22+
from bqskit.qis.state.system import StateSystem
23+
from bqskit.qis.state.system import StateSystemLike
24+
from bqskit.qis.unitary.unitarymatrix import UnitaryLike
25+
from bqskit.qis.unitary.unitarymatrix import UnitaryMatrix
2226

2327

2428
class Minimization(Instantiater):
@@ -61,7 +65,6 @@ def instantiate(
6165
) -> npt.NDArray[np.float64]:
6266
"""Instantiate `circuit`, see Instantiater for more info."""
6367
cost = self.cost_fn_gen.gen_cost(circuit, target)
64-
# print(x0, circuit.num_params, circuit.gate_counts)
6568
return self.minimizer.minimize(cost, x0)
6669

6770
@staticmethod
@@ -88,3 +91,48 @@ def get_violation_report(circuit: Circuit) -> str:
8891
def get_method_name() -> str:
8992
"""Return the name of this method."""
9093
return 'minimization'
94+
95+
def multi_start_instantiate_inplace(
96+
self,
97+
circuit: Circuit,
98+
target: UnitaryLike | StateLike | StateSystemLike,
99+
num_starts: int,
100+
) -> None:
101+
"""
102+
Instantiate `circuit` to best implement `target` with multiple starts.
103+
104+
See Instantiater for more info.
105+
"""
106+
target = self.check_target(target)
107+
start_gen = RandomStartGenerator()
108+
starts = start_gen.gen_starting_points(num_starts, circuit, target)
109+
cost_fn = self.cost_fn_gen.gen_cost(circuit, target)
110+
params_list = [self.instantiate(circuit, target, x0) for x0 in starts]
111+
params = sorted(params_list, key=lambda x: cost_fn(x))[0]
112+
circuit.set_params(params)
113+
114+
async def multi_start_instantiate_async(
115+
self,
116+
circuit: Circuit,
117+
target: UnitaryLike | StateLike | StateSystemLike,
118+
num_starts: int,
119+
) -> Circuit:
120+
"""
121+
Instantiate `circuit` to best implement `target` with multiple starts.
122+
123+
See Instantiater for more info.
124+
"""
125+
from bqskit.runtime import get_runtime
126+
target = self.check_target(target)
127+
start_gen = RandomStartGenerator()
128+
starts = start_gen.gen_starting_points(num_starts, circuit, target)
129+
cost_fn = self.cost_fn_gen.gen_cost(circuit, target)
130+
params_list = await get_runtime().map(
131+
self.instantiate,
132+
[circuit] * num_starts,
133+
[target] * num_starts,
134+
starts,
135+
)
136+
params = sorted(params_list, key=lambda x: cost_fn(x))[0]
137+
circuit.set_params(params)
138+
return circuit

bqskit/qis/unitary/unitarymatrix.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@ def dagger(self) -> UnitaryMatrix:
152152
"""The conjugate transpose of the unitary."""
153153
return self.conj().T
154154

155+
def to_special(self) -> UnitaryMatrix:
156+
"""Return a special unitary matrix verson of this one."""
157+
determinant = np.linalg.det(self)
158+
dimension = len(self)
159+
global_phase = np.angle(determinant) / dimension
160+
global_phase = global_phase % (2 * np.pi / dimension)
161+
global_phase_factor = np.exp(-1j * global_phase)
162+
return global_phase_factor * self
163+
164+
def is_special(self) -> bool:
165+
"""Return true if this unitary is special."""
166+
return 1 - np.abs(np.linalg.det(self)) < 1e-8
167+
155168
def __len__(self) -> int:
156169
"""The dimension of the square unitary matrix."""
157170
return self.shape[0]

0 commit comments

Comments
 (0)