tequila-basic 1.9.9__py3-none-any.whl → 1.9.10__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/__init__.py +29 -14
- tequila/apps/__init__.py +14 -5
- tequila/apps/_unary_state_prep_impl.py +145 -112
- tequila/apps/adapt/__init__.py +9 -1
- tequila/apps/adapt/adapt.py +154 -113
- tequila/apps/krylov/__init__.py +1 -1
- tequila/apps/krylov/krylov.py +23 -21
- tequila/apps/robustness/helpers.py +10 -6
- tequila/apps/robustness/interval.py +238 -156
- tequila/apps/unary_state_prep.py +29 -23
- tequila/autograd_imports.py +8 -5
- tequila/circuit/__init__.py +2 -1
- tequila/circuit/_gates_impl.py +135 -67
- tequila/circuit/circuit.py +163 -79
- tequila/circuit/compiler.py +114 -105
- tequila/circuit/gates.py +288 -120
- tequila/circuit/gradient.py +35 -23
- tequila/circuit/noise.py +83 -74
- tequila/circuit/postselection.py +120 -0
- tequila/circuit/pyzx.py +10 -6
- tequila/circuit/qasm.py +201 -83
- tequila/circuit/qpic.py +63 -61
- tequila/grouping/binary_rep.py +148 -146
- tequila/grouping/binary_utils.py +84 -75
- tequila/grouping/compile_groups.py +334 -230
- tequila/grouping/ev_utils.py +77 -41
- tequila/grouping/fermionic_functions.py +383 -308
- tequila/grouping/fermionic_methods.py +170 -123
- tequila/grouping/overlapping_methods.py +69 -52
- tequila/hamiltonian/paulis.py +12 -13
- tequila/hamiltonian/paulistring.py +1 -1
- tequila/hamiltonian/qubit_hamiltonian.py +45 -35
- tequila/ml/__init__.py +1 -0
- tequila/ml/interface_torch.py +19 -16
- tequila/ml/ml_api.py +11 -10
- tequila/ml/utils_ml.py +12 -11
- tequila/objective/__init__.py +8 -3
- tequila/objective/braket.py +55 -47
- tequila/objective/objective.py +87 -55
- tequila/objective/qtensor.py +36 -27
- tequila/optimizers/__init__.py +31 -23
- tequila/optimizers/_containers.py +11 -7
- tequila/optimizers/optimizer_base.py +111 -83
- tequila/optimizers/optimizer_gd.py +258 -231
- tequila/optimizers/optimizer_gpyopt.py +56 -42
- tequila/optimizers/optimizer_scipy.py +157 -112
- tequila/quantumchemistry/__init__.py +66 -38
- tequila/quantumchemistry/chemistry_tools.py +393 -209
- tequila/quantumchemistry/encodings.py +121 -13
- tequila/quantumchemistry/madness_interface.py +170 -96
- tequila/quantumchemistry/orbital_optimizer.py +86 -41
- tequila/quantumchemistry/psi4_interface.py +166 -97
- tequila/quantumchemistry/pyscf_interface.py +70 -23
- tequila/quantumchemistry/qc_base.py +866 -414
- tequila/simulators/__init__.py +0 -3
- tequila/simulators/simulator_api.py +247 -105
- tequila/simulators/simulator_aqt.py +102 -0
- tequila/simulators/simulator_base.py +147 -53
- tequila/simulators/simulator_cirq.py +58 -42
- tequila/simulators/simulator_cudaq.py +600 -0
- tequila/simulators/simulator_ddsim.py +390 -0
- tequila/simulators/simulator_mqp.py +30 -0
- tequila/simulators/simulator_pyquil.py +190 -171
- tequila/simulators/simulator_qibo.py +95 -87
- tequila/simulators/simulator_qiskit.py +119 -107
- tequila/simulators/simulator_qlm.py +52 -26
- tequila/simulators/simulator_qulacs.py +74 -52
- tequila/simulators/simulator_spex.py +95 -60
- tequila/simulators/simulator_symbolic.py +6 -5
- tequila/simulators/test_spex_simulator.py +8 -11
- tequila/tools/convenience.py +4 -4
- tequila/tools/qng.py +72 -64
- tequila/tools/random_generators.py +38 -34
- tequila/utils/bitstrings.py +7 -7
- tequila/utils/exceptions.py +19 -5
- tequila/utils/joined_transformation.py +8 -10
- tequila/utils/keymap.py +0 -5
- tequila/utils/misc.py +6 -4
- tequila/version.py +1 -1
- tequila/wavefunction/qubit_wavefunction.py +47 -28
- {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/METADATA +13 -16
- tequila_basic-1.9.10.dist-info/RECORD +93 -0
- {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/WHEEL +1 -1
- tequila_basic-1.9.9.dist-info/RECORD +0 -88
- {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/licenses/LICENSE +0 -0
- {tequila_basic-1.9.9.dist-info → tequila_basic-1.9.10.dist-info}/top_level.txt +0 -0
@@ -2,6 +2,7 @@
|
|
2
2
|
Collections of Fermion-to-Qubit encodings known to tequila
|
3
3
|
Most are Interfaces to OpenFermion
|
4
4
|
"""
|
5
|
+
|
5
6
|
import abc
|
6
7
|
|
7
8
|
from tequila import TequilaException
|
@@ -19,14 +20,17 @@ def known_encodings():
|
|
19
20
|
"BravyiKitaev": BravyiKitaev,
|
20
21
|
"BravyiKitaevFast": BravyiKitaevFast,
|
21
22
|
"BravyiKitaevTree": BravyiKitaevTree,
|
22
|
-
"TaperedBravyiKitaev": TaperedBravyKitaev
|
23
|
+
"TaperedBravyiKitaev": TaperedBravyKitaev,
|
24
|
+
"TaperedBinary": TaperedBinary,
|
23
25
|
}
|
24
26
|
# aliases
|
25
|
-
encodings = {
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
encodings = {
|
28
|
+
**encodings,
|
29
|
+
"ReorderedJordanWigner": lambda **kwargs: JordanWigner(up_then_down=True, **kwargs),
|
30
|
+
"ReorderedBravyiKitaev": lambda **kwargs: BravyiKitaev(up_then_down=True, **kwargs),
|
31
|
+
"ReorderedBravyiKitaevTree": lambda **kwargs: BravyiKitaevTree(up_then_down=True, **kwargs),
|
32
|
+
"ReorderedTaperedBinary": lambda **kwargs: TaperedBinary(up_then_down=True, **kwargs),
|
33
|
+
}
|
30
34
|
return {k.replace("_", "").replace("-", "").upper(): v for k, v in encodings.items()}
|
31
35
|
|
32
36
|
|
@@ -63,8 +67,9 @@ class EncodingBase(metaclass=abc.ABCMeta):
|
|
63
67
|
The openfermion QubitOperator of this class ecoding
|
64
68
|
"""
|
65
69
|
if self.up_then_down:
|
66
|
-
op = openfermion.reorder(
|
67
|
-
|
70
|
+
op = openfermion.reorder(
|
71
|
+
operator=fermion_operator, order_function=openfermion.up_then_down, num_modes=2 * self.n_orbitals
|
72
|
+
)
|
68
73
|
else:
|
69
74
|
op = fermion_operator
|
70
75
|
|
@@ -128,6 +133,7 @@ class EncodingBase(metaclass=abc.ABCMeta):
|
|
128
133
|
fop = openfermion.FermionOperator(string, 1.0)
|
129
134
|
op = self(fop)
|
130
135
|
from tequila.wavefunction.qubit_wavefunction import QubitWaveFunction
|
136
|
+
|
131
137
|
wfn = QubitWaveFunction.from_basis_state(n_qubits, 0)
|
132
138
|
wfn = wfn.apply_qubitoperator(operator=op)
|
133
139
|
assert wfn.length() == 1
|
@@ -200,6 +206,7 @@ class JordanWigner(EncodingBase):
|
|
200
206
|
"""
|
201
207
|
OpenFermion::jordan_wigner
|
202
208
|
"""
|
209
|
+
|
203
210
|
_ucc_support = True
|
204
211
|
|
205
212
|
def do_transform(self, fermion_operator: openfermion.FermionOperator, *args, **kwargs) -> openfermion.QubitOperator:
|
@@ -275,7 +282,9 @@ class BravyiKitaevFast(EncodingBase):
|
|
275
282
|
if n_qubits != self.n_orbitals * 2:
|
276
283
|
raise Exception(
|
277
284
|
"BravyiKitaevFast transformation currently only possible for full Hamiltonians (no UCC generators).\nfermion_operator was {}".format(
|
278
|
-
fermion_operator
|
285
|
+
fermion_operator
|
286
|
+
)
|
287
|
+
)
|
279
288
|
op = openfermion.get_interaction_operator(fermion_operator)
|
280
289
|
return openfermion.bravyi_kitaev_fast(op)
|
281
290
|
|
@@ -311,12 +320,14 @@ class TaperedBravyKitaev(EncodingBase):
|
|
311
320
|
def do_transform(self, fermion_operator: openfermion.FermionOperator, *args, **kwargs) -> openfermion.QubitOperator:
|
312
321
|
if openfermion.count_qubits(fermion_operator) != self.n_orbitals * 2:
|
313
322
|
raise Exception("TaperedBravyiKitaev not ready for UCC generators yet")
|
314
|
-
return openfermion.symmetry_conserving_bravyi_kitaev(
|
315
|
-
|
323
|
+
return openfermion.symmetry_conserving_bravyi_kitaev(
|
324
|
+
fermion_operator, active_orbitals=self.active_orbitals, active_fermions=self.active_fermions
|
325
|
+
)
|
316
326
|
|
317
327
|
def map_state(self, state: list, *args, **kwargs):
|
318
|
-
non_tapered_trafo = BravyiKitaevTree(
|
319
|
-
|
328
|
+
non_tapered_trafo = BravyiKitaevTree(
|
329
|
+
up_then_down=True, n_electrons=self.n_electrons, n_orbitals=self.n_orbitals
|
330
|
+
)
|
320
331
|
key = non_tapered_trafo.map_state(state=state, *args, **kwargs)
|
321
332
|
n_qubits = self.n_orbitals * 2
|
322
333
|
active_qubits = [i for i in range(n_qubits) if i not in [n_qubits - 1, n_qubits // 2 - 1]]
|
@@ -325,3 +336,100 @@ class TaperedBravyKitaev(EncodingBase):
|
|
325
336
|
|
326
337
|
def me_to_jw(self) -> QCircuit:
|
327
338
|
raise TequilaException("{}::me_to_jw: unimplemented".format(type(self).__name__))
|
339
|
+
|
340
|
+
|
341
|
+
class TaperedBinary(EncodingBase):
|
342
|
+
_ucc_support = True
|
343
|
+
|
344
|
+
"""
|
345
|
+
Uses OpenFermion::binary_code_transform (checksum code arxiv:1712.07067)
|
346
|
+
Reduces Hamiltonian by 2 qubits
|
347
|
+
See OpenFermion Documentation for more
|
348
|
+
"""
|
349
|
+
|
350
|
+
def __init__(
|
351
|
+
self, n_electrons, n_orbitals, active_fermions=None, active_orbitals=None, up_then_down=False, *args, **kwargs
|
352
|
+
):
|
353
|
+
if active_fermions is None:
|
354
|
+
self.active_fermions = (
|
355
|
+
n_electrons # it maybe changed at some point to support different number of alpha and beta electr
|
356
|
+
)
|
357
|
+
else:
|
358
|
+
self.active_fermions = active_fermions
|
359
|
+
if active_orbitals is None:
|
360
|
+
self.active_orbitals = n_orbitals * 2 # in openfermion those are spin-orbitals
|
361
|
+
else:
|
362
|
+
self.active_orbitals = active_orbitals
|
363
|
+
super().__init__(n_orbitals=n_orbitals, n_electrons=n_electrons, up_then_down=up_then_down, *args, **kwargs)
|
364
|
+
self.spin_parity = bool((self.n_electrons / 2) % 2) # total parity of all \sigma\in\{\alpha\beta\} SOs
|
365
|
+
from scipy.special import factorial
|
366
|
+
|
367
|
+
self.modes = self.active_orbitals # asumed n alpha = n beta
|
368
|
+
|
369
|
+
def __call__(self, fermion_operator: openfermion.FermionOperator, *args, **kwargs) -> QubitHamiltonian:
|
370
|
+
"""
|
371
|
+
:param fermion_operator:
|
372
|
+
an openfermion FermionOperator
|
373
|
+
:return:
|
374
|
+
The openfermion QubitOperator of this class ecoding
|
375
|
+
"""
|
376
|
+
fop = self.do_transform(fermion_operator=fermion_operator, *args, **kwargs)
|
377
|
+
fop.compress()
|
378
|
+
return self.post_processing(QubitHamiltonian.from_openfermion(fop))
|
379
|
+
|
380
|
+
def do_transform(self, fermion_operator: openfermion.FermionOperator, *args, **kwargs) -> openfermion.QubitOperator:
|
381
|
+
mul = openfermion.interleaved_code(self.modes) * (
|
382
|
+
2 * openfermion.transforms.checksum_code(self.modes // 2, self.spin_parity)
|
383
|
+
)
|
384
|
+
return openfermion.transforms.binary_code_transform(fermion_operator, mul)
|
385
|
+
|
386
|
+
def post_processing(self, op: QubitHamiltonian, *args, **kwargs):
|
387
|
+
if not self.up_then_down:
|
388
|
+
da = {i: 2 * i for i in range(self.n_orbitals - 1)}
|
389
|
+
db = {i + self.n_orbitals - 1: 2 * i + 1 for i in range(self.n_orbitals - 1)}
|
390
|
+
da.update(db)
|
391
|
+
op = op.map_qubits(da)
|
392
|
+
return op
|
393
|
+
|
394
|
+
def map_state(self, state: list, *args, **kwargs):
|
395
|
+
if len(state) < (2 * self.n_orbitals - 2):
|
396
|
+
state = state + [0] * (2 * self.n_orbitals - len(state) - 2)
|
397
|
+
if self.up_then_down:
|
398
|
+
return [state[2 * i] for i in range(self.n_orbitals - 1)] + [
|
399
|
+
state[2 * i + 1] for i in range(self.n_orbitals - 1)
|
400
|
+
]
|
401
|
+
else:
|
402
|
+
return state
|
403
|
+
|
404
|
+
def me_to_jw(self) -> QCircuit:
|
405
|
+
"""
|
406
|
+
In case of upthendown, expected to be qubit_{n_orbital} free, otherwise please map it properly
|
407
|
+
"""
|
408
|
+
U = QCircuit()
|
409
|
+
if self.spin_parity: # since we now the spin parity
|
410
|
+
U += X(2 * self.n_orbitals - 2) + X(2 * self.n_orbitals - 1)
|
411
|
+
for i in range(
|
412
|
+
self.n_orbitals - 1
|
413
|
+
): # we can tapper only one electron per \sigma, we need only to find the difference
|
414
|
+
U += CNOT(2 * i, 2 * self.n_orbitals - 2)
|
415
|
+
U += CNOT(2 * i + 1, 2 * self.n_orbitals - 1)
|
416
|
+
if self.up_then_down:
|
417
|
+
da = {2 * i: i for i in range(self.n_orbitals)}
|
418
|
+
db = {2 * i + 1: self.n_orbitals + i - 1 for i in range(self.n_orbitals)}
|
419
|
+
db.update(da)
|
420
|
+
U = U.map_qubits(db)
|
421
|
+
return U
|
422
|
+
|
423
|
+
def hcb_to_me(self) -> QCircuit:
|
424
|
+
"""
|
425
|
+
The HCB term of the tappered orbital is not proyected out but should affect to the ExpValue since it is not
|
426
|
+
on the Hamiltonian
|
427
|
+
"""
|
428
|
+
U = QCircuit()
|
429
|
+
for i in range(self.n_orbitals - 1):
|
430
|
+
U += CNOT(
|
431
|
+
control=i + i * (not self.up_then_down),
|
432
|
+
target=i + self.up_then_down * (self.n_orbitals - 1) + (not self.up_then_down) * (i + 1),
|
433
|
+
)
|
434
|
+
U.n_qubits = 2 * self.n_orbitals - 2
|
435
|
+
return U
|