tequila-basic 1.9.8__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 +177 -88
- 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 +91 -56
- 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 +394 -203
- tequila/quantumchemistry/encodings.py +121 -13
- tequila/quantumchemistry/madness_interface.py +170 -96
- tequila/quantumchemistry/orbital_optimizer.py +86 -40
- 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 +258 -106
- tequila/simulators/simulator_aqt.py +102 -0
- tequila/simulators/simulator_base.py +156 -55
- 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 +124 -114
- tequila/simulators/simulator_qlm.py +52 -26
- tequila/simulators/simulator_qulacs.py +85 -59
- tequila/simulators/simulator_spex.py +464 -0
- tequila/simulators/simulator_symbolic.py +6 -5
- tequila/simulators/test_spex_simulator.py +208 -0
- tequila/tools/convenience.py +4 -4
- tequila/tools/qng.py +72 -64
- tequila/tools/random_generators.py +38 -34
- tequila/utils/bitstrings.py +13 -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 +52 -30
- {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info}/METADATA +23 -17
- tequila_basic-1.9.10.dist-info/RECORD +93 -0
- {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info}/WHEEL +1 -1
- tequila_basic-1.9.8.dist-info/RECORD +0 -86
- {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info/licenses}/LICENSE +0 -0
- {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,8 @@
|
|
1
1
|
from typing import Union
|
2
2
|
|
3
3
|
import qulacs
|
4
|
-
import numbers
|
4
|
+
import numbers
|
5
|
+
import numpy
|
5
6
|
import warnings
|
6
7
|
|
7
8
|
from tequila import TequilaException, TequilaWarning
|
@@ -17,10 +18,12 @@ Developer Note:
|
|
17
18
|
The angles are scaled with -1.0 to keep things consistent with the rest of tequila
|
18
19
|
"""
|
19
20
|
|
21
|
+
|
20
22
|
class TequilaQulacsException(TequilaException):
|
21
23
|
def __str__(self):
|
22
24
|
return "Error in qulacs backend:" + self.message
|
23
25
|
|
26
|
+
|
24
27
|
class BackendCircuitQulacs(BackendCircuit):
|
25
28
|
"""
|
26
29
|
Class representing circuits compiled to qulacs.
|
@@ -49,7 +52,7 @@ class BackendCircuitQulacs(BackendCircuit):
|
|
49
52
|
"trotterized": True,
|
50
53
|
"swap": False,
|
51
54
|
"multitarget": True,
|
52
|
-
"controlled_rotation": True,
|
55
|
+
"controlled_rotation": True, # needed for gates depending on variables
|
53
56
|
"generalized_rotation": True,
|
54
57
|
"exponential_pauli": False,
|
55
58
|
"controlled_exponential_pauli": True,
|
@@ -60,7 +63,7 @@ class BackendCircuitQulacs(BackendCircuit):
|
|
60
63
|
"controlled_phase": True,
|
61
64
|
"toffoli": False,
|
62
65
|
"phase_to_z": True,
|
63
|
-
"cc_max": False
|
66
|
+
"cc_max": False,
|
64
67
|
}
|
65
68
|
|
66
69
|
numbering = BitNumbering.LSB
|
@@ -83,41 +86,48 @@ class BackendCircuitQulacs(BackendCircuit):
|
|
83
86
|
kwargs
|
84
87
|
"""
|
85
88
|
self.op_lookup = {
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
89
|
+
"I": qulacs.gate.Identity,
|
90
|
+
"X": qulacs.gate.X,
|
91
|
+
"Y": qulacs.gate.Y,
|
92
|
+
"Z": qulacs.gate.Z,
|
93
|
+
"H": qulacs.gate.H,
|
94
|
+
"Rx": (lambda c: c.add_parametric_RX_gate, qulacs.gate.RX),
|
95
|
+
"Ry": (lambda c: c.add_parametric_RY_gate, qulacs.gate.RY),
|
96
|
+
"Rz": (lambda c: c.add_parametric_RZ_gate, qulacs.gate.RZ),
|
97
|
+
"SWAP": qulacs.gate.SWAP,
|
98
|
+
"Measure": qulacs.gate.Measurement,
|
99
|
+
"Exp-Pauli": None,
|
97
100
|
}
|
98
101
|
self.measurements = None
|
99
102
|
self.variables = []
|
100
103
|
super().__init__(abstract_circuit=abstract_circuit, noise=noise, *args, **kwargs)
|
101
|
-
self.has_noise=False
|
104
|
+
self.has_noise = False
|
102
105
|
if noise is not None:
|
106
|
+
warnings.warn(
|
107
|
+
"Warning: noise in qulacs module will be dropped. Currently only works for qulacs version 0.5 or lower",
|
108
|
+
TequilaWarning,
|
109
|
+
)
|
103
110
|
|
104
|
-
|
105
|
-
|
106
|
-
self.has_noise=True
|
111
|
+
self.has_noise = True
|
107
112
|
self.noise_lookup = {
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
113
|
+
"bit flip": [qulacs.gate.BitFlipNoise],
|
114
|
+
"phase flip": [lambda target, prob: qulacs.gate.Probabilistic([prob], [qulacs.gate.Z(target)])],
|
115
|
+
"phase damp": [
|
116
|
+
lambda target, prob: qulacs.gate.DephasingNoise(target, (1 / 2) * (1 - numpy.sqrt(1 - prob)))
|
117
|
+
],
|
118
|
+
"amplitude damp": [qulacs.gate.AmplitudeDampingNoise],
|
119
|
+
"phase-amplitude damp": [
|
120
|
+
qulacs.gate.AmplitudeDampingNoise,
|
121
|
+
lambda target, prob: qulacs.gate.DephasingNoise(target, (1 / 2) * (1 - numpy.sqrt(1 - prob))),
|
122
|
+
],
|
123
|
+
"depolarizing": [lambda target, prob: qulacs.gate.DepolarizingNoise(target, 3 * prob / 4)],
|
116
124
|
}
|
117
125
|
|
118
|
-
self.circuit=self.add_noise_to_circuit(noise)
|
126
|
+
self.circuit = self.add_noise_to_circuit(noise)
|
119
127
|
|
120
|
-
def initialize_state(
|
128
|
+
def initialize_state(
|
129
|
+
self, n_qubits: int = None, initial_state: Union[int, QubitWaveFunction] = None
|
130
|
+
) -> qulacs.QuantumState:
|
121
131
|
if n_qubits is None:
|
122
132
|
n_qubits = self.n_qubits
|
123
133
|
|
@@ -269,13 +279,14 @@ class BackendCircuitQulacs(BackendCircuit):
|
|
269
279
|
None
|
270
280
|
"""
|
271
281
|
assert not gate.is_controlled()
|
272
|
-
convert = {
|
282
|
+
convert = {"x": 1, "y": 2, "z": 3}
|
273
283
|
pind = [convert[x.lower()] for x in gate.paulistring.values()]
|
274
284
|
qind = [self.qubit(x) for x in gate.paulistring.keys()]
|
275
285
|
if len(gate.extract_variables()) > 0:
|
276
286
|
self.variables.append(-gate.parameter * gate.paulistring.coeff)
|
277
|
-
circuit.add_parametric_multi_Pauli_rotation_gate(
|
278
|
-
|
287
|
+
circuit.add_parametric_multi_Pauli_rotation_gate(
|
288
|
+
qind, pind, -gate.parameter(variables) * gate.paulistring.coeff
|
289
|
+
)
|
279
290
|
else:
|
280
291
|
circuit.add_multi_Pauli_rotation_gate(qind, pind, -gate.parameter(variables) * gate.paulistring.coeff)
|
281
292
|
|
@@ -298,7 +309,7 @@ class BackendCircuitQulacs(BackendCircuit):
|
|
298
309
|
None
|
299
310
|
"""
|
300
311
|
op = self.op_lookup[gate.name]
|
301
|
-
if gate.name ==
|
312
|
+
if gate.name == "Exp-Pauli":
|
302
313
|
self.add_exponential_pauli_gate(gate, circuit, variables)
|
303
314
|
return
|
304
315
|
else:
|
@@ -307,7 +318,9 @@ class BackendCircuitQulacs(BackendCircuit):
|
|
307
318
|
self.variables.append(-gate.parameter)
|
308
319
|
op(circuit)(self.qubit(gate.target[0]), -gate.parameter(variables=variables))
|
309
320
|
if gate.is_controlled():
|
310
|
-
raise TequilaQulacsException(
|
321
|
+
raise TequilaQulacsException(
|
322
|
+
"Gates which depend on variables can not be controlled! Gate was:\n{}".format(gate)
|
323
|
+
)
|
311
324
|
return
|
312
325
|
else:
|
313
326
|
op = op[1]
|
@@ -362,8 +375,7 @@ class BackendCircuitQulacs(BackendCircuit):
|
|
362
375
|
self.measurements = sorted(target_qubits)
|
363
376
|
return circuit
|
364
377
|
|
365
|
-
|
366
|
-
def add_noise_to_circuit(self,noise_model):
|
378
|
+
def add_noise_to_circuit(self, noise_model):
|
367
379
|
"""
|
368
380
|
Apply noise from a NoiseModel to a circuit.
|
369
381
|
Parameters
|
@@ -376,19 +388,19 @@ class BackendCircuitQulacs(BackendCircuit):
|
|
376
388
|
qulacs.ParametrizedQuantumCircuit:
|
377
389
|
self.circuit, with noise added on.
|
378
390
|
"""
|
379
|
-
c=self.circuit
|
380
|
-
n=noise_model
|
381
|
-
g_count=c.get_gate_count()
|
382
|
-
new=self.initialize_circuit()
|
391
|
+
c = self.circuit
|
392
|
+
n = noise_model
|
393
|
+
g_count = c.get_gate_count()
|
394
|
+
new = self.initialize_circuit()
|
383
395
|
for i in range(g_count):
|
384
|
-
g=c.get_gate(i)
|
396
|
+
g = c.get_gate(i)
|
385
397
|
new.add_gate(g)
|
386
|
-
qubits=g.get_target_index_list() + g.get_control_index_list()
|
398
|
+
qubits = g.get_target_index_list() + g.get_control_index_list()
|
387
399
|
for noise in n.noises:
|
388
400
|
if len(qubits) == noise.level:
|
389
|
-
for j,channel in enumerate(self.noise_lookup[noise.name]):
|
401
|
+
for j, channel in enumerate(self.noise_lookup[noise.name]):
|
390
402
|
for q in qubits:
|
391
|
-
chan=channel(q,noise.probs[j])
|
403
|
+
chan = channel(q, noise.probs[j])
|
392
404
|
new.add_gate(chan)
|
393
405
|
return new
|
394
406
|
|
@@ -415,27 +427,33 @@ class BackendCircuitQulacs(BackendCircuit):
|
|
415
427
|
opt = qulacs.circuit.QuantumCircuitOptimizer()
|
416
428
|
opt.optimize(circuit, max_block_size)
|
417
429
|
if not silent:
|
418
|
-
print(
|
419
|
-
|
420
|
-
|
430
|
+
print(
|
431
|
+
"qulacs: optimized circuit depth from {} to {} with max_block_size {}".format(
|
432
|
+
old, circuit.calculate_depth(), max_block_size
|
433
|
+
)
|
434
|
+
)
|
421
435
|
return circuit
|
422
436
|
|
437
|
+
|
423
438
|
class BackendExpectationValueQulacs(BackendExpectationValue):
|
424
439
|
"""
|
425
440
|
Class representing Expectation Values compiled for Qulacs.
|
426
441
|
|
427
442
|
Ovverrides some methods of BackendExpectationValue, which should be seen for details.
|
428
443
|
"""
|
444
|
+
|
429
445
|
use_mapping = True
|
430
446
|
BackendCircuitType = BackendCircuitQulacs
|
431
447
|
|
432
|
-
def simulate(self, variables, *args, **kwargs) -> numpy.array:
|
448
|
+
def simulate(self, variables, initial_state: Union[int, QubitWaveFunction] = 0, *args, **kwargs) -> numpy.array:
|
433
449
|
"""
|
434
450
|
Perform simulation of this expectationvalue.
|
435
451
|
Parameters
|
436
452
|
----------
|
437
453
|
variables:
|
438
454
|
variables, to be supplied to the underlying circuit.
|
455
|
+
initial_state: int or QubitWaveFunction:
|
456
|
+
the initial state of the circuit
|
439
457
|
args
|
440
458
|
kwargs
|
441
459
|
|
@@ -453,12 +471,12 @@ class BackendExpectationValueQulacs(BackendExpectationValue):
|
|
453
471
|
return numpy.asarray[self.H]
|
454
472
|
|
455
473
|
self.U.update_variables(variables)
|
456
|
-
state = self.U.initialize_state(self.n_qubits)
|
474
|
+
state = self.U.initialize_state(self.n_qubits, initial_state)
|
457
475
|
self.U.circuit.update_quantum_state(state)
|
458
476
|
result = []
|
459
477
|
for H in self.H:
|
460
478
|
if isinstance(H, numbers.Number):
|
461
|
-
result.append(H)
|
479
|
+
result.append(H) # those are accumulated unit strings, e.g 0.1*X(3) in wfn on qubits 0,1
|
462
480
|
else:
|
463
481
|
result.append(H.get_expectation_value(state))
|
464
482
|
|
@@ -481,7 +499,7 @@ class BackendExpectationValueQulacs(BackendExpectationValue):
|
|
481
499
|
|
482
500
|
# map the reduced operators to the potentially smaller qubit system
|
483
501
|
qubit_map = {}
|
484
|
-
for i,q in enumerate(self.U.
|
502
|
+
for i, q in enumerate(self.U.abstract_qubits):
|
485
503
|
qubit_map[q] = i
|
486
504
|
|
487
505
|
result = []
|
@@ -495,7 +513,9 @@ class BackendExpectationValueQulacs(BackendExpectationValue):
|
|
495
513
|
result.append(qulacs_H)
|
496
514
|
return result
|
497
515
|
|
498
|
-
def sample(
|
516
|
+
def sample(
|
517
|
+
self, variables, samples, initial_state: Union[int, QubitWaveFunction] = 0, *args, **kwargs
|
518
|
+
) -> numpy.array:
|
499
519
|
"""
|
500
520
|
Sample this Expectation Value.
|
501
521
|
Parameters
|
@@ -504,6 +524,8 @@ class BackendExpectationValueQulacs(BackendExpectationValue):
|
|
504
524
|
variables, to supply to the underlying circuit.
|
505
525
|
samples: int:
|
506
526
|
the number of samples to take.
|
527
|
+
initial_state: int or QubitWaveFunction:
|
528
|
+
the initial state of the circuit
|
507
529
|
args
|
508
530
|
kwargs
|
509
531
|
|
@@ -513,13 +535,15 @@ class BackendExpectationValueQulacs(BackendExpectationValue):
|
|
513
535
|
the result of sampling as a number.
|
514
536
|
"""
|
515
537
|
self.update_variables(variables)
|
516
|
-
state = self.U.initialize_state(self.n_qubits)
|
538
|
+
state = self.U.initialize_state(self.n_qubits, initial_state)
|
517
539
|
self.U.circuit.update_quantum_state(state)
|
518
540
|
result = []
|
519
|
-
for H in
|
541
|
+
for H in (
|
542
|
+
self._reduced_hamiltonians
|
543
|
+
): # those are the hamiltonians which where non-used qubits are already traced out
|
520
544
|
E = 0.0
|
521
545
|
if H.is_all_z() and not self.U.has_noise:
|
522
|
-
E = super().sample(samples=samples, variables=variables, *args, **kwargs)
|
546
|
+
E = super().sample(samples=samples, variables=variables, initial_state=initial_state, *args, **kwargs)
|
523
547
|
else:
|
524
548
|
for ps in H.paulistrings:
|
525
549
|
# change basis, measurement is destructive so the state will be copied
|
@@ -530,21 +554,23 @@ class BackendExpectationValueQulacs(BackendExpectationValue):
|
|
530
554
|
qbc = self.U.create_circuit(abstract_circuit=bc, variables=None)
|
531
555
|
Esamples = []
|
532
556
|
for sample in range(samples):
|
533
|
-
if self.U.has_noise and sample>0:
|
534
|
-
state = self.U.initialize_state(self.n_qubits)
|
557
|
+
if self.U.has_noise and sample > 0:
|
558
|
+
state = self.U.initialize_state(self.n_qubits, initial_state)
|
535
559
|
self.U.circuit.update_quantum_state(state)
|
536
560
|
state_tmp = state
|
537
561
|
else:
|
538
562
|
state_tmp = state.copy()
|
539
|
-
if
|
563
|
+
if (
|
564
|
+
len(bc.gates) > 0
|
565
|
+
): # otherwise there is no basis change (empty qulacs circuit does not work out)
|
540
566
|
qbc.update_quantum_state(state_tmp)
|
541
567
|
ps_measure = 1.0
|
542
568
|
for idx in ps.keys():
|
543
|
-
assert idx in self.U.abstract_qubits
|
569
|
+
assert idx in self.U.abstract_qubits # assert that the hamiltonian was really reduced
|
544
570
|
M = qulacs.gate.Measurement(self.U.qubit(idx), self.U.qubit(idx))
|
545
571
|
M.update_quantum_state(state_tmp)
|
546
572
|
measured = state_tmp.get_classical_value(self.U.qubit(idx))
|
547
|
-
ps_measure *=
|
573
|
+
ps_measure *= -2.0 * measured + 1.0 # 0 becomes 1 and 1 becomes -1
|
548
574
|
Esamples.append(ps_measure)
|
549
575
|
E += ps.coeff * sum(Esamples) / len(Esamples)
|
550
576
|
result.append(E)
|