emu-sv 2.0.2__py3-none-any.whl → 2.0.4__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.
- emu_sv/__init__.py +2 -1
- emu_sv/hamiltonian.py +24 -22
- emu_sv/lindblad_operator.py +188 -0
- emu_sv/sv_backend.py +1 -0
- emu_sv/time_evolution.py +1 -0
- {emu_sv-2.0.2.dist-info → emu_sv-2.0.4.dist-info}/METADATA +2 -2
- emu_sv-2.0.4.dist-info/RECORD +14 -0
- emu_sv-2.0.2.dist-info/RECORD +0 -13
- {emu_sv-2.0.2.dist-info → emu_sv-2.0.4.dist-info}/WHEEL +0 -0
emu_sv/__init__.py
CHANGED
|
@@ -16,6 +16,7 @@ from .dense_operator import DenseOperator
|
|
|
16
16
|
from .sv_backend import SVBackend, SVConfig
|
|
17
17
|
from .state_vector import StateVector, inner
|
|
18
18
|
|
|
19
|
+
|
|
19
20
|
__all__ = [
|
|
20
21
|
"__version__",
|
|
21
22
|
"BitStrings",
|
|
@@ -35,4 +36,4 @@ __all__ = [
|
|
|
35
36
|
"inner",
|
|
36
37
|
]
|
|
37
38
|
|
|
38
|
-
__version__ = "2.0.
|
|
39
|
+
__version__ = "2.0.4"
|
emu_sv/hamiltonian.py
CHANGED
|
@@ -3,34 +3,36 @@ from emu_sv.state_vector import StateVector
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class RydbergHamiltonian:
|
|
6
|
-
"""
|
|
7
|
-
|
|
6
|
+
"""Represents the Rydberg Hamiltonian for a system of interacting qubits
|
|
7
|
+
driven by laser fields, including detuning, phase, and interaction terms.
|
|
8
|
+
|
|
9
|
+
The Hamiltonian is defined as:
|
|
8
10
|
|
|
9
|
-
H =
|
|
11
|
+
H = ∑ⱼ (Ωⱼ/2)[cos(ϕⱼ) σˣⱼ + sin(ϕⱼ) σʸⱼ] - ∑ⱼ Δⱼ nⱼ + ∑_{i>j} Uᵢⱼ nᵢ nⱼ
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
where:
|
|
14
|
+
- Ωⱼ is the Rabi frequency on qubit j,
|
|
15
|
+
- Δⱼ is the detuning on qubit j,
|
|
16
|
+
- ϕⱼ is the laser phase on qubit j,
|
|
17
|
+
- Uᵢⱼ is the interaction strength between qubits i and j,
|
|
18
|
+
- nⱼ = |1⟩⟨1| is the number operator on qubit j.
|
|
14
19
|
|
|
15
20
|
Attributes:
|
|
16
|
-
omegas (torch.Tensor):
|
|
17
|
-
deltas (torch.Tensor):
|
|
18
|
-
phis (torch.Tensor):
|
|
19
|
-
interaction_matrix (torch.Tensor): matrix Uᵢⱼ
|
|
20
|
-
|
|
21
|
+
omegas (torch.Tensor): vector of Rabi frequencies Ωⱼ / 2 for each qubit.
|
|
22
|
+
deltas (torch.Tensor): vector of detunings Δⱼ for each qubit.
|
|
23
|
+
phis (torch.Tensor): vector of phases ϕⱼ for each qubit.
|
|
24
|
+
interaction_matrix (torch.Tensor): matrix Uᵢⱼ for pairwise interactions.
|
|
25
|
+
device (torch.device): device on which all tensors are allocated.
|
|
26
|
+
diag (torch.Tensor): diagonal contribution to the Hamiltonian (detuning + interactions).
|
|
27
|
+
inds (torch.Tensor): index mapping for σˣ operations.
|
|
21
28
|
nqubits (int): number of qubits in the system.
|
|
22
|
-
diag (torch.Tensor): diagonal elements of the Hamiltonian,
|
|
23
|
-
calculated based on `deltas` and `interaction_matrix`.
|
|
24
|
-
inds (torch.Tensor): index tensor used for vector manipulations
|
|
25
|
-
in matrix-vector multiplications.
|
|
26
29
|
|
|
27
30
|
Methods:
|
|
28
|
-
__mul__(vec):
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
_apply_sigma_operators_real(): only applies ∑ⱼ(Ωⱼ/2)σˣⱼ when all phases are zero (ϕⱼ=0).
|
|
31
|
+
__mul__(vec): Applies the Hamiltonian H to a state vector |ψ⟩.
|
|
32
|
+
_apply_sigma_operators_real(): Applies only σˣ terms (ϕⱼ = 0).
|
|
33
|
+
_apply_sigma_operators_complex(): Applies generalized σˣ/σʸ terms (ϕⱼ ≠ 0).
|
|
34
|
+
_create_diagonal(): Computes the diagonal part of H from Δⱼ and Uᵢⱼ.
|
|
35
|
+
expect(state): Computes ⟨ψ|H|ψ⟩ for a given StateVector.
|
|
34
36
|
"""
|
|
35
37
|
|
|
36
38
|
def __init__(
|
|
@@ -107,7 +109,7 @@ class RydbergHamiltonian:
|
|
|
107
109
|
Returns:
|
|
108
110
|
the resulting state vector.
|
|
109
111
|
"""
|
|
110
|
-
c_omegas = self.omegas * torch.exp(
|
|
112
|
+
c_omegas = self.omegas * torch.exp(1.0j * self.phis)
|
|
111
113
|
|
|
112
114
|
dim_to_act = 1
|
|
113
115
|
for n, c_omega_n in enumerate(c_omegas):
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
from emu_base.jump_lindblad_operators import compute_noise_from_lindbladians
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
dtype = torch.complex128
|
|
6
|
+
sigmax = torch.tensor([[0.0, 1.0], [1.0, 0.0]], dtype=dtype)
|
|
7
|
+
sigmay = torch.tensor([[0.0, -1.0j], [1.0j, 0.0]], dtype=dtype)
|
|
8
|
+
n_op = torch.tensor([[0.0, 0.0], [0.0, 1.0]], dtype=dtype)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class RydbergLindbladian:
|
|
12
|
+
"""
|
|
13
|
+
Apply the Lindblad superoperator ℒ to a density matrix 𝜌, ℒ(𝜌).
|
|
14
|
+
|
|
15
|
+
This class implements
|
|
16
|
+
H @𝜌- H @ 𝜌 + i ∑ₖ − 1/2 Aₖ† Aₖ 𝜌 − 1/2 𝜌 Aₖ^† Aₖ + Aₖ 𝜌 Aₖ^†,
|
|
17
|
+
where A_k is a jump operator and H is the Rydberg Hamiltonian.
|
|
18
|
+
The complex -𝑖, will be multiplied in the evolution.
|
|
19
|
+
|
|
20
|
+
Attributes:
|
|
21
|
+
nqubits (int): number of qubits in the system.
|
|
22
|
+
omegas (torch.Tensor): amplited frequencies Ωⱼ for each qubit, divided by 2.
|
|
23
|
+
deltas (torch.Tensor): detunings 𝛿ᵢ for each qubit.
|
|
24
|
+
phis (torch.Tensor): phases 𝜙ᵢ for each qubit.
|
|
25
|
+
interaction_matrix (torch.Tensor): interaction_matrix (torch.Tensor): matrix Uᵢⱼ
|
|
26
|
+
representing pairwise Rydberg interaction strengths between qubits.
|
|
27
|
+
pulser_linblads (list[torch.Tensor]): List of 2x2 local Lindblad (jump)
|
|
28
|
+
operators acting on each qubit.
|
|
29
|
+
device (torch.device): device on which tensors are allocated. cpu or gpu: cuda.
|
|
30
|
+
complex (bool): flag indicating whether any drive phase is nonzero
|
|
31
|
+
(i.e., complex Hamiltonian terms).
|
|
32
|
+
diag (torch.Tensor): precomputed diagonal interaction term for the density matrix evolution.
|
|
33
|
+
|
|
34
|
+
Methods:
|
|
35
|
+
apply_local_op_to_density_matrix(density_matrix, local_op, target_qubit):
|
|
36
|
+
Applies a local operator to the density matrix from the left: L @ ρ.
|
|
37
|
+
|
|
38
|
+
apply_density_matrix_to_local_op_T(density_matrix, local_op, target_qubit):
|
|
39
|
+
Applies a daggered local operator to the density matrix from the right: ρ @ L†.
|
|
40
|
+
|
|
41
|
+
__matmul__(density_matrix):
|
|
42
|
+
Applies the full Lindbladian superoperator to the input density matrix,
|
|
43
|
+
including coherent evolution and all dissipation channels.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
omegas: torch.Tensor,
|
|
49
|
+
deltas: torch.Tensor,
|
|
50
|
+
phis: torch.Tensor,
|
|
51
|
+
pulser_linblads: list[torch.Tensor],
|
|
52
|
+
interaction_matrix: torch.Tensor,
|
|
53
|
+
device: torch.device,
|
|
54
|
+
):
|
|
55
|
+
self.nqubits: int = len(omegas)
|
|
56
|
+
self.omegas: torch.Tensor = omegas / 2.0
|
|
57
|
+
self.deltas: torch.Tensor = deltas
|
|
58
|
+
self.phis: torch.Tensor = phis
|
|
59
|
+
self.interaction_matrix: torch.Tensor = interaction_matrix
|
|
60
|
+
self.pulser_linblads: list[torch.Tensor] = pulser_linblads
|
|
61
|
+
self.device: torch.device = device
|
|
62
|
+
self.complex = self.phis.any()
|
|
63
|
+
|
|
64
|
+
self.diag: torch.Tensor = self._create_diagonal()
|
|
65
|
+
|
|
66
|
+
def _create_diagonal(self) -> torch.Tensor:
|
|
67
|
+
"""
|
|
68
|
+
Return the diagonal elements of the Rydberg Hamiltonian matrix
|
|
69
|
+
concerning only the interaction
|
|
70
|
+
|
|
71
|
+
H.diag = ∑ᵢ﹥ⱼUᵢⱼnᵢnⱼ
|
|
72
|
+
"""
|
|
73
|
+
diag = torch.zeros(2**self.nqubits, dtype=dtype, device=self.device)
|
|
74
|
+
|
|
75
|
+
for i in range(self.nqubits):
|
|
76
|
+
diag = diag.view(2**i, 2, -1)
|
|
77
|
+
i_fixed = diag[:, 1, :]
|
|
78
|
+
for j in range(i + 1, self.nqubits):
|
|
79
|
+
i_fixed = i_fixed.view(2**i, 2 ** (j - i - 1), 2, -1)
|
|
80
|
+
# replacing i_j_fixed by i_fixed breaks the code :)
|
|
81
|
+
i_j_fixed = i_fixed[:, :, 1, :]
|
|
82
|
+
i_j_fixed += self.interaction_matrix[i, j]
|
|
83
|
+
return diag.view(-1)
|
|
84
|
+
|
|
85
|
+
def apply_local_op_to_density_matrix(
|
|
86
|
+
self,
|
|
87
|
+
density_matrix: torch.Tensor,
|
|
88
|
+
local_op: torch.Tensor,
|
|
89
|
+
target_qubit: int,
|
|
90
|
+
) -> torch.Tensor:
|
|
91
|
+
"""
|
|
92
|
+
Calculate a local operator (2x2) L being multiplied by a density matrix ρ
|
|
93
|
+
from the left
|
|
94
|
+
Return L @ ρ
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
orignal_shape = density_matrix.shape
|
|
98
|
+
density_matrix = density_matrix.view(2**target_qubit, 2, -1)
|
|
99
|
+
density_matrix = local_op @ density_matrix
|
|
100
|
+
|
|
101
|
+
return density_matrix.view(orignal_shape)
|
|
102
|
+
|
|
103
|
+
def apply_density_matrix_to_local_op_T(
|
|
104
|
+
self,
|
|
105
|
+
density_matrix: torch.Tensor,
|
|
106
|
+
local_op: torch.Tensor,
|
|
107
|
+
target_qubit: int,
|
|
108
|
+
) -> torch.Tensor:
|
|
109
|
+
"""
|
|
110
|
+
Calculates a density matrix ρ being multiplied by a daggered local (2x2)
|
|
111
|
+
operator L† from the right,
|
|
112
|
+
|
|
113
|
+
return: ρ @L†
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
orignal_shape = density_matrix.shape
|
|
117
|
+
|
|
118
|
+
density_matrix = density_matrix.view(2 ** (target_qubit + self.nqubits), 2, -1)
|
|
119
|
+
density_matrix = local_op.conj() @ density_matrix
|
|
120
|
+
|
|
121
|
+
return density_matrix.view(orignal_shape)
|
|
122
|
+
|
|
123
|
+
def __matmul__(self, density_matrix: torch.Tensor) -> torch.Tensor:
|
|
124
|
+
"""Apply the i*RydbergLindbladian operator to the density matrix ρ
|
|
125
|
+
in the following way:
|
|
126
|
+
Define and effective Hamiltonian
|
|
127
|
+
Heff = Hρ -0.5i ∑ₖ Lₖ† Lₖ ρ
|
|
128
|
+
Then, the Lindblad operator applying to ρ is giving by
|
|
129
|
+
ℒ(𝜌) = Heff - Heff^†+i*∑ₖ Lₖ ρ Lₖ†
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
# compute -0.5i ∑ₖ Lₖ† Lₖ
|
|
133
|
+
sum_lindblad_local = compute_noise_from_lindbladians(self.pulser_linblads).to(
|
|
134
|
+
self.device
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# apply all local terms: Ωⱼ σₓ - δⱼ n - 0.5i (∑ₖ Lₖ† Lₖ) to each qubit
|
|
138
|
+
H_den_matrix = torch.zeros_like(density_matrix, dtype=dtype, device=self.device)
|
|
139
|
+
|
|
140
|
+
if not self.complex:
|
|
141
|
+
for qubit, (omega, delta) in enumerate(zip(self.omegas, self.deltas)):
|
|
142
|
+
H_q = (
|
|
143
|
+
omega * sigmax.to(device=self.device)
|
|
144
|
+
- delta * n_op.to(device=self.device)
|
|
145
|
+
+ sum_lindblad_local
|
|
146
|
+
)
|
|
147
|
+
H_den_matrix += self.apply_local_op_to_density_matrix(
|
|
148
|
+
density_matrix, H_q, qubit
|
|
149
|
+
)
|
|
150
|
+
else:
|
|
151
|
+
for qubit, (omega, delta, phi) in enumerate(
|
|
152
|
+
zip(self.omegas, self.deltas, self.phis)
|
|
153
|
+
):
|
|
154
|
+
H_q = (
|
|
155
|
+
omega
|
|
156
|
+
* (
|
|
157
|
+
(
|
|
158
|
+
torch.cos(phi) * sigmax.to(device=self.device)
|
|
159
|
+
+ torch.sin(phi) * sigmay.to(device=self.device)
|
|
160
|
+
)
|
|
161
|
+
)
|
|
162
|
+
- delta * n_op.to(device=self.device)
|
|
163
|
+
+ sum_lindblad_local
|
|
164
|
+
)
|
|
165
|
+
H_den_matrix += self.apply_local_op_to_density_matrix(
|
|
166
|
+
density_matrix, H_q, qubit
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# apply the interaction terms ∑ᵢⱼ Uᵢⱼ nᵢ nⱼ
|
|
170
|
+
H_den_matrix += self.diag.view(-1, 1) * density_matrix
|
|
171
|
+
|
|
172
|
+
# Heff - Heff^†= [H, ρ] - 0.5i ∑ₖ Lₖ† Lₖρ - ρ 0.5i ∑ₖ Lₖ† Lₖρ
|
|
173
|
+
H_den_matrix = H_den_matrix - H_den_matrix.conj().T
|
|
174
|
+
|
|
175
|
+
# compute ∑ₖ Lₖ ρ Lₖ†, last part of the Lindblad operator
|
|
176
|
+
L_den_matrix_Ldag = sum(
|
|
177
|
+
self.apply_density_matrix_to_local_op_T(
|
|
178
|
+
self.apply_local_op_to_density_matrix(
|
|
179
|
+
density_matrix, L.to(self.device), qubit
|
|
180
|
+
),
|
|
181
|
+
L.to(self.device),
|
|
182
|
+
qubit,
|
|
183
|
+
)
|
|
184
|
+
for qubit in range(self.nqubits)
|
|
185
|
+
for L in self.pulser_linblads
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
return H_den_matrix + 1.0j * L_den_matrix_Ldag
|
emu_sv/sv_backend.py
CHANGED
emu_sv/time_evolution.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: emu-sv
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.4
|
|
4
4
|
Summary: Pasqal State Vector based pulse emulator built on PyTorch
|
|
5
5
|
Project-URL: Documentation, https://pasqal-io.github.io/emulators/
|
|
6
6
|
Project-URL: Repository, https://github.com/pasqal-io/emulators
|
|
@@ -25,7 +25,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
25
25
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
26
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
27
27
|
Requires-Python: >=3.10
|
|
28
|
-
Requires-Dist: emu-base==2.0.
|
|
28
|
+
Requires-Dist: emu-base==2.0.4
|
|
29
29
|
Description-Content-Type: text/markdown
|
|
30
30
|
|
|
31
31
|
<div align="center">
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
emu_sv/__init__.py,sha256=Tzc6RlABZ1ZVKt1mPUes9djq0eiK6FTgPagEHuFhF6Q,702
|
|
2
|
+
emu_sv/custom_callback_implementations.py,sha256=zvsSiDIc56gwybKq87VFZyKsniTDye6-oFd2-R0shpg,3447
|
|
3
|
+
emu_sv/dense_operator.py,sha256=NfgzVpnNitc5ZSM4RlfpAc5Ls2wFPNsTxdeFdhJSg1o,6909
|
|
4
|
+
emu_sv/density_matrix_state.py,sha256=6UBLUXaJaUdzOhflrKolcnH8737JszX7sry1WmbyakI,6993
|
|
5
|
+
emu_sv/hamiltonian.py,sha256=CqNGuWJlO2ZljK47wt130s-5uKiOldQUsC3tjwk1mKA,6106
|
|
6
|
+
emu_sv/lindblad_operator.py,sha256=KmaNCahpAi8SIXh-TrFD-ggmGpa1zklp8DMWVK9Y_J4,7433
|
|
7
|
+
emu_sv/state_vector.py,sha256=lqSbv4BMtDtgY0YUPuhIUNJxrlVa7vUWuN_XqwpG5sQ,9823
|
|
8
|
+
emu_sv/sv_backend.py,sha256=AkEtI6-SY20D0ORro3Kv8tHDRUc8gxejSiRa6d--vBE,4452
|
|
9
|
+
emu_sv/sv_config.py,sha256=QRy0VbCugmY6TQZ48nD6RxPJbpu0wzN7-E1Sud7YxLQ,5106
|
|
10
|
+
emu_sv/time_evolution.py,sha256=obV7DcHot0jtnEmjR1ilYiSyDcJ5rTvThRB8hFjP-2s,797
|
|
11
|
+
emu_sv/utils.py,sha256=-axfQ2tqw0C7I9yw-28g7lytyk373DNBjDALh4kLBrM,302
|
|
12
|
+
emu_sv-2.0.4.dist-info/METADATA,sha256=paHoVgW22OONoxvlwaypB-UF01zi0giZqUtvAz7fhmw,3513
|
|
13
|
+
emu_sv-2.0.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
14
|
+
emu_sv-2.0.4.dist-info/RECORD,,
|
emu_sv-2.0.2.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
emu_sv/__init__.py,sha256=ubEb50_rPztWF-3xXyJsLy1zAxjmUVSuPqXXstpwD04,701
|
|
2
|
-
emu_sv/custom_callback_implementations.py,sha256=zvsSiDIc56gwybKq87VFZyKsniTDye6-oFd2-R0shpg,3447
|
|
3
|
-
emu_sv/dense_operator.py,sha256=NfgzVpnNitc5ZSM4RlfpAc5Ls2wFPNsTxdeFdhJSg1o,6909
|
|
4
|
-
emu_sv/density_matrix_state.py,sha256=6UBLUXaJaUdzOhflrKolcnH8737JszX7sry1WmbyakI,6993
|
|
5
|
-
emu_sv/hamiltonian.py,sha256=veJlJh_Q2_Fgc0IIfKPSWb6n_oem5WWGQUGDeepl924,6138
|
|
6
|
-
emu_sv/state_vector.py,sha256=lqSbv4BMtDtgY0YUPuhIUNJxrlVa7vUWuN_XqwpG5sQ,9823
|
|
7
|
-
emu_sv/sv_backend.py,sha256=9AZ9ksNv8lsgM_MxRM3xS709J1pbx5_R-zQ0jFDQ1Bg,4434
|
|
8
|
-
emu_sv/sv_config.py,sha256=QRy0VbCugmY6TQZ48nD6RxPJbpu0wzN7-E1Sud7YxLQ,5106
|
|
9
|
-
emu_sv/time_evolution.py,sha256=48C0DL_SOu7Jdjk2QKBNPsevOpQlgsPYUHE7cScY-ZM,796
|
|
10
|
-
emu_sv/utils.py,sha256=-axfQ2tqw0C7I9yw-28g7lytyk373DNBjDALh4kLBrM,302
|
|
11
|
-
emu_sv-2.0.2.dist-info/METADATA,sha256=IpPmesUmd5OZQDEOUCAc9NqMp4hYnHqSfs3rBUw4RjI,3513
|
|
12
|
-
emu_sv-2.0.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
13
|
-
emu_sv-2.0.2.dist-info/RECORD,,
|
|
File without changes
|