tensorcircuit-nightly 1.0.2.dev20250108__py3-none-any.whl → 1.4.0.dev20251103__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tensorcircuit-nightly might be problematic. Click here for more details.
- tensorcircuit/__init__.py +18 -2
- tensorcircuit/about.py +46 -0
- tensorcircuit/abstractcircuit.py +4 -0
- tensorcircuit/analogcircuit.py +413 -0
- tensorcircuit/applications/layers.py +1 -1
- tensorcircuit/applications/van.py +1 -1
- tensorcircuit/backends/abstract_backend.py +320 -7
- tensorcircuit/backends/cupy_backend.py +3 -1
- tensorcircuit/backends/jax_backend.py +102 -4
- tensorcircuit/backends/jax_ops.py +110 -1
- tensorcircuit/backends/numpy_backend.py +49 -3
- tensorcircuit/backends/pytorch_backend.py +92 -3
- tensorcircuit/backends/tensorflow_backend.py +102 -3
- tensorcircuit/basecircuit.py +157 -98
- tensorcircuit/circuit.py +115 -57
- tensorcircuit/cloud/local.py +1 -1
- tensorcircuit/cloud/quafu_provider.py +1 -1
- tensorcircuit/cloud/tencent.py +1 -1
- tensorcircuit/compiler/simple_compiler.py +2 -2
- tensorcircuit/cons.py +142 -21
- tensorcircuit/densitymatrix.py +43 -14
- tensorcircuit/experimental.py +387 -129
- tensorcircuit/fgs.py +282 -81
- tensorcircuit/gates.py +66 -22
- tensorcircuit/interfaces/__init__.py +1 -3
- tensorcircuit/interfaces/jax.py +189 -0
- tensorcircuit/keras.py +3 -3
- tensorcircuit/mpscircuit.py +154 -65
- tensorcircuit/quantum.py +868 -152
- tensorcircuit/quditcircuit.py +733 -0
- tensorcircuit/quditgates.py +618 -0
- tensorcircuit/results/counts.py +147 -20
- tensorcircuit/results/readout_mitigation.py +4 -1
- tensorcircuit/shadows.py +1 -1
- tensorcircuit/simplify.py +3 -1
- tensorcircuit/stabilizercircuit.py +479 -0
- tensorcircuit/templates/__init__.py +2 -0
- tensorcircuit/templates/blocks.py +2 -2
- tensorcircuit/templates/hamiltonians.py +174 -0
- tensorcircuit/templates/lattice.py +1789 -0
- tensorcircuit/timeevol.py +896 -0
- tensorcircuit/translation.py +10 -3
- tensorcircuit/utils.py +7 -0
- {tensorcircuit_nightly-1.0.2.dev20250108.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/METADATA +73 -23
- tensorcircuit_nightly-1.4.0.dev20251103.dist-info/RECORD +96 -0
- {tensorcircuit_nightly-1.0.2.dev20250108.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/WHEEL +1 -1
- {tensorcircuit_nightly-1.0.2.dev20250108.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info}/top_level.txt +0 -1
- tensorcircuit_nightly-1.0.2.dev20250108.dist-info/RECORD +0 -115
- tests/__init__.py +0 -0
- tests/conftest.py +0 -67
- tests/test_backends.py +0 -1031
- tests/test_calibrating.py +0 -149
- tests/test_channels.py +0 -365
- tests/test_circuit.py +0 -1699
- tests/test_cloud.py +0 -219
- tests/test_compiler.py +0 -147
- tests/test_dmcircuit.py +0 -555
- tests/test_ensemble.py +0 -72
- tests/test_fgs.py +0 -310
- tests/test_gates.py +0 -156
- tests/test_interfaces.py +0 -429
- tests/test_keras.py +0 -160
- tests/test_miscs.py +0 -277
- tests/test_mpscircuit.py +0 -341
- tests/test_noisemodel.py +0 -156
- tests/test_qaoa.py +0 -86
- tests/test_qem.py +0 -152
- tests/test_quantum.py +0 -526
- tests/test_quantum_attr.py +0 -42
- tests/test_results.py +0 -347
- tests/test_shadows.py +0 -160
- tests/test_simplify.py +0 -46
- tests/test_templates.py +0 -218
- tests/test_torchnn.py +0 -99
- tests/test_van.py +0 -102
- {tensorcircuit_nightly-1.0.2.dev20250108.dist-info → tensorcircuit_nightly-1.4.0.dev20251103.dist-info/licenses}/LICENSE +0 -0
tensorcircuit/densitymatrix.py
CHANGED
|
@@ -17,7 +17,7 @@ from .channels import kraus_to_super_gate
|
|
|
17
17
|
from .circuit import Circuit
|
|
18
18
|
from .cons import backend, contractor, dtypestr
|
|
19
19
|
from .basecircuit import BaseCircuit
|
|
20
|
-
from .quantum import QuOperator
|
|
20
|
+
from .quantum import QuOperator, _infer_num_sites
|
|
21
21
|
|
|
22
22
|
Gate = gates.Gate
|
|
23
23
|
Tensor = Any
|
|
@@ -35,9 +35,11 @@ class DMCircuit(BaseCircuit):
|
|
|
35
35
|
dminputs: Optional[Tensor] = None,
|
|
36
36
|
mpo_dminputs: Optional[QuOperator] = None,
|
|
37
37
|
split: Optional[Dict[str, Any]] = None,
|
|
38
|
+
dim: Optional[int] = None,
|
|
38
39
|
) -> None:
|
|
39
40
|
"""
|
|
40
41
|
The density matrix simulator based on tensornetwork engine.
|
|
42
|
+
Do not use this class with d!=2 directly
|
|
41
43
|
|
|
42
44
|
:param nqubits: Number of qubits
|
|
43
45
|
:type nqubits: int
|
|
@@ -55,6 +57,7 @@ class DMCircuit(BaseCircuit):
|
|
|
55
57
|
``max_singular_values`` and ``max_truncation_err``.
|
|
56
58
|
:type split: Optional[Dict[str, Any]]
|
|
57
59
|
"""
|
|
60
|
+
self._d = 2 if dim is None else dim
|
|
58
61
|
if not empty:
|
|
59
62
|
if (
|
|
60
63
|
(inputs is None)
|
|
@@ -73,9 +76,9 @@ class DMCircuit(BaseCircuit):
|
|
|
73
76
|
inputs = backend.cast(inputs, dtype=dtypestr)
|
|
74
77
|
inputs = backend.reshape(inputs, [-1])
|
|
75
78
|
N = inputs.shape[0]
|
|
76
|
-
n =
|
|
79
|
+
n = _infer_num_sites(N, self._d)
|
|
77
80
|
assert n == nqubits
|
|
78
|
-
inputs = backend.reshape(inputs, [
|
|
81
|
+
inputs = backend.reshape(inputs, [self._d for _ in range(n)])
|
|
79
82
|
inputs_gate = Gate(inputs)
|
|
80
83
|
self._nodes = [inputs_gate]
|
|
81
84
|
self.coloring_nodes(self._nodes)
|
|
@@ -94,7 +97,9 @@ class DMCircuit(BaseCircuit):
|
|
|
94
97
|
elif dminputs is not None:
|
|
95
98
|
dminputs = backend.convert_to_tensor(dminputs)
|
|
96
99
|
dminputs = backend.cast(dminputs, dtype=dtypestr)
|
|
97
|
-
dminputs = backend.reshape(
|
|
100
|
+
dminputs = backend.reshape(
|
|
101
|
+
dminputs, [self._d for _ in range(2 * nqubits)]
|
|
102
|
+
)
|
|
98
103
|
dminputs_gate = Gate(dminputs)
|
|
99
104
|
nodes = [dminputs_gate]
|
|
100
105
|
self._front = [dminputs_gate.get_edge(i) for i in range(2 * nqubits)]
|
|
@@ -173,14 +178,39 @@ class DMCircuit(BaseCircuit):
|
|
|
173
178
|
self._nodes = [t]
|
|
174
179
|
|
|
175
180
|
@staticmethod
|
|
176
|
-
def check_kraus(kraus: Sequence[Gate]) -> bool:
|
|
181
|
+
def check_kraus(kraus: Sequence[Gate]) -> bool:
|
|
182
|
+
r"""
|
|
183
|
+
Check if Kraus operators satisfy the completeness relation:
|
|
184
|
+
:math:`\sum_i K_i^\dagger K_i = I`
|
|
185
|
+
|
|
186
|
+
:param kraus: Sequence of Kraus operators
|
|
187
|
+
:type kraus: Sequence[Gate]
|
|
188
|
+
:return: True if completeness relation is satisfied within tolerance
|
|
189
|
+
:rtype: bool
|
|
190
|
+
:raises ValueError: If completeness relation is not satisfied
|
|
191
|
+
"""
|
|
192
|
+
# Convert all operators to tensors and get their shape
|
|
193
|
+
k_tensors = [k.tensor if isinstance(k, tn.Node) else k for k in kraus]
|
|
194
|
+
shape = k_tensors[0].shape
|
|
195
|
+
dim = shape[0] # Assuming square matrices
|
|
196
|
+
|
|
197
|
+
# Sum K_i K_i^†
|
|
198
|
+
sum_kk = backend.zeros([dim, dim], dtype=k_tensors[0].dtype)
|
|
199
|
+
for k in k_tensors:
|
|
200
|
+
kdag = backend.conj(backend.transpose(k))
|
|
201
|
+
sum_kk = sum_kk + backend.matmul(kdag, k)
|
|
202
|
+
|
|
203
|
+
# Check if sum equals identity within tolerance
|
|
204
|
+
identity = backend.eye(dim, dtype=sum_kk.dtype)
|
|
205
|
+
if not np.allclose(sum_kk, identity, atol=1e-5):
|
|
206
|
+
raise ValueError("Kraus operators do not satisfy completeness relation")
|
|
207
|
+
|
|
177
208
|
return True
|
|
178
209
|
|
|
179
210
|
def apply_general_kraus(
|
|
180
211
|
self, kraus: Sequence[Gate], index: Sequence[Tuple[int, ...]], **kws: Any
|
|
181
212
|
) -> None:
|
|
182
213
|
# note the API difference for index arg between DM and DM2
|
|
183
|
-
self.check_kraus(kraus)
|
|
184
214
|
assert len(kraus) == len(index) or len(index) == 1
|
|
185
215
|
if len(index) == 1:
|
|
186
216
|
index = [index[0] for _ in range(len(kraus))]
|
|
@@ -192,7 +222,7 @@ class DMCircuit(BaseCircuit):
|
|
|
192
222
|
dd = dmc.densitymatrix()
|
|
193
223
|
circuits.append(dd)
|
|
194
224
|
tensor = reduce(add, circuits)
|
|
195
|
-
tensor = backend.
|
|
225
|
+
tensor = backend.reshaped(tensor, d=self._d)
|
|
196
226
|
self._nodes = [Gate(tensor)]
|
|
197
227
|
dangling = [e for e in self._nodes[0]]
|
|
198
228
|
self._front = dangling
|
|
@@ -202,7 +232,7 @@ class DMCircuit(BaseCircuit):
|
|
|
202
232
|
|
|
203
233
|
@staticmethod
|
|
204
234
|
def apply_general_kraus_delayed(
|
|
205
|
-
krausf: Callable[..., Sequence[Gate]]
|
|
235
|
+
krausf: Callable[..., Sequence[Gate]],
|
|
206
236
|
) -> Callable[..., None]:
|
|
207
237
|
def apply(self: "DMCircuit", *index: int, **vars: float) -> None:
|
|
208
238
|
for key in ["status", "name"]:
|
|
@@ -230,7 +260,7 @@ class DMCircuit(BaseCircuit):
|
|
|
230
260
|
t = contractor(nodes, output_edge_order=d_edges)
|
|
231
261
|
else:
|
|
232
262
|
t = nodes[0]
|
|
233
|
-
dm = backend.
|
|
263
|
+
dm = backend.reshapem(t.tensor)
|
|
234
264
|
if check:
|
|
235
265
|
self.check_density_matrix(dm)
|
|
236
266
|
return dm
|
|
@@ -249,7 +279,7 @@ class DMCircuit(BaseCircuit):
|
|
|
249
279
|
dm = self.densitymatrix()
|
|
250
280
|
e, v = backend.eigh(dm)
|
|
251
281
|
np.testing.assert_allclose(
|
|
252
|
-
e[:-1], backend.zeros([
|
|
282
|
+
e[:-1], backend.zeros([self._d**self._nqubits - 1]), atol=1e-5
|
|
253
283
|
)
|
|
254
284
|
return v[:, -1]
|
|
255
285
|
|
|
@@ -272,7 +302,7 @@ class DMCircuit(BaseCircuit):
|
|
|
272
302
|
reuse: bool = True,
|
|
273
303
|
noise_conf: Optional[Any] = None,
|
|
274
304
|
status: Optional[Tensor] = None,
|
|
275
|
-
**kws: Any
|
|
305
|
+
**kws: Any,
|
|
276
306
|
) -> tn.Node.tensor:
|
|
277
307
|
"""
|
|
278
308
|
Compute the expectation of corresponding operators.
|
|
@@ -341,7 +371,6 @@ class DMCircuit2(DMCircuit):
|
|
|
341
371
|
)
|
|
342
372
|
for k in kraus
|
|
343
373
|
]
|
|
344
|
-
self.check_kraus(kraus)
|
|
345
374
|
if not isinstance(
|
|
346
375
|
index[0], int
|
|
347
376
|
): # try best to be compatible with DMCircuit interface
|
|
@@ -351,7 +380,7 @@ class DMCircuit2(DMCircuit):
|
|
|
351
380
|
# index = [index[0] for _ in range(len(kraus))]
|
|
352
381
|
super_op = kraus_to_super_gate(kraus)
|
|
353
382
|
nlegs = 4 * len(index)
|
|
354
|
-
super_op = backend.reshape(super_op, [
|
|
383
|
+
super_op = backend.reshape(super_op, [self._d for _ in range(nlegs)])
|
|
355
384
|
super_op = Gate(super_op)
|
|
356
385
|
o2i = int(nlegs / 2)
|
|
357
386
|
r2l = int(nlegs / 4)
|
|
@@ -367,7 +396,7 @@ class DMCircuit2(DMCircuit):
|
|
|
367
396
|
|
|
368
397
|
@staticmethod
|
|
369
398
|
def apply_general_kraus_delayed(
|
|
370
|
-
krausf: Callable[..., Sequence[Gate]]
|
|
399
|
+
krausf: Callable[..., Sequence[Gate]],
|
|
371
400
|
) -> Callable[..., None]:
|
|
372
401
|
def apply(self: "DMCircuit2", *index: int, **vars: float) -> None:
|
|
373
402
|
for key in ["status", "name"]:
|