tequila-basic 1.9.7__py3-none-any.whl → 1.9.9__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.
- tequila/apps/unary_state_prep.py +1 -2
- tequila/circuit/circuit.py +20 -15
- tequila/hamiltonian/paulis.py +4 -3
- tequila/objective/objective.py +5 -2
- tequila/quantumchemistry/chemistry_tools.py +8 -1
- tequila/quantumchemistry/encodings.py +2 -2
- tequila/quantumchemistry/orbital_optimizer.py +10 -2
- tequila/simulators/simulator_api.py +35 -9
- tequila/simulators/simulator_base.py +58 -28
- tequila/simulators/simulator_cirq.py +6 -6
- tequila/simulators/simulator_pyquil.py +3 -3
- tequila/simulators/simulator_qibo.py +14 -16
- tequila/simulators/simulator_qiskit.py +88 -53
- tequila/simulators/simulator_qiskit_gpu.py +9 -0
- tequila/simulators/simulator_qlm.py +3 -3
- tequila/simulators/simulator_qulacs.py +37 -28
- tequila/simulators/simulator_qulacs_gpu.py +6 -4
- tequila/simulators/simulator_spex.py +429 -0
- tequila/simulators/simulator_symbolic.py +15 -23
- tequila/simulators/test_spex_simulator.py +211 -0
- tequila/utils/bitstrings.py +14 -3
- tequila/version.py +1 -1
- tequila/wavefunction/qubit_wavefunction.py +340 -237
- {tequila_basic-1.9.7.dist-info → tequila_basic-1.9.9.dist-info}/METADATA +13 -9
- {tequila_basic-1.9.7.dist-info → tequila_basic-1.9.9.dist-info}/RECORD +28 -25
- {tequila_basic-1.9.7.dist-info → tequila_basic-1.9.9.dist-info}/WHEEL +1 -1
- {tequila_basic-1.9.7.dist-info → tequila_basic-1.9.9.dist-info/licenses}/LICENSE +0 -0
- {tequila_basic-1.9.7.dist-info → tequila_basic-1.9.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,211 @@
|
|
1
|
+
import tequila as tq
|
2
|
+
import numpy as np
|
3
|
+
import time
|
4
|
+
import os
|
5
|
+
import csv
|
6
|
+
from tequila.hamiltonian import PauliString
|
7
|
+
import pytest
|
8
|
+
|
9
|
+
|
10
|
+
#!/usr/bin/env python
|
11
|
+
import tequila as tq
|
12
|
+
import numpy as np
|
13
|
+
import time
|
14
|
+
|
15
|
+
print("Test: Circuit und Hamiltonian mit Variablen (SPEX vs. Qulacs)")
|
16
|
+
|
17
|
+
# --- Parameterdefinition ---
|
18
|
+
# Definiere mehrere Variablen für die Rotation
|
19
|
+
a = tq.Variable("a")
|
20
|
+
b = tq.Variable("b")
|
21
|
+
c = tq.Variable("c")
|
22
|
+
variables = {"a": np.pi/3, "b": np.pi/4, "c": np.pi/6}
|
23
|
+
|
24
|
+
# --- Circuitaufbau ---
|
25
|
+
# Erzeuge einen Circuit, der auf 3 Qubits operiert:
|
26
|
+
# - Eine Rx-Rotation auf Qubit 0 (Winkel "a")
|
27
|
+
# - Eine Ry-Rotation auf Qubit 1 (Winkel "b")
|
28
|
+
# - Eine Rz-Rotation auf Qubit 2 (Winkel "c")
|
29
|
+
# - Zusätzlich eine parametrische exponentielle Pauli-Rotation (ExpPauli) auf Qubit 0 und 2 (Pauli-String "X(0)Z(2)")
|
30
|
+
U = tq.gates.Rx(angle="a", target=(0,)) \
|
31
|
+
+ tq.gates.Ry(angle="b", target=(1,)) \
|
32
|
+
+ tq.gates.Rz(angle="c", target=(2,))
|
33
|
+
U += tq.gates.ExpPauli(angle="a", paulistring="X(0)Z(2)")
|
34
|
+
|
35
|
+
print("\nCircuit U:")
|
36
|
+
print(U)
|
37
|
+
|
38
|
+
# --- Hamiltonianaufbau ---
|
39
|
+
# Erstelle einen zusammengesetzten Hamiltonian auf 3 Qubits,
|
40
|
+
# z.B.: H = Z(0) + X(1)Y(2) + Z(0)Z(1)
|
41
|
+
H = tq.QubitHamiltonian("Z(0) + X(1)Y(2) + Z(0)Z(1)")
|
42
|
+
print("\nHamiltonian H:")
|
43
|
+
print(H)
|
44
|
+
|
45
|
+
# Erzeuge ein Erwartungswertobjekt
|
46
|
+
E = tq.ExpectationValue(U=U, H=H)
|
47
|
+
|
48
|
+
# --- Simulation mit SPEX ---
|
49
|
+
start = time.time()
|
50
|
+
wfn_spex = tq.simulate(U, variables, backend='spex')
|
51
|
+
exp_spex = tq.simulate(E, variables, backend='spex')
|
52
|
+
end = time.time()
|
53
|
+
time_spex = end - start
|
54
|
+
|
55
|
+
# --- Simulation mit Qulacs ---
|
56
|
+
start = time.time()
|
57
|
+
wfn_qulacs = tq.simulate(U, variables, backend='qulacs')
|
58
|
+
exp_qulacs = tq.simulate(E, variables, backend='qulacs')
|
59
|
+
end = time.time()
|
60
|
+
time_qulacs = end - start
|
61
|
+
|
62
|
+
# --- Ergebnisse ausgeben ---
|
63
|
+
print("\nSimulationsergebnisse:")
|
64
|
+
print("Wellenfunktion (SPEX backend):")
|
65
|
+
print(wfn_spex)
|
66
|
+
print("\nWellenfunktion (Qulacs backend):")
|
67
|
+
print(wfn_qulacs)
|
68
|
+
|
69
|
+
print("\nErwartungswert (SPEX backend):", exp_spex, f"(Simulationszeit: {time_spex:.3f}s)")
|
70
|
+
print("Erwartungswert (Qulacs backend):", exp_qulacs, f"(Simulationszeit: {time_qulacs:.3f}s)")
|
71
|
+
|
72
|
+
# Optional: Vergleiche das innere Produkt der beiden Wavefunctions (Quadrat des Betrags)
|
73
|
+
inner_prod = np.abs(wfn_spex.inner(wfn_qulacs))**2
|
74
|
+
print("\nInneres Produkt (Quadrat) zwischen SPEX und Qulacs:", inner_prod)
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
"""
|
79
|
+
print("\nTest: 1")
|
80
|
+
U = tq.gates.ExpPauli(paulistring=PauliString({0: "X", 1: "Z"}), angle=np.pi / 2)
|
81
|
+
H = tq.QubitHamiltonian("Z(0)")
|
82
|
+
E = tq.ExpectationValue(U=U, H=H)
|
83
|
+
|
84
|
+
print(U)
|
85
|
+
print("spex-U:", tq.simulate(U, backend='spex'))
|
86
|
+
print("qulacs-U:", tq.simulate(U, backend='qulacs'))
|
87
|
+
print("spex:", tq.simulate(E, backend='spex'))
|
88
|
+
print("qulacs:", tq.simulate(E, backend='qulacs'))
|
89
|
+
|
90
|
+
|
91
|
+
print("\nTest: 2")
|
92
|
+
H = tq.QubitHamiltonian("Z(0)X(1)")
|
93
|
+
|
94
|
+
U = tq.gates.Rx(angle=np.pi / 4, target=(0,))
|
95
|
+
U += tq.gates.Ry(angle=np.pi / 3, target=(1,))
|
96
|
+
E = tq.ExpectationValue(U=U, H=H)
|
97
|
+
|
98
|
+
print(U)
|
99
|
+
print("spex-U:", tq.simulate(U, backend='spex'))
|
100
|
+
print("qulacs-U:", tq.simulate(U, backend='qulacs'))
|
101
|
+
print("spex:", tq.simulate(E, backend='spex'))
|
102
|
+
print("qulacs:", tq.simulate(E, backend='qulacs'))
|
103
|
+
|
104
|
+
|
105
|
+
print("\nTest: 3")
|
106
|
+
H = tq.QubitHamiltonian("Z(0)")
|
107
|
+
|
108
|
+
U = tq.gates.X(target=(0,))
|
109
|
+
U += tq.gates.Y(target=(1,))
|
110
|
+
E = tq.ExpectationValue(U=U, H=H)
|
111
|
+
|
112
|
+
print(U)
|
113
|
+
print("spex-U:", tq.simulate(U, backend='spex'))
|
114
|
+
print("qulacs-U:", tq.simulate(U, backend='qulacs'))
|
115
|
+
print("spex:", tq.simulate(E, backend='spex'))
|
116
|
+
print("qulacs:", tq.simulate(E, backend='qulacs'))
|
117
|
+
|
118
|
+
|
119
|
+
print("\nTest: 4")
|
120
|
+
U = (
|
121
|
+
tq.gates.Rx(angle=np.pi / 2, target=(0,)) +
|
122
|
+
tq.gates.Rz(angle=np.pi / 2, target=(1,)) +
|
123
|
+
tq.gates.Ry(angle=np.pi / 3, target=(2,)) +
|
124
|
+
tq.gates.ExpPauli(paulistring=PauliString({0: "X", 1: "X", 2: "X"}), angle=np.pi / 4)
|
125
|
+
)
|
126
|
+
|
127
|
+
H = tq.QubitHamiltonian("X(0)X(1)X(2) + Z(0) + Z(1) + Z(2)")
|
128
|
+
E = tq.ExpectationValue(U=U, H=H)
|
129
|
+
|
130
|
+
print(U)
|
131
|
+
print("spex-U:", tq.simulate(U, backend='spex'))
|
132
|
+
print("qulacs-U:", tq.simulate(U, backend='qulacs'))
|
133
|
+
print("spex:", tq.simulate(E, backend='spex'))
|
134
|
+
print("qulacs:", tq.simulate(E, backend='qulacs'))
|
135
|
+
|
136
|
+
print("\nTest: 5")
|
137
|
+
os.environ["OMP_NUM_THREADS"] = "6"
|
138
|
+
|
139
|
+
results = []
|
140
|
+
|
141
|
+
for n in range(1, 15):
|
142
|
+
# 1) Geometrie aufbauen
|
143
|
+
geom = ""
|
144
|
+
for k in range(2*n):
|
145
|
+
geom += f"h 0.0 0.0 {1.5*k}\n"
|
146
|
+
|
147
|
+
# 2) Molekül + Hamiltonian
|
148
|
+
mol = tq.Molecule(geometry=geom, basis_set="sto-3g")
|
149
|
+
H = mol.make_hardcore_boson_hamiltonian()
|
150
|
+
|
151
|
+
# 3) Ansatz U
|
152
|
+
edges = [(2*i, 2*i+1) for i in range(n)]
|
153
|
+
U = mol.make_ansatz(name="HCB-SPA", edges=edges)
|
154
|
+
# Alle im Ansatz auftretenden Variablen auf 1.0 setzen
|
155
|
+
U = U.map_variables({var: 1.0 for var in U.extract_variables()})
|
156
|
+
|
157
|
+
# 4) Erwartungswert-Objekt
|
158
|
+
E_obj = tq.ExpectationValue(H=H, U=U)
|
159
|
+
|
160
|
+
# -- SPEX-Berechnung --
|
161
|
+
start_spex = time.time()
|
162
|
+
E_spex = tq.simulate(E_obj, backend='spex', num_threads=6)
|
163
|
+
end_spex = time.time()
|
164
|
+
time_spex = end_spex - start_spex
|
165
|
+
|
166
|
+
# -- Qulacs-Berechnung --
|
167
|
+
if n <= 10:
|
168
|
+
start_qulacs = time.time()
|
169
|
+
E_qulacs = tq.simulate(E_obj, backend='qulacs')
|
170
|
+
end_qulacs = time.time()
|
171
|
+
time_qulacs = end_qulacs - start_qulacs
|
172
|
+
|
173
|
+
total_measurements = E_obj.count_measurements()
|
174
|
+
|
175
|
+
# Speichern der Daten
|
176
|
+
results.append({
|
177
|
+
'n': n,
|
178
|
+
'total_measurements' : total_measurements,
|
179
|
+
'E_spex': E_spex,
|
180
|
+
'time_spex': time_spex,
|
181
|
+
'E_qulacs': E_qulacs,
|
182
|
+
'time_qulacs': time_qulacs
|
183
|
+
})
|
184
|
+
|
185
|
+
if E_qulacs is not None:
|
186
|
+
print(f"n={n:2d} | total_measurements={total_measurements} | "
|
187
|
+
f"E_spex={E_spex:.6f} (dt={time_spex:.2f}s) | "
|
188
|
+
f"E_qulacs={E_qulacs:.6f} (dt={time_qulacs:.2f}s)")
|
189
|
+
else:
|
190
|
+
print(f"n={n:2d} | total_measurements={total_measurements} | "
|
191
|
+
f"E_spex={E_spex:.6f} (dt={time_spex:.2f}s) | "
|
192
|
+
f"E_qulacs=--- (dt=---) (für n>13 nicht berechnet)")
|
193
|
+
|
194
|
+
with open("spex_qulacs_comparison.csv", mode="w", newline="") as f:
|
195
|
+
writer = csv.writer(f)
|
196
|
+
# Kopfzeile
|
197
|
+
writer.writerow(["n", "total_measurements", "E_spex", "time_spex", "E_qulacs", "time_qulacs"])
|
198
|
+
# Datenzeilen
|
199
|
+
for entry in results:
|
200
|
+
writer.writerow([
|
201
|
+
entry["n"],
|
202
|
+
entry["total_measurements"],
|
203
|
+
entry["E_spex"],
|
204
|
+
entry["time_spex"],
|
205
|
+
entry["E_qulacs"] if entry["E_qulacs"] is not None else "NA",
|
206
|
+
entry["time_qulacs"] if entry["time_qulacs"] is not None else "NA"
|
207
|
+
])
|
208
|
+
|
209
|
+
E_qulacs = None
|
210
|
+
|
211
|
+
"""
|
tequila/utils/bitstrings.py
CHANGED
@@ -69,6 +69,12 @@ class BitString:
|
|
69
69
|
self.update_nbits()
|
70
70
|
return self
|
71
71
|
|
72
|
+
def to_integer(self, numbering: BitNumbering):
|
73
|
+
if numbering == self.numbering:
|
74
|
+
return self.integer
|
75
|
+
else:
|
76
|
+
return reverse_int_bits(self.integer, self.nbits)
|
77
|
+
|
72
78
|
@property
|
73
79
|
def array(self):
|
74
80
|
return [int(i) for i in self.binary]
|
@@ -178,7 +184,7 @@ class BitStringLSB(BitString):
|
|
178
184
|
return BitNumbering.LSB
|
179
185
|
|
180
186
|
|
181
|
-
def
|
187
|
+
def reverse_int_bits(x: int, nbits: int) -> int:
|
182
188
|
if nbits is None:
|
183
189
|
nbits = x.bit_length()
|
184
190
|
assert nbits <= 32
|
@@ -192,8 +198,13 @@ def _reverse_int_bits(x: int, nbits: int) -> int:
|
|
192
198
|
|
193
199
|
|
194
200
|
def initialize_bitstring(integer: int, nbits: int = None, numbering_in: BitNumbering = BitNumbering.MSB,
|
195
|
-
numbering_out: BitNumbering =
|
196
|
-
|
201
|
+
numbering_out: BitNumbering = None):
|
202
|
+
if numbering_out is None:
|
203
|
+
numbering_out = numbering_in
|
204
|
+
|
205
|
+
if numbering_in != numbering_out:
|
206
|
+
integer = reverse_int_bits(integer, nbits)
|
207
|
+
|
197
208
|
if numbering_out == BitNumbering.MSB:
|
198
209
|
return BitString.from_int(integer=integer, nbits=nbits)
|
199
210
|
else:
|
tequila/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
__version__ = "1.9.
|
1
|
+
__version__ = "1.9.9"
|
2
2
|
__author__ = "Tequila Developers "
|