tensorcircuit-nightly 1.2.1.dev20250725__py3-none-any.whl → 1.3.0.dev20250727__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 +1 -1
- tensorcircuit/backends/jax_backend.py +8 -1
- tensorcircuit/circuit.py +48 -0
- tensorcircuit/cons.py +60 -2
- tensorcircuit/fgs.py +254 -72
- tensorcircuit/mpscircuit.py +45 -4
- tensorcircuit/results/counts.py +99 -0
- tensorcircuit/stabilizercircuit.py +25 -15
- tensorcircuit/templates/__init__.py +1 -0
- tensorcircuit/templates/hamiltonians.py +153 -0
- tensorcircuit/utils.py +7 -0
- {tensorcircuit_nightly-1.2.1.dev20250725.dist-info → tensorcircuit_nightly-1.3.0.dev20250727.dist-info}/METADATA +2 -2
- {tensorcircuit_nightly-1.2.1.dev20250725.dist-info → tensorcircuit_nightly-1.3.0.dev20250727.dist-info}/RECORD +22 -20
- tests/test_circuit.py +13 -0
- tests/test_dmcircuit.py +1 -1
- tests/test_fgs.py +8 -0
- tests/test_hamiltonians.py +159 -0
- tests/test_miscs.py +20 -0
- tests/test_stabilizer.py +9 -0
- {tensorcircuit_nightly-1.2.1.dev20250725.dist-info → tensorcircuit_nightly-1.3.0.dev20250727.dist-info}/WHEEL +0 -0
- {tensorcircuit_nightly-1.2.1.dev20250725.dist-info → tensorcircuit_nightly-1.3.0.dev20250727.dist-info}/licenses/LICENSE +0 -0
- {tensorcircuit_nightly-1.2.1.dev20250725.dist-info → tensorcircuit_nightly-1.3.0.dev20250727.dist-info}/top_level.txt +0 -0
tensorcircuit/results/counts.py
CHANGED
|
@@ -12,6 +12,19 @@ ct = Dict[str, int]
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def reverse_count(count: ct) -> ct:
|
|
15
|
+
"""
|
|
16
|
+
Reverse the bit string keys in a count dictionary.
|
|
17
|
+
|
|
18
|
+
:param count: A dictionary mapping bit strings to counts
|
|
19
|
+
:type count: ct
|
|
20
|
+
:return: A new dictionary with reversed bit string keys
|
|
21
|
+
:rtype: ct
|
|
22
|
+
|
|
23
|
+
:Example:
|
|
24
|
+
|
|
25
|
+
>>> reverse_count({"01": 10, "10": 20})
|
|
26
|
+
{'10': 10, '01': 20}
|
|
27
|
+
"""
|
|
15
28
|
ncount = {}
|
|
16
29
|
for k, v in count.items():
|
|
17
30
|
ncount[k[::-1]] = v
|
|
@@ -19,15 +32,56 @@ def reverse_count(count: ct) -> ct:
|
|
|
19
32
|
|
|
20
33
|
|
|
21
34
|
def sort_count(count: ct) -> ct:
|
|
35
|
+
"""
|
|
36
|
+
Sort the count dictionary by counts in descending order.
|
|
37
|
+
|
|
38
|
+
:param count: A dictionary mapping bit strings to counts
|
|
39
|
+
:type count: ct
|
|
40
|
+
:return: A new dictionary sorted by count values (descending)
|
|
41
|
+
:rtype: ct
|
|
42
|
+
|
|
43
|
+
:Example:
|
|
44
|
+
|
|
45
|
+
>>> sort_count({"00": 5, "01": 15, "10": 10})
|
|
46
|
+
{'01': 15, '10': 10, '00': 5}
|
|
47
|
+
"""
|
|
22
48
|
return {k: v for k, v in sorted(count.items(), key=lambda item: -item[1])}
|
|
23
49
|
|
|
24
50
|
|
|
25
51
|
def normalized_count(count: ct) -> Dict[str, float]:
|
|
52
|
+
"""
|
|
53
|
+
Normalize the count dictionary to represent probabilities.
|
|
54
|
+
|
|
55
|
+
:param count: A dictionary mapping bit strings to counts
|
|
56
|
+
:type count: ct
|
|
57
|
+
:return: A new dictionary with probabilities instead of counts
|
|
58
|
+
:rtype: Dict[str, float]
|
|
59
|
+
|
|
60
|
+
:Example:
|
|
61
|
+
|
|
62
|
+
>>> normalized_count({"00": 5, "01": 15})
|
|
63
|
+
{'00': 0.25, '01': 0.75}
|
|
64
|
+
"""
|
|
26
65
|
shots = sum([v for k, v in count.items()])
|
|
27
66
|
return {k: v / shots for k, v in count.items()}
|
|
28
67
|
|
|
29
68
|
|
|
30
69
|
def marginal_count(count: ct, keep_list: Sequence[int]) -> ct:
|
|
70
|
+
"""
|
|
71
|
+
Compute the marginal distribution of a count dictionary over specified qubits.
|
|
72
|
+
|
|
73
|
+
:param count: A dictionary mapping bit strings to counts
|
|
74
|
+
:type count: ct
|
|
75
|
+
:param keep_list: List of qubit indices to keep in the marginal distribution
|
|
76
|
+
:type keep_list: Sequence[int]
|
|
77
|
+
:return: A new count dictionary with marginal distribution
|
|
78
|
+
:rtype: ct
|
|
79
|
+
|
|
80
|
+
:Example:
|
|
81
|
+
|
|
82
|
+
>>> marginal_count({"001": 10, "110": 20}, [0, 2])
|
|
83
|
+
{'01': 10, '10': 20}
|
|
84
|
+
"""
|
|
31
85
|
import qiskit
|
|
32
86
|
|
|
33
87
|
count = reverse_count(count)
|
|
@@ -36,6 +90,21 @@ def marginal_count(count: ct, keep_list: Sequence[int]) -> ct:
|
|
|
36
90
|
|
|
37
91
|
|
|
38
92
|
def count2vec(count: ct, normalization: bool = True) -> Tensor:
|
|
93
|
+
"""
|
|
94
|
+
Convert count dictionary to probability vector.
|
|
95
|
+
|
|
96
|
+
:param count: A dictionary mapping bit strings to counts
|
|
97
|
+
:type count: ct
|
|
98
|
+
:param normalization: Whether to normalize the counts to probabilities, defaults to True
|
|
99
|
+
:type normalization: bool, optional
|
|
100
|
+
:return: Probability vector as numpy array
|
|
101
|
+
:rtype: Tensor
|
|
102
|
+
|
|
103
|
+
:Example:
|
|
104
|
+
|
|
105
|
+
>>> count2vec({"00": 2, "10": 3, "11": 5})
|
|
106
|
+
array([0.2, 0. , 0.3, 0.5])
|
|
107
|
+
"""
|
|
39
108
|
nqubit = len(list(count.keys())[0])
|
|
40
109
|
probability = [0] * 2**nqubit
|
|
41
110
|
shots = sum([v for k, v in count.items()])
|
|
@@ -47,6 +116,21 @@ def count2vec(count: ct, normalization: bool = True) -> Tensor:
|
|
|
47
116
|
|
|
48
117
|
|
|
49
118
|
def vec2count(vec: Tensor, prune: bool = False) -> ct:
|
|
119
|
+
"""
|
|
120
|
+
Convert probability vector to count dictionary.
|
|
121
|
+
|
|
122
|
+
:param vec: Probability vector
|
|
123
|
+
:type vec: Tensor
|
|
124
|
+
:param prune: Whether to remove near-zero probabilities, defaults to False
|
|
125
|
+
:type prune: bool, optional
|
|
126
|
+
:return: Count dictionary
|
|
127
|
+
:rtype: ct
|
|
128
|
+
|
|
129
|
+
:Example:
|
|
130
|
+
|
|
131
|
+
>>> vec2count(np.array([0.2, 0.3, 0.1, 0.4]))
|
|
132
|
+
{'00': 0.2, '01': 0.3, '10': 0.1, '11': 0.4}
|
|
133
|
+
"""
|
|
50
134
|
from ..quantum import count_vector2dict
|
|
51
135
|
|
|
52
136
|
if isinstance(vec, list):
|
|
@@ -63,6 +147,16 @@ def vec2count(vec: Tensor, prune: bool = False) -> ct:
|
|
|
63
147
|
|
|
64
148
|
|
|
65
149
|
def kl_divergence(c1: ct, c2: ct) -> float:
|
|
150
|
+
"""
|
|
151
|
+
Compute the Kullback-Leibler divergence between two count distributions.
|
|
152
|
+
|
|
153
|
+
:param c1: First count dictionary
|
|
154
|
+
:type c1: ct
|
|
155
|
+
:param c2: Second count dictionary
|
|
156
|
+
:type c2: ct
|
|
157
|
+
:return: KL divergence value
|
|
158
|
+
:rtype: float
|
|
159
|
+
"""
|
|
66
160
|
eps = 1e-4 # typical value for inverse of the total shots
|
|
67
161
|
c1 = normalized_count(c1) # type: ignore
|
|
68
162
|
c2 = normalized_count(c2) # type: ignore
|
|
@@ -113,6 +207,11 @@ def merge_count(*counts: ct) -> ct:
|
|
|
113
207
|
:type counts: ct
|
|
114
208
|
:return: Merged count dictionary
|
|
115
209
|
:rtype: ct
|
|
210
|
+
|
|
211
|
+
:Example:
|
|
212
|
+
|
|
213
|
+
>>> merge_count({"00": 10, "01": 20}, {"00": 5, "10": 15})
|
|
214
|
+
{'00': 15, '01': 20, '10': 15}
|
|
116
215
|
"""
|
|
117
216
|
merged: ct = {}
|
|
118
217
|
for count in counts:
|
|
@@ -147,14 +147,16 @@ class StabilizerCircuit(AbstractCircuit):
|
|
|
147
147
|
|
|
148
148
|
def measure(self, *index: int, with_prob: bool = False) -> Tensor:
|
|
149
149
|
"""
|
|
150
|
-
Measure qubits in Z basis.
|
|
150
|
+
Measure qubits in the Z basis.
|
|
151
151
|
|
|
152
|
-
:param index: Indices of qubits to measure
|
|
152
|
+
:param index: Indices of the qubits to measure.
|
|
153
153
|
:type index: int
|
|
154
|
-
:param with_prob:
|
|
154
|
+
:param with_prob: If True, returns the theoretical probability of the measurement outcome.
|
|
155
|
+
defaults to False
|
|
155
156
|
:type with_prob: bool, optional
|
|
156
|
-
:return:
|
|
157
|
-
|
|
157
|
+
:return: A tensor containing the measurement results.
|
|
158
|
+
If `with_prob` is True, a tuple containing the results and the probability is returned.
|
|
159
|
+
:rtype: Tensor
|
|
158
160
|
"""
|
|
159
161
|
# Convert negative indices
|
|
160
162
|
|
|
@@ -162,20 +164,28 @@ class StabilizerCircuit(AbstractCircuit):
|
|
|
162
164
|
|
|
163
165
|
# Add measurement instructions
|
|
164
166
|
s1 = self.current_simulator().copy()
|
|
165
|
-
m = s1.measure_many(*index)
|
|
166
167
|
# Sample once from the circuit using sampler
|
|
167
168
|
|
|
168
|
-
|
|
169
|
+
if with_prob:
|
|
170
|
+
num_random_measurements = 0
|
|
171
|
+
for i in index:
|
|
172
|
+
if s1.peek_z(i) == 0:
|
|
173
|
+
num_random_measurements += 1
|
|
174
|
+
probability = (0.5) ** num_random_measurements
|
|
175
|
+
|
|
176
|
+
m = s1.measure_many(*index)
|
|
177
|
+
if with_prob:
|
|
178
|
+
return m, probability
|
|
169
179
|
return m
|
|
170
180
|
|
|
171
181
|
def cond_measurement(self, index: int) -> Tensor:
|
|
172
182
|
"""
|
|
173
|
-
Measure
|
|
183
|
+
Measure a single qubit in the Z basis and collapse the state.
|
|
174
184
|
|
|
175
|
-
:param index:
|
|
185
|
+
:param index: The index of the qubit to measure.
|
|
176
186
|
:type index: int
|
|
177
|
-
:return:
|
|
178
|
-
:rtype:
|
|
187
|
+
:return: The measurement result (0 or 1).
|
|
188
|
+
:rtype: Tensor
|
|
179
189
|
"""
|
|
180
190
|
# Convert negative indices
|
|
181
191
|
|
|
@@ -191,12 +201,12 @@ class StabilizerCircuit(AbstractCircuit):
|
|
|
191
201
|
|
|
192
202
|
def cond_measure_many(self, *index: int) -> Tensor:
|
|
193
203
|
"""
|
|
194
|
-
Measure qubits in Z basis
|
|
204
|
+
Measure multiple qubits in the Z basis and collapse the state.
|
|
195
205
|
|
|
196
|
-
:param index:
|
|
206
|
+
:param index: The indices of the qubits to measure.
|
|
197
207
|
:type index: int
|
|
198
|
-
:return:
|
|
199
|
-
:rtype:
|
|
208
|
+
:return: A tensor containing the measurement results.
|
|
209
|
+
:rtype: Tensor
|
|
200
210
|
"""
|
|
201
211
|
# Convert negative indices
|
|
202
212
|
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
from typing import Any, List, Tuple, Union
|
|
2
|
+
import numpy as np
|
|
3
|
+
from ..cons import dtypestr, backend
|
|
4
|
+
from ..quantum import PauliStringSum2COO
|
|
5
|
+
from .lattice import AbstractLattice
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _create_empty_sparse_matrix(shape: Tuple[int, int]) -> Any:
|
|
9
|
+
"""
|
|
10
|
+
Helper function to create a backend-agnostic empty sparse matrix.
|
|
11
|
+
"""
|
|
12
|
+
indices = backend.convert_to_tensor(backend.zeros((0, 2), dtype="int32"))
|
|
13
|
+
values = backend.convert_to_tensor(backend.zeros((0,), dtype=dtypestr)) # type: ignore
|
|
14
|
+
return backend.coo_sparse_matrix(indices=indices, values=values, shape=shape) # type: ignore
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def heisenberg_hamiltonian(
|
|
18
|
+
lattice: AbstractLattice,
|
|
19
|
+
j_coupling: Union[float, List[float], Tuple[float, ...]] = 1.0,
|
|
20
|
+
) -> Any:
|
|
21
|
+
"""
|
|
22
|
+
Generates the sparse matrix of the Heisenberg Hamiltonian for a given lattice.
|
|
23
|
+
|
|
24
|
+
The Heisenberg Hamiltonian is defined as:
|
|
25
|
+
H = J * Σ_{<i,j>} (X_i X_j + Y_i Y_j + Z_i Z_j)
|
|
26
|
+
where the sum is over all unique nearest-neighbor pairs <i,j>.
|
|
27
|
+
|
|
28
|
+
:param lattice: An instance of a class derived from AbstractLattice,
|
|
29
|
+
which provides the geometric information of the system.
|
|
30
|
+
:type lattice: AbstractLattice
|
|
31
|
+
:param j_coupling: The coupling constants. Can be a single float for an
|
|
32
|
+
isotropic model (Jx=Jy=Jz) or a list/tuple of 3 floats for an
|
|
33
|
+
anisotropic model (Jx, Jy, Jz). Defaults to 1.0.
|
|
34
|
+
:type j_coupling: Union[float, List[float], Tuple[float, ...]], optional
|
|
35
|
+
:return: The Hamiltonian as a backend-agnostic sparse matrix.
|
|
36
|
+
:rtype: Any
|
|
37
|
+
"""
|
|
38
|
+
num_sites = lattice.num_sites
|
|
39
|
+
neighbor_pairs = lattice.get_neighbor_pairs(k=1, unique=True)
|
|
40
|
+
|
|
41
|
+
if isinstance(j_coupling, (float, int)):
|
|
42
|
+
js = [float(j_coupling)] * 3
|
|
43
|
+
else:
|
|
44
|
+
if len(j_coupling) != 3:
|
|
45
|
+
raise ValueError("j_coupling must be a float or a list/tuple of 3 floats.")
|
|
46
|
+
js = [float(j) for j in j_coupling]
|
|
47
|
+
|
|
48
|
+
if not neighbor_pairs:
|
|
49
|
+
return _create_empty_sparse_matrix(shape=(2**num_sites, 2**num_sites))
|
|
50
|
+
if num_sites == 0:
|
|
51
|
+
raise ValueError("Cannot generate a Hamiltonian for a lattice with zero sites.")
|
|
52
|
+
|
|
53
|
+
pauli_map = {"X": 1, "Y": 2, "Z": 3}
|
|
54
|
+
|
|
55
|
+
ls: List[List[int]] = []
|
|
56
|
+
weights: List[float] = []
|
|
57
|
+
|
|
58
|
+
pauli_terms = ["X", "Y", "Z"]
|
|
59
|
+
for i, j in neighbor_pairs:
|
|
60
|
+
for idx, pauli_char in enumerate(pauli_terms):
|
|
61
|
+
if abs(js[idx]) > 1e-9:
|
|
62
|
+
string = [0] * num_sites
|
|
63
|
+
string[i] = pauli_map[pauli_char]
|
|
64
|
+
string[j] = pauli_map[pauli_char]
|
|
65
|
+
ls.append(string)
|
|
66
|
+
weights.append(js[idx])
|
|
67
|
+
|
|
68
|
+
hamiltonian_matrix = PauliStringSum2COO(ls, weight=weights, numpy=False)
|
|
69
|
+
|
|
70
|
+
return hamiltonian_matrix
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def rydberg_hamiltonian(
|
|
74
|
+
lattice: AbstractLattice, omega: float, delta: float, c6: float
|
|
75
|
+
) -> Any:
|
|
76
|
+
"""
|
|
77
|
+
Generates the sparse matrix of the Rydberg atom array Hamiltonian.
|
|
78
|
+
|
|
79
|
+
The Hamiltonian is defined as:
|
|
80
|
+
H = Σ_i (Ω/2)X_i - Σ_i δ(1 - Z_i)/2 + Σ_{i<j} V_ij (1-Z_i)/2 (1-Z_j)/2
|
|
81
|
+
= Σ_i (Ω/2)X_i + Σ_i (δ/2)Z_i + Σ_{i<j} (V_ij/4)(Z_iZ_j - Z_i - Z_j)
|
|
82
|
+
where V_ij = C6 / |r_i - r_j|^6.
|
|
83
|
+
|
|
84
|
+
Note: Constant energy offset terms (proportional to the identity operator)
|
|
85
|
+
are ignored in this implementation.
|
|
86
|
+
|
|
87
|
+
:param lattice: An instance of a class derived from AbstractLattice,
|
|
88
|
+
which provides site coordinates and the distance matrix.
|
|
89
|
+
:type lattice: AbstractLattice
|
|
90
|
+
:param omega: The Rabi frequency (Ω) of the driving laser field.
|
|
91
|
+
:type omega: float
|
|
92
|
+
:param delta: The laser detuning (δ).
|
|
93
|
+
:type delta: float
|
|
94
|
+
:param c6: The Van der Waals interaction coefficient (C6).
|
|
95
|
+
:type c6: float
|
|
96
|
+
:return: The Hamiltonian as a backend-agnostic sparse matrix.
|
|
97
|
+
:rtype: Any
|
|
98
|
+
"""
|
|
99
|
+
num_sites = lattice.num_sites
|
|
100
|
+
if num_sites == 0:
|
|
101
|
+
raise ValueError("Cannot generate a Hamiltonian for a lattice with zero sites.")
|
|
102
|
+
|
|
103
|
+
pauli_map = {"X": 1, "Y": 2, "Z": 3}
|
|
104
|
+
ls: List[List[int]] = []
|
|
105
|
+
weights: List[float] = []
|
|
106
|
+
|
|
107
|
+
for i in range(num_sites):
|
|
108
|
+
x_string = [0] * num_sites
|
|
109
|
+
x_string[i] = pauli_map["X"]
|
|
110
|
+
ls.append(x_string)
|
|
111
|
+
weights.append(omega / 2.0)
|
|
112
|
+
|
|
113
|
+
z_coefficients = np.zeros(num_sites)
|
|
114
|
+
|
|
115
|
+
for i in range(num_sites):
|
|
116
|
+
z_coefficients[i] += delta / 2.0
|
|
117
|
+
|
|
118
|
+
dist_matrix = lattice.distance_matrix
|
|
119
|
+
|
|
120
|
+
for i in range(num_sites):
|
|
121
|
+
for j in range(i + 1, num_sites):
|
|
122
|
+
distance = dist_matrix[i, j]
|
|
123
|
+
|
|
124
|
+
if distance < 1e-9:
|
|
125
|
+
continue
|
|
126
|
+
|
|
127
|
+
interaction_strength = c6 / (distance**6)
|
|
128
|
+
coefficient = interaction_strength / 4.0
|
|
129
|
+
|
|
130
|
+
zz_string = [0] * num_sites
|
|
131
|
+
zz_string[i] = pauli_map["Z"]
|
|
132
|
+
zz_string[j] = pauli_map["Z"]
|
|
133
|
+
ls.append(zz_string)
|
|
134
|
+
weights.append(coefficient)
|
|
135
|
+
|
|
136
|
+
# The interaction term V_ij * n_i * n_j, when expanded using
|
|
137
|
+
# n_i = (1-Z_i)/2, becomes (V_ij/4)*(I - Z_i - Z_j + Z_i*Z_j).
|
|
138
|
+
# This contributes a positive term (+V_ij/4) to the ZZ interaction,
|
|
139
|
+
# but negative terms (-V_ij/4) to the single-site Z_i and Z_j operators.
|
|
140
|
+
|
|
141
|
+
z_coefficients[i] -= coefficient
|
|
142
|
+
z_coefficients[j] -= coefficient
|
|
143
|
+
|
|
144
|
+
for i in range(num_sites):
|
|
145
|
+
if abs(z_coefficients[i]) > 1e-9:
|
|
146
|
+
z_string = [0] * num_sites
|
|
147
|
+
z_string[i] = pauli_map["Z"]
|
|
148
|
+
ls.append(z_string)
|
|
149
|
+
weights.append(z_coefficients[i]) # type: ignore
|
|
150
|
+
|
|
151
|
+
hamiltonian_matrix = PauliStringSum2COO(ls, weight=weights, numpy=False)
|
|
152
|
+
|
|
153
|
+
return hamiltonian_matrix
|
tensorcircuit/utils.py
CHANGED
|
@@ -11,6 +11,13 @@ import time
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def gpu_memory_share(flag: bool = True) -> None:
|
|
14
|
+
"""
|
|
15
|
+
Set the GPU memory growth mode
|
|
16
|
+
|
|
17
|
+
:param flag: whether to set the GPU memory growth mode, defaults to True
|
|
18
|
+
:type flag: bool
|
|
19
|
+
:return: None
|
|
20
|
+
"""
|
|
14
21
|
# TODO(@refraction-ray): the default torch behavior should be True
|
|
15
22
|
# preallocate behavior for torch to be investigated
|
|
16
23
|
if flag is True:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tensorcircuit-nightly
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0.dev20250727
|
|
4
4
|
Summary: nightly release for tensorcircuit
|
|
5
5
|
Home-page: https://github.com/refraction-ray/tensorcircuit-dev
|
|
6
6
|
Author: TensorCircuit Authors
|
|
@@ -70,7 +70,7 @@ TensorCircuit-NG is the actively maintained official version and a [fully compat
|
|
|
70
70
|
|
|
71
71
|
Please begin with [Quick Start](/docs/source/quickstart.rst) in the [full documentation](https://tensorcircuit-ng.readthedocs.io/).
|
|
72
72
|
|
|
73
|
-
For more information on software usage, sota algorithm implementation and engineer paradigm demonstration, please refer to 80+ [example scripts](/examples) and 30+ [tutorial notebooks](https://tensorcircuit-ng.readthedocs.io/en/latest/#tutorials). API docstrings and test cases in [tests](/tests) are also informative. One can also refer to tensorcircuit-ng [deepwiki](https://deepwiki.com/tensorcircuit/tensorcircuit-ng)
|
|
73
|
+
For more information on software usage, sota algorithm implementation and engineer paradigm demonstration, please refer to 80+ [example scripts](/examples) and 30+ [tutorial notebooks](https://tensorcircuit-ng.readthedocs.io/en/latest/#tutorials). API docstrings and test cases in [tests](/tests) are also informative. One can also refer to tensorcircuit-ng [deepwiki](https://deepwiki.com/tensorcircuit/tensorcircuit-ng) or [Context7 MCP](https://context7.com/tensorcircuit/tensorcircuit-ng).
|
|
74
74
|
|
|
75
75
|
For beginners, please refer to [quantum computing lectures with TC-NG](https://github.com/sxzgroup/qc_lecture) to learn both quantum computing basics and representative usage of TensorCircuit-NG.
|
|
76
76
|
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
tensorcircuit/__init__.py,sha256=
|
|
1
|
+
tensorcircuit/__init__.py,sha256=OVdReKvSMFFosvmCxCnQlOZK_hVKpavJKAdDoChQ-is,2032
|
|
2
2
|
tensorcircuit/about.py,sha256=DazTswU2nAwOmASTaDII3L04PVtaQ7oiWPty5YMI3Wk,5267
|
|
3
3
|
tensorcircuit/abstractcircuit.py,sha256=0osacPqq7B1EJki-cI1aLYoVRmjFaG9q3XevWMs7SsA,44125
|
|
4
4
|
tensorcircuit/asciiart.py,sha256=neY1OWFwtoW5cHPNwkQHgRPktDniQvdlP9QKHkk52fM,8236
|
|
5
5
|
tensorcircuit/basecircuit.py,sha256=ipCg3J55sgkciUZ2qCZqpVqE00YIWRlACu509nktg3I,37203
|
|
6
6
|
tensorcircuit/channels.py,sha256=CFQxWI-JmkIxexslCBdjp_RSxUbHs6eAJv4LvlXXXCY,28637
|
|
7
|
-
tensorcircuit/circuit.py,sha256=
|
|
8
|
-
tensorcircuit/cons.py,sha256=
|
|
7
|
+
tensorcircuit/circuit.py,sha256=mE4b_9xRu3ydoB8iDffdx35V9GZLhAQD_tkjZDLnLjg,39105
|
|
8
|
+
tensorcircuit/cons.py,sha256=uYKBeYKkDoJEqJTNrOZPRM31tBtkqe5aAg8GtVidJ1Y,33014
|
|
9
9
|
tensorcircuit/densitymatrix.py,sha256=VqMBnWCxO5-OsOp6LOdc5RS2AzmB3U4-w40Vn_lqygo,14865
|
|
10
10
|
tensorcircuit/experimental.py,sha256=RW97ncitCfO1QJLAUbKBvm2Tsc0hzKhqkC65ShA9-Q0,34456
|
|
11
|
-
tensorcircuit/fgs.py,sha256=
|
|
11
|
+
tensorcircuit/fgs.py,sha256=pzaZuzPIFPpfr5Z-UsBQ_Yp0x7mbSM2sUc4dO2SUmVs,49543
|
|
12
12
|
tensorcircuit/gates.py,sha256=x-wA7adVpP7o0AQLt_xYUScFKj8tU_wUOV2mR1GyrPc,29322
|
|
13
13
|
tensorcircuit/keras.py,sha256=5OF4dfhEeS8sRYglpqYtQsWPeqp7uK0i7-P-6RRJ7zQ,10126
|
|
14
14
|
tensorcircuit/mps_base.py,sha256=UZ-v8vsr_rAsKrfun8prVgbXJ-qsdqKy2DZIHpq3sxo,15400
|
|
15
|
-
tensorcircuit/mpscircuit.py,sha256=
|
|
15
|
+
tensorcircuit/mpscircuit.py,sha256=COO9xzvA2Whe7Ncp6OqrgtXKmahHgTHxXTELAVHzFSY,36777
|
|
16
16
|
tensorcircuit/noisemodel.py,sha256=vzxpoYEZbHVC4a6g7_Jk4dxsHi4wvhpRFwud8b616Qo,11878
|
|
17
17
|
tensorcircuit/quantum.py,sha256=LNkIv5cJ2KG6puC18zTuXi-5cojW1Tnz-N-WjZ0Qu5Q,90217
|
|
18
18
|
tensorcircuit/shadows.py,sha256=6XmWNubbuaxFNvZVWu-RXd0lN9Jkk-xwong_K8o8_KE,17014
|
|
19
19
|
tensorcircuit/simplify.py,sha256=O11G3UYiVAc30GOfwXXmhLXwGZrQ8OVwLTMQMZp_XBc,9414
|
|
20
|
-
tensorcircuit/stabilizercircuit.py,sha256=
|
|
20
|
+
tensorcircuit/stabilizercircuit.py,sha256=yNqcEKtYzRYrgqGil8QEyKN4OEMp9g6uOG2zuRaU8uc,15465
|
|
21
21
|
tensorcircuit/torchnn.py,sha256=z_QpM0QC3mydGyWpyp877j-tSFCPyzynCwqrTWaw-IA,4637
|
|
22
22
|
tensorcircuit/translation.py,sha256=VnU7DnYmbk1cWjqa7N68WNLNDn3DwENrMzmbG4_CQco,28611
|
|
23
|
-
tensorcircuit/utils.py,sha256=
|
|
23
|
+
tensorcircuit/utils.py,sha256=nEDR1wTh1WF_yV6UyZYlifqOPWdKk_Krr4HjhrWHnGQ,7228
|
|
24
24
|
tensorcircuit/vis.py,sha256=O4hm050KKfOAoVyHsjpMg6NBNVoWhLSlv-xsCx4opsU,12196
|
|
25
25
|
tensorcircuit/applications/__init__.py,sha256=nAX-Am6JoL9k53iJ_CjZJ2NcjIpaz21H87nrW4Op03k,246
|
|
26
26
|
tensorcircuit/applications/dqas.py,sha256=RcIM-mHLcZ99U5oXQSBSVL36wfDoBe45kuaQageI_SQ,34463
|
|
@@ -42,7 +42,7 @@ tensorcircuit/backends/__init__.py,sha256=WiUmbUFzM29w3hKfhuKxVUk3PpqDFiXf4za9g0
|
|
|
42
42
|
tensorcircuit/backends/abstract_backend.py,sha256=Ob8zp-AgovoY3uYFNEUA_WlJz9YtgnaJvugKUXWttAA,59018
|
|
43
43
|
tensorcircuit/backends/backend_factory.py,sha256=Z0aQ-RnxOnQzp-SRw8sefAH8XyBSlj2NXZwOlHinbfY,1713
|
|
44
44
|
tensorcircuit/backends/cupy_backend.py,sha256=4vgO3lnQnsvWL5hukhskjJp37EAHqio6z6TVXTQcdjs,15077
|
|
45
|
-
tensorcircuit/backends/jax_backend.py,sha256=
|
|
45
|
+
tensorcircuit/backends/jax_backend.py,sha256=dkDQ380CJHIdlt1fZvlN_g8DIowWPEcTTV_XBcs0YB0,26088
|
|
46
46
|
tensorcircuit/backends/jax_ops.py,sha256=o7tLlQMRnaKWcr5rVnOMqwG6KZVpR8M8ryNQ-ceXVxs,4789
|
|
47
47
|
tensorcircuit/backends/numpy_backend.py,sha256=sd1migp_E2FWjchvOeYRuyM47yexegT2_SW_ukSYSF8,14171
|
|
48
48
|
tensorcircuit/backends/pytorch_backend.py,sha256=yhfZSrm99yNW-dmijk8t6zAkbVgLRd4b_aIWKrpT7bY,24230
|
|
@@ -70,37 +70,39 @@ tensorcircuit/interfaces/tensorflow.py,sha256=U4hZjm-yWxOJ5tqmffk8-tNvOkAltYBJ8Z
|
|
|
70
70
|
tensorcircuit/interfaces/tensortrans.py,sha256=oUxIVpXfANZVRXfPjiGJDzFPiszfBsiY40ydh0BaELE,10364
|
|
71
71
|
tensorcircuit/interfaces/torch.py,sha256=13IFGmWUFoWiSzKAzwp2EkOSxgiwN_oUFxjQb36gimo,5149
|
|
72
72
|
tensorcircuit/results/__init__.py,sha256=3kkIvmjLYQd5ff-emY8l82rpv9mwMZdM2kTLZ9sNfA4,89
|
|
73
|
-
tensorcircuit/results/counts.py,sha256=
|
|
73
|
+
tensorcircuit/results/counts.py,sha256=6Dw7SVwnahcLnVlhcU4RfES1CqH2ZVdt0bGeUTYaij8,6512
|
|
74
74
|
tensorcircuit/results/readout_mitigation.py,sha256=dVpNvtFZe7n_fDVczKcqYPEepu3fV2qK3u-SfOpTf68,31746
|
|
75
75
|
tensorcircuit/results/qem/__init__.py,sha256=Pw0hcFYNesuPE8uNDm9P8DVTIFCSBqUcIkr6smQYzuM,419
|
|
76
76
|
tensorcircuit/results/qem/benchmark_circuits.py,sha256=LlFuKCDFKihMOhiY6WUZt9QPyoPeQw0SuaczdcSA3oM,3243
|
|
77
77
|
tensorcircuit/results/qem/qem_methods.py,sha256=v8HyVsRX9vkjgGfLyB1K0Eq5UyUnh-thysqo05kXo6E,12148
|
|
78
|
-
tensorcircuit/templates/__init__.py,sha256=
|
|
78
|
+
tensorcircuit/templates/__init__.py,sha256=CzkNn6sAk9gkXYa0IemrsISXIqcaIqM2UWvGi2u2C38,237
|
|
79
79
|
tensorcircuit/templates/ansatz.py,sha256=0hmMtdSvHq9qodzpzC0TKJIWV28kTlfZqzUHjBd9aYA,3229
|
|
80
80
|
tensorcircuit/templates/blocks.py,sha256=xUzL7TVL8ym_sGV9NJ40_9x2c2pBjh2CevO8aCj9WzA,6183
|
|
81
81
|
tensorcircuit/templates/chems.py,sha256=9ksMYTutfDEF3U04xrj9j0bYWb5gwTwMdMPi-SZKci0,171
|
|
82
82
|
tensorcircuit/templates/conversions.py,sha256=D3chiKDr7G1ekCJngiol91k9iqrMag1DZQGSx0j_uH4,3023
|
|
83
83
|
tensorcircuit/templates/dataset.py,sha256=ldPvCUlwjHU_S98E2ISQp34KqJzJPpPHmDIKJ4K-qYo,1933
|
|
84
84
|
tensorcircuit/templates/graphs.py,sha256=cPYrxjoem0xZ-Is9dZKAvEzWZL_FejfIRiCEOTA4qd4,3935
|
|
85
|
+
tensorcircuit/templates/hamiltonians.py,sha256=Ag8djD6lckTeU7I99gCbXiQAb2VYqzm_p7-hpXo-5u4,5554
|
|
85
86
|
tensorcircuit/templates/lattice.py,sha256=F35ebANk0DSmSHLR0-Q_hUbcznyCmZjb4fKmvCMywmA,58575
|
|
86
87
|
tensorcircuit/templates/measurements.py,sha256=pzc5Aa9S416Ilg4aOY77Z6ZhUlYcXnAkQNQFTuHjFFs,10943
|
|
87
|
-
tensorcircuit_nightly-1.
|
|
88
|
+
tensorcircuit_nightly-1.3.0.dev20250727.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
88
89
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
89
90
|
tests/conftest.py,sha256=J9nHlLE3Zspz1rMyzadEuBWhaS5I4Q9sq0lnWybcdIA,1457
|
|
90
91
|
tests/test_backends.py,sha256=rClxb2gyAoGeXd_ZYVSAJ0zEvJ7z_2btAeFM_Iy_wwY,33925
|
|
91
92
|
tests/test_calibrating.py,sha256=D1Tlv8mucUhg3ULvB5QlYyaDfw7aEERwq69-aGSb1A4,3805
|
|
92
93
|
tests/test_channels.py,sha256=BL4CirU8ku9-_NrI6PZAS5xZ0wrL1UEC1S3wPI9dYQM,12628
|
|
93
|
-
tests/test_circuit.py,sha256=
|
|
94
|
+
tests/test_circuit.py,sha256=IsSIFEs7hUCSYexMb-ESt1ZUpztHtLA0qz0CZolGdc4,52240
|
|
94
95
|
tests/test_cloud.py,sha256=241ng6LnG_o_2PKR-BuUFfmrj3V1aeFiI-_bcWuPFyo,5606
|
|
95
96
|
tests/test_compiler.py,sha256=R1t0MDQR01uEbY2wxqzQEf-LkSehrfZWmLvPuguC2JI,3419
|
|
96
|
-
tests/test_dmcircuit.py,sha256=
|
|
97
|
+
tests/test_dmcircuit.py,sha256=ZtTS-Jcpt-oN3yafYee9ZZCFW8-2I0MaLpyaDPve0PA,17234
|
|
97
98
|
tests/test_ensemble.py,sha256=0RzJkv-5D8LeZxS0Q0MwtEcgnXd2zefMquPHRNYT6RY,2109
|
|
98
|
-
tests/test_fgs.py,sha256=
|
|
99
|
+
tests/test_fgs.py,sha256=W-wPl1_2GquutfDJvD7yQvol-qkvVQnWe2tbAgGJz3w,10491
|
|
99
100
|
tests/test_gates.py,sha256=rAIV2QFpFsA5bT1QivTSkhdarvwu5t0N3IOz4SEDrzg,4593
|
|
101
|
+
tests/test_hamiltonians.py,sha256=E0E5ABhUeG7XLMLRkb3AIAPi7aJgnIeMWTgqzF1Q6yc,5724
|
|
100
102
|
tests/test_interfaces.py,sha256=iJPmes8S8HkA9_PGjsu4Ike-vCXYyS1EMgnNKKXDNaU,16938
|
|
101
103
|
tests/test_keras.py,sha256=U453jukavmx0RMeTSDEgPzrNdHNEfK1CW0CqO3XCNKo,4841
|
|
102
104
|
tests/test_lattice.py,sha256=_ptDVK3EhS-X5fCQWiP8sHk3azdyGFuwqg6KMkBTkDE,65789
|
|
103
|
-
tests/test_miscs.py,sha256=
|
|
105
|
+
tests/test_miscs.py,sha256=mm6kv5LqLkwHxWrGzLxajyOp1RaaKoHxq2OT1J3DpIM,9741
|
|
104
106
|
tests/test_mpscircuit.py,sha256=mDXX8oQeFeHr_PdZvwqyDs_tVcVAqLmCERqlTAU7590,10552
|
|
105
107
|
tests/test_noisemodel.py,sha256=UYoMtCjwDaB-CCn5kLosofz-qTMiY4KGAFBjVtqqLPE,5637
|
|
106
108
|
tests/test_qaoa.py,sha256=hEcC_XVmKBGt9XgUGtbTO8eQQK4mjorgTIrfqZCeQls,2616
|
|
@@ -110,11 +112,11 @@ tests/test_quantum_attr.py,sha256=Zl6WbkbnTWVp6FL2rR21qBGsLoheoIEZXqWZKxfpDRs,12
|
|
|
110
112
|
tests/test_results.py,sha256=8cQO0ShkBc4_pB-fi9s35WJbuZl5ex5y1oElSV-GlRo,11882
|
|
111
113
|
tests/test_shadows.py,sha256=1T3kJesVJ5XfZrSncL80xdq-taGCSnTDF3eL15UlavY,5160
|
|
112
114
|
tests/test_simplify.py,sha256=35tbOu1QANsPvY1buLwNhqPnMkBOsnBtHn82qaukmgI,1175
|
|
113
|
-
tests/test_stabilizer.py,sha256=
|
|
115
|
+
tests/test_stabilizer.py,sha256=MivuZ5pY7GOcEPTanhtrflXostyLBToHyjfPqCU0tG0,5450
|
|
114
116
|
tests/test_templates.py,sha256=Xm9otFFaaBWG9TZpgJ-nNh9MBfRipTzFWL8fBOnie2k,7192
|
|
115
117
|
tests/test_torchnn.py,sha256=CHLTfWkF7Ses5_XnGFN_uv_JddfgenFEFzaDtSH8XYU,2848
|
|
116
118
|
tests/test_van.py,sha256=kAWz860ivlb5zAJuYpzuBe27qccT-Yf0jatf5uXtTo4,3163
|
|
117
|
-
tensorcircuit_nightly-1.
|
|
118
|
-
tensorcircuit_nightly-1.
|
|
119
|
-
tensorcircuit_nightly-1.
|
|
120
|
-
tensorcircuit_nightly-1.
|
|
119
|
+
tensorcircuit_nightly-1.3.0.dev20250727.dist-info/METADATA,sha256=z1m8jG1FkT2VOYqt_udwFhII6IlJR9WzFWQb8m67NNs,34895
|
|
120
|
+
tensorcircuit_nightly-1.3.0.dev20250727.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
121
|
+
tensorcircuit_nightly-1.3.0.dev20250727.dist-info/top_level.txt,sha256=O_Iqeh2x02lasEYMI9iyPNNNtMzcpg5qvwMOkZQ7n4A,20
|
|
122
|
+
tensorcircuit_nightly-1.3.0.dev20250727.dist-info/RECORD,,
|
tests/test_circuit.py
CHANGED
|
@@ -889,6 +889,19 @@ def test_circuit_quoperator(backend):
|
|
|
889
889
|
np.testing.assert_allclose(qo.eval_matrix(), c.matrix(), atol=1e-5)
|
|
890
890
|
|
|
891
891
|
|
|
892
|
+
def test_perm_matrix():
|
|
893
|
+
from tensorcircuit.translation import perm_matrix
|
|
894
|
+
|
|
895
|
+
p2 = perm_matrix(2)
|
|
896
|
+
np.testing.assert_allclose(
|
|
897
|
+
p2, np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])
|
|
898
|
+
)
|
|
899
|
+
p3 = perm_matrix(3)
|
|
900
|
+
v = np.arange(8)
|
|
901
|
+
vt = np.array([0, 4, 2, 6, 1, 5, 3, 7])
|
|
902
|
+
np.testing.assert_allclose(p3 @ v, vt)
|
|
903
|
+
|
|
904
|
+
|
|
892
905
|
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
893
906
|
def test_qir2cirq(backend):
|
|
894
907
|
try:
|
tests/test_dmcircuit.py
CHANGED
tests/test_fgs.py
CHANGED
|
@@ -170,6 +170,14 @@ def test_post_select(backend, highp):
|
|
|
170
170
|
np.testing.assert_allclose(c.get_cmatrix(), c1.get_cmatrix(), atol=1e-5)
|
|
171
171
|
|
|
172
172
|
|
|
173
|
+
@pytest.mark.parametrize("backend", [lf("npb"), lf("tfb"), lf("jaxb")])
|
|
174
|
+
def test_post_select_cmatrix_refresh(backend, highp):
|
|
175
|
+
sim_post = tc.FGSSimulator(L=2, filled=[0])
|
|
176
|
+
sim_post.evol_hp(0, 1, np.pi / 4)
|
|
177
|
+
sim_post.post_select(0, keep=1)
|
|
178
|
+
np.testing.assert_allclose(1 - sim_post.get_cmatrix()[0, 0], 1, atol=1e-6)
|
|
179
|
+
|
|
180
|
+
|
|
173
181
|
@pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb")])
|
|
174
182
|
def test_jittable_measure(backend):
|
|
175
183
|
@tc.backend.jit
|