Skip to content

Commit 46caba8

Browse files
Merge branch 'beta'
2 parents a46ef11 + 0f8b9dd commit 46caba8

File tree

3 files changed

+31
-12
lines changed

3 files changed

+31
-12
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626

2727
- Add ccx as another alias for toffoli gate
2828

29+
### Changed
30+
31+
- Seperate channel auto register for circuit class with unitary and general case
32+
33+
- The old standlone depolarizing implementation can now be called via `c.depolarizing_reference`
34+
2935
### Fixed
3036

3137
- Move `iswap` gate to vgates list
@@ -36,6 +42,8 @@
3642

3743
- Fix the use of rev over rev jacobian for hessian method and back to the efficient solution of fwd over rev order due to the solution of nested vmap issue on tf backend
3844

45+
- Identify potential bug in `unitary_kraus2` implementation, change to `unitary_kraus` instead
46+
3947
## 0.4.0
4048

4149
### Added

tensorcircuit/applications/layers.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@ def f(
213213
qubit2,
214214
-symbol0 * g[e[0]][e[1]].get("weight", 1.0) * 2,
215215
) ## should be better as * 2 # e^{-i\theta H}, H=-ZZ
216-
circuit.depolarizing(e[0], px=params[0], py=params[1], pz=params[2])
217-
circuit.depolarizing(e[1], px=params[0], py=params[1], pz=params[2])
216+
circuit.depolarizing(e[0], px=params[0], py=params[1], pz=params[2]) # type: ignore
217+
circuit.depolarizing(e[1], px=params[0], py=params[1], pz=params[2]) # type: ignore
218218
return circuit
219219

220220
f.__doc__ = """%slayer_bitflip_mc""" % gates
@@ -238,8 +238,8 @@ def f(
238238
-symbol[i] * g[e[0]][e[1]].get("weight", 1.0) * 2, # type: ignore
239239
)
240240
## should be better as * 2 # e^{-i\theta H}, H=-ZZ
241-
circuit.depolarizing(e[0], px=params[0], py=params[1], pz=params[2])
242-
circuit.depolarizing(e[1], px=params[0], py=params[1], pz=params[2])
241+
circuit.depolarizing(e[0], px=params[0], py=params[1], pz=params[2]) # type: ignore
242+
circuit.depolarizing(e[1], px=params[0], py=params[1], pz=params[2]) # type: ignore
243243
return circuit
244244

245245
f.__doc__ = """any%slayer_bitflip_mc""" % gates
@@ -288,8 +288,8 @@ def anyswaplayer_bitflip_mc(
288288
unitary=array_to_tensor(_swap_matrix),
289289
theta=symbol[i] * g[e[0]][e[1]].get("weight", 1.0),
290290
)
291-
circuit.depolarizing(e[0], px=px, py=py, pz=pz)
292-
circuit.depolarizing(e[1], px=px, py=py, pz=pz)
291+
circuit.depolarizing(e[0], px=px, py=py, pz=pz) # type: ignore
292+
circuit.depolarizing(e[1], px=px, py=py, pz=pz) # type: ignore
293293
return circuit
294294

295295

@@ -324,7 +324,7 @@ def bitfliplayer(ci: DMCircuit, g: Graph, px: float, py: float, pz: float) -> No
324324
def bitfliplayer_mc(ci: Circuit, g: Graph, px: float, py: float, pz: float) -> None:
325325
n = len(g.nodes)
326326
for i in range(n):
327-
ci.depolarizing(i, px=px, py=py, pz=pz)
327+
ci.depolarizing(i, px=px, py=py, pz=pz) # type: ignore
328328
bitfliplayer.__repr__ = """bitfliplayer_mc""" # type: ignore
329329
bitfliplayer.__trainable__ = True # type: ignore
330330

tensorcircuit/circuit.py

+16-5
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def depolarizing2(
255255
# building time and running time are similar
256256

257257
# overwritten now, deprecated
258-
def depolarizing(
258+
def depolarizing_reference(
259259
self,
260260
index: int,
261261
*,
@@ -321,6 +321,8 @@ def unitary_kraus2(
321321
status: Optional[float] = None,
322322
name: Optional[str] = None,
323323
) -> Tensor:
324+
# dont use, has issue conflicting with vmap, concurrent access lock emerged
325+
# potential issue raised from switch
324326
# general impl from Monte Carlo trajectory depolarizing above
325327
# still jittable
326328
# speed is similar to ``unitary_kraus``
@@ -545,7 +547,7 @@ def calculate_kraus_p(i: int) -> Tensor:
545547
for w, k in zip(prob, kraus_tensor)
546548
]
547549

548-
return self.unitary_kraus2(
550+
return self.unitary_kraus(
549551
new_kraus, *index, prob=prob, status=status, name=name
550552
)
551553

@@ -579,7 +581,7 @@ def general_kraus(
579581

580582
@staticmethod
581583
def apply_general_kraus_delayed(
582-
krausf: Callable[..., Sequence[Gate]]
584+
krausf: Callable[..., Sequence[Gate]], is_unitary: bool = False
583585
) -> Callable[..., None]:
584586
def apply(
585587
self: "Circuit",
@@ -589,17 +591,26 @@ def apply(
589591
**vars: float,
590592
) -> None:
591593
kraus = krausf(**vars)
592-
self.apply_general_kraus(kraus, *index, status=status, name=name)
594+
if not is_unitary:
595+
self.apply_general_kraus(kraus, *index, status=status, name=name)
596+
else:
597+
self.unitary_kraus(kraus, *index, status=status, name=name)
593598

594599
return apply
595600

596601
@classmethod
597602
def _meta_apply_channels(cls) -> None:
598603
for k in channels.channels:
604+
if k in ["depolarizing", "generaldepolarizing"]:
605+
is_unitary = True
606+
else:
607+
is_unitary = False
599608
setattr(
600609
cls,
601610
k,
602-
cls.apply_general_kraus_delayed(getattr(channels, k + "channel")),
611+
cls.apply_general_kraus_delayed(
612+
getattr(channels, k + "channel"), is_unitary=is_unitary
613+
),
603614
)
604615
doc = """
605616
Apply %s quantum channel on the circuit.

0 commit comments

Comments
 (0)