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.
Files changed (86) hide show
  1. tequila/__init__.py +29 -14
  2. tequila/apps/__init__.py +14 -5
  3. tequila/apps/_unary_state_prep_impl.py +145 -112
  4. tequila/apps/adapt/__init__.py +9 -1
  5. tequila/apps/adapt/adapt.py +154 -113
  6. tequila/apps/krylov/__init__.py +1 -1
  7. tequila/apps/krylov/krylov.py +23 -21
  8. tequila/apps/robustness/helpers.py +10 -6
  9. tequila/apps/robustness/interval.py +238 -156
  10. tequila/apps/unary_state_prep.py +29 -23
  11. tequila/autograd_imports.py +8 -5
  12. tequila/circuit/__init__.py +2 -1
  13. tequila/circuit/_gates_impl.py +135 -67
  14. tequila/circuit/circuit.py +177 -88
  15. tequila/circuit/compiler.py +114 -105
  16. tequila/circuit/gates.py +288 -120
  17. tequila/circuit/gradient.py +35 -23
  18. tequila/circuit/noise.py +83 -74
  19. tequila/circuit/postselection.py +120 -0
  20. tequila/circuit/pyzx.py +10 -6
  21. tequila/circuit/qasm.py +201 -83
  22. tequila/circuit/qpic.py +63 -61
  23. tequila/grouping/binary_rep.py +148 -146
  24. tequila/grouping/binary_utils.py +84 -75
  25. tequila/grouping/compile_groups.py +334 -230
  26. tequila/grouping/ev_utils.py +77 -41
  27. tequila/grouping/fermionic_functions.py +383 -308
  28. tequila/grouping/fermionic_methods.py +170 -123
  29. tequila/grouping/overlapping_methods.py +69 -52
  30. tequila/hamiltonian/paulis.py +12 -13
  31. tequila/hamiltonian/paulistring.py +1 -1
  32. tequila/hamiltonian/qubit_hamiltonian.py +45 -35
  33. tequila/ml/__init__.py +1 -0
  34. tequila/ml/interface_torch.py +19 -16
  35. tequila/ml/ml_api.py +11 -10
  36. tequila/ml/utils_ml.py +12 -11
  37. tequila/objective/__init__.py +8 -3
  38. tequila/objective/braket.py +55 -47
  39. tequila/objective/objective.py +91 -56
  40. tequila/objective/qtensor.py +36 -27
  41. tequila/optimizers/__init__.py +31 -23
  42. tequila/optimizers/_containers.py +11 -7
  43. tequila/optimizers/optimizer_base.py +111 -83
  44. tequila/optimizers/optimizer_gd.py +258 -231
  45. tequila/optimizers/optimizer_gpyopt.py +56 -42
  46. tequila/optimizers/optimizer_scipy.py +157 -112
  47. tequila/quantumchemistry/__init__.py +66 -38
  48. tequila/quantumchemistry/chemistry_tools.py +394 -203
  49. tequila/quantumchemistry/encodings.py +121 -13
  50. tequila/quantumchemistry/madness_interface.py +170 -96
  51. tequila/quantumchemistry/orbital_optimizer.py +86 -40
  52. tequila/quantumchemistry/psi4_interface.py +166 -97
  53. tequila/quantumchemistry/pyscf_interface.py +70 -23
  54. tequila/quantumchemistry/qc_base.py +866 -414
  55. tequila/simulators/__init__.py +0 -3
  56. tequila/simulators/simulator_api.py +258 -106
  57. tequila/simulators/simulator_aqt.py +102 -0
  58. tequila/simulators/simulator_base.py +156 -55
  59. tequila/simulators/simulator_cirq.py +58 -42
  60. tequila/simulators/simulator_cudaq.py +600 -0
  61. tequila/simulators/simulator_ddsim.py +390 -0
  62. tequila/simulators/simulator_mqp.py +30 -0
  63. tequila/simulators/simulator_pyquil.py +190 -171
  64. tequila/simulators/simulator_qibo.py +95 -87
  65. tequila/simulators/simulator_qiskit.py +124 -114
  66. tequila/simulators/simulator_qlm.py +52 -26
  67. tequila/simulators/simulator_qulacs.py +85 -59
  68. tequila/simulators/simulator_spex.py +464 -0
  69. tequila/simulators/simulator_symbolic.py +6 -5
  70. tequila/simulators/test_spex_simulator.py +208 -0
  71. tequila/tools/convenience.py +4 -4
  72. tequila/tools/qng.py +72 -64
  73. tequila/tools/random_generators.py +38 -34
  74. tequila/utils/bitstrings.py +13 -7
  75. tequila/utils/exceptions.py +19 -5
  76. tequila/utils/joined_transformation.py +8 -10
  77. tequila/utils/keymap.py +0 -5
  78. tequila/utils/misc.py +6 -4
  79. tequila/version.py +1 -1
  80. tequila/wavefunction/qubit_wavefunction.py +52 -30
  81. {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info}/METADATA +23 -17
  82. tequila_basic-1.9.10.dist-info/RECORD +93 -0
  83. {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info}/WHEEL +1 -1
  84. tequila_basic-1.9.8.dist-info/RECORD +0 -86
  85. {tequila_basic-1.9.8.dist-info → tequila_basic-1.9.10.dist-info/licenses}/LICENSE +0 -0
  86. {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, numpy
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, # needed for gates depending on variables
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
- 'I': qulacs.gate.Identity,
87
- 'X': qulacs.gate.X,
88
- 'Y': qulacs.gate.Y,
89
- 'Z': qulacs.gate.Z,
90
- 'H': qulacs.gate.H,
91
- 'Rx': (lambda c: c.add_parametric_RX_gate, qulacs.gate.RX),
92
- 'Ry': (lambda c: c.add_parametric_RY_gate, qulacs.gate.RY),
93
- 'Rz': (lambda c: c.add_parametric_RZ_gate, qulacs.gate.RZ),
94
- 'SWAP': qulacs.gate.SWAP,
95
- 'Measure': qulacs.gate.Measurement,
96
- 'Exp-Pauli': None
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
- warnings.warn("Warning: noise in qulacs module will be dropped. Currently only works for qulacs version 0.5 or lower", TequilaWarning)
105
-
106
- self.has_noise=True
111
+ self.has_noise = True
107
112
  self.noise_lookup = {
108
- 'bit flip': [qulacs.gate.BitFlipNoise],
109
- 'phase flip': [lambda target, prob: qulacs.gate.Probabilistic([prob],[qulacs.gate.Z(target)])],
110
- 'phase damp': [lambda target, prob: qulacs.gate.DephasingNoise(target,(1/2)*(1-numpy.sqrt(1-prob)))],
111
- 'amplitude damp': [qulacs.gate.AmplitudeDampingNoise],
112
- 'phase-amplitude damp': [qulacs.gate.AmplitudeDampingNoise,
113
- lambda target, prob: qulacs.gate.DephasingNoise(target,(1/2)*(1-numpy.sqrt(1-prob)))
114
- ],
115
- 'depolarizing': [lambda target,prob: qulacs.gate.DepolarizingNoise(target,3*prob/4)]
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(self, n_qubits: int = None, initial_state: Union[int, QubitWaveFunction] = None) -> qulacs.QuantumState:
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 = {'x': 1, 'y': 2, 'z': 3}
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(qind, pind,
278
- -gate.parameter(variables) * gate.paulistring.coeff)
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 == 'Exp-Pauli':
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("Gates which depend on variables can not be controlled! Gate was:\n{}".format(gate))
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("qulacs: optimized circuit depth from {} to {} with max_block_size {}".format(old,
419
- circuit.calculate_depth(),
420
- max_block_size))
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) # those are accumulated unit strings, e.g 0.1*X(3) in wfn on qubits 0,1
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.abstract_circuit.qubits):
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(self, variables, samples, *args, **kwargs) -> numpy.array:
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 self._reduced_hamiltonians: # those are the hamiltonians which where non-used qubits are already traced out
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 len(bc.gates) > 0: # otherwise there is no basis change (empty qulacs circuit does not work out)
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 # assert that the hamiltonian was really reduced
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 *= (-2.0 * measured + 1.0) # 0 becomes 1 and 1 becomes -1
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)