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
@@ -4,8 +4,10 @@ from tequila.circuit.circuit import QCircuit
4
4
  from tequila.hamiltonian.qubit_hamiltonian import QubitHamiltonian
5
5
  from scipy.stats import unitary_group, ortho_group
6
6
 
7
- def make_random_circuit(n_qubits: int, rotation_gates: list=['rx', 'ry', 'rz'], n_rotations: int=None,
8
- enable_controls: bool=None) -> QCircuit:
7
+
8
+ def make_random_circuit(
9
+ n_qubits: int, rotation_gates: list = ["rx", "ry", "rz"], n_rotations: int = None, enable_controls: bool = None
10
+ ) -> QCircuit:
9
11
  """Function that creates a circuit with random rotations or random control rotations.
10
12
 
11
13
  Args:
@@ -15,37 +17,38 @@ def make_random_circuit(n_qubits: int, rotation_gates: list=['rx', 'ry', 'rz'],
15
17
  enable_controls (bool): Boolean that switch on controls. Default to None.
16
18
 
17
19
  Returns:
18
- QCircuit: Random quantum circuit consiting of the given rotations gates
20
+ QCircuit: Random quantum circuit consiting of the given rotations gates
19
21
  and their controlled versions
20
22
  """
21
23
  if n_rotations is None:
22
- n_rotations = np.random.randint(n_qubits, high=n_qubits*3)
24
+ n_rotations = np.random.randint(n_qubits, high=n_qubits * 3)
23
25
 
24
26
  gates_list = [np.random.choice(rotation_gates) for i in range(n_rotations)]
25
-
26
- angles = 2*np.pi * np.random.rand(n_rotations)
27
-
27
+
28
+ angles = 2 * np.pi * np.random.rand(n_rotations)
29
+
28
30
  circ = QCircuit()
29
31
  for i, angle in enumerate(angles):
30
- target = i%n_qubits
32
+ target = i % n_qubits
31
33
  if enable_controls:
32
34
  controls = [i for i in circ.qubits if i != target]
33
35
  control = np.random.choice(controls + [None])
34
- else:
36
+ else:
35
37
  control = None
36
38
 
37
- if gates_list[i]=='rx':
39
+ if gates_list[i] == "rx":
38
40
  circ += gates.Rx(angle=angle, target=target, control=control)
39
-
40
- elif gates_list[i]=='ry':
41
+
42
+ elif gates_list[i] == "ry":
41
43
  circ += gates.Ry(angle=angle, target=target, control=control)
42
-
43
- elif gates_list[i]=='rz':
44
+
45
+ elif gates_list[i] == "rz":
44
46
  circ += gates.Rz(angle=angle, target=target, control=control)
45
-
47
+
46
48
  return circ
47
49
 
48
- def make_random_hamiltonian(n_qubits: int , paulis: list=['X','Y','Z'], n_ps: int = None) -> QubitHamiltonian:
50
+
51
+ def make_random_hamiltonian(n_qubits: int, paulis: list = ["X", "Y", "Z"], n_ps: int = None) -> QubitHamiltonian:
49
52
  """Function that creates a random Hamiltonian, given the list
50
53
  of Pauli ops. to use and the number of Pauli strings.
51
54
 
@@ -58,27 +61,28 @@ def make_random_hamiltonian(n_qubits: int , paulis: list=['X','Y','Z'], n_ps: in
58
61
  tq.QubitHamiltonian: Random Hamiltonian
59
62
  """
60
63
  if n_ps is None:
61
- n_ps = np.random.randint(1, high=2*n_qubits+1)
62
-
63
- ham = ''
64
+ n_ps = np.random.randint(1, high=2 * n_qubits + 1)
65
+
66
+ ham = ""
64
67
  for ps in range(n_ps):
65
- coeff = '{}*'.format(round(np.random.sample(),2))
66
- pauli_str = ''
68
+ coeff = "{}*".format(round(np.random.sample(), 2))
69
+ pauli_str = ""
67
70
  for qb in range(n_qubits):
68
- pauli_str += '{}({})'.format(np.random.choice(paulis), qb)
69
-
70
- if ps < n_ps-1:
71
- pauli_str += '+'
72
-
73
- ham += coeff+pauli_str
74
-
75
- #print(ham)
76
-
71
+ pauli_str += "{}({})".format(np.random.choice(paulis), qb)
72
+
73
+ if ps < n_ps - 1:
74
+ pauli_str += "+"
75
+
76
+ ham += coeff + pauli_str
77
+
78
+ # print(ham)
79
+
77
80
  H = QubitHamiltonian(ham)
78
81
  return H
79
82
 
80
- def generate_random_unitary(size, complex = False):
81
- '''
83
+
84
+ def generate_random_unitary(size, complex=False):
85
+ """
82
86
  Generates a random unitary (or furthermore orthogonal if complex is False) matrix of a specified size.
83
87
 
84
88
  Parameters:
@@ -87,8 +91,8 @@ def generate_random_unitary(size, complex = False):
87
91
 
88
92
  Returns:
89
93
  - numpy.ndarray: A randomly generated unitary matrix.
90
- '''
94
+ """
91
95
  if complex:
92
96
  return unitary_group.rvs(size)
93
97
  else:
94
- return ortho_group.rvs(size)
98
+ return ortho_group.rvs(size)
@@ -43,14 +43,14 @@ class BitString:
43
43
  @property
44
44
  def binary(self):
45
45
  if self.numbering is BitNumbering.MSB:
46
- return format(self._value, 'b').zfill(self.nbits)
46
+ return format(self._value, "b").zfill(self.nbits)
47
47
  else:
48
- return format(self._value, 'b').zfill(self.nbits)[::-1]
48
+ return format(self._value, "b").zfill(self.nbits)[::-1]
49
49
 
50
50
  @binary.setter
51
51
  def binary(self, other: str):
52
- assert (isinstance(other, str))
53
- if other.startswith('0b'):
52
+ assert isinstance(other, str)
53
+ if other.startswith("0b"):
54
54
  other = other[2:]
55
55
  if self.numbering == BitNumbering.LSB:
56
56
  self._value = int(other[::-1], 2)
@@ -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]
@@ -172,7 +178,6 @@ class BitString:
172
178
 
173
179
 
174
180
  class BitStringLSB(BitString):
175
-
176
181
  @property
177
182
  def numbering(self) -> BitNumbering:
178
183
  return BitNumbering.LSB
@@ -191,8 +196,9 @@ def reverse_int_bits(x: int, nbits: int) -> int:
191
196
  return x >> (32 - nbits)
192
197
 
193
198
 
194
- def initialize_bitstring(integer: int, nbits: int = None, numbering_in: BitNumbering = BitNumbering.MSB,
195
- numbering_out: BitNumbering = None):
199
+ def initialize_bitstring(
200
+ integer: int, nbits: int = None, numbering_in: BitNumbering = BitNumbering.MSB, numbering_out: BitNumbering = None
201
+ ):
196
202
  if numbering_out is None:
197
203
  numbering_out = numbering_in
198
204
 
@@ -31,9 +31,16 @@ class TequilaParameterError(TequilaException):
31
31
  """
32
32
 
33
33
  def __init__(self, parameter_name, parameter_class, parameter_value, called_from=""):
34
- self.message = "OpenVQE ParameterError:" + called_from + " unknown parameter value: " + str(
35
- parameter_name) + "=" + str(
36
- parameter_value) + " for " + str(parameter_class)
34
+ self.message = (
35
+ "OpenVQE ParameterError:"
36
+ + called_from
37
+ + " unknown parameter value: "
38
+ + str(parameter_name)
39
+ + "="
40
+ + str(parameter_value)
41
+ + " for "
42
+ + str(parameter_class)
43
+ )
37
44
 
38
45
 
39
46
  class TequilaTypeError(TequilaException):
@@ -42,5 +49,12 @@ class TequilaTypeError(TequilaException):
42
49
  """
43
50
 
44
51
  def __init__(self, attr, type, expected):
45
- self.message = "OpenVQE TypeError: " + "excpected type: " + str(expected) + " but got type " + str(
46
- type) + " for attribute " + str(attr)
52
+ self.message = (
53
+ "OpenVQE TypeError: "
54
+ + "excpected type: "
55
+ + str(expected)
56
+ + " but got type "
57
+ + str(type)
58
+ + " for attribute "
59
+ + str(attr)
60
+ )
@@ -1,12 +1,12 @@
1
1
  class JoinedTransformation:
2
- '''
2
+ """
3
3
  class structure used to construct,track, and permit differentiation of the computation required
4
4
  by mathematical operations on ExpectationValues,Variables and Objectives thereof.
5
5
  JoinedTransformations allow operations to be combined.
6
- '''
6
+ """
7
7
 
8
8
  def __init__(self, left, right, split, op):
9
- '''
9
+ """
10
10
  :param left: Callable: the lefthand operation, one level down
11
11
  :param right: Callable: the righthand operation, one level down
12
12
  :param split: Int: the position in the call method, at which lefthand and righthand arguments split
@@ -15,21 +15,21 @@ class JoinedTransformation:
15
15
  Example: split 2, left = numpy.add, right= numpy.subtract, op = numpy.multiply, call on list of length 4:
16
16
  then the Joined Transform performs the following computation when called:
17
17
  np.Multiply(np.add(arg_0,arg_1),np.subtract(arg_2,arg_3))
18
- '''
18
+ """
19
19
  self.split = split
20
20
  self.left = left
21
21
  self.right = right
22
22
  self.op = op
23
23
 
24
24
  def __call__(self, *args, **kwargs):
25
- '''
25
+ """
26
26
 
27
27
  :param args: iter: the arguments to the transformation.
28
28
  :param kwargs: dict: keyword arguments to the transformation. Must be uniform.
29
29
  :return: a number, the result of the calculation.
30
- '''
31
- E_left = args[:self.split]
32
- E_right = args[self.split:]
30
+ """
31
+ E_left = args[: self.split]
32
+ E_right = args[self.split :]
33
33
  if self.op is None:
34
34
  if len(args) == 1:
35
35
  return args[0]
@@ -39,13 +39,11 @@ class JoinedTransformation:
39
39
  print(len(args))
40
40
  return self.op(*args)
41
41
  else:
42
-
43
42
  return self.op(self.left(*E_left, **kwargs), *E_right)
44
43
  if self.left is None:
45
44
  if self.right is None:
46
45
  return self.op(*args)
47
46
  else:
48
-
49
47
  return self.op(*E_left, self.right(*E_right, **kwargs))
50
48
  else:
51
49
  return self.op(self.left(*E_left, **kwargs), self.right(*E_right, **kwargs))
tequila/utils/keymap.py CHANGED
@@ -4,7 +4,6 @@ from tequila import BitNumbering, BitString, BitStringLSB
4
4
 
5
5
 
6
6
  class KeyMapABC:
7
-
8
7
  @property
9
8
  def n_qubits(self):
10
9
  return None
@@ -18,7 +17,6 @@ class KeyMapABC:
18
17
 
19
18
 
20
19
  class KeyMapLSB2MSB(KeyMapABC):
21
-
22
20
  def __call__(self, input_state: BitStringLSB, initial_state: int = None) -> BitString:
23
21
  if isinstance(input_state, numbers.Integral):
24
22
  return BitString.from_int(integer=input_state)
@@ -27,7 +25,6 @@ class KeyMapLSB2MSB(KeyMapABC):
27
25
 
28
26
 
29
27
  class KeyMapMSB2LSB(KeyMapABC):
30
-
31
28
  @property
32
29
  def numbering(self) -> BitNumbering:
33
30
  return BitNumbering.LSB
@@ -40,7 +37,6 @@ class KeyMapMSB2LSB(KeyMapABC):
40
37
 
41
38
 
42
39
  class KeyMapSubregisterToRegister(KeyMapABC):
43
-
44
40
  @property
45
41
  def n_qubits(self):
46
42
  return len(self.register)
@@ -93,7 +89,6 @@ class KeyMapSubregisterToRegister(KeyMapABC):
93
89
 
94
90
 
95
91
  class KeyMapRegisterToSubregister(KeyMapSubregisterToRegister):
96
-
97
92
  def __call__(self, input_state: BitString, initial_state: BitString = None) -> BitString:
98
93
  """
99
94
  Map from register to subregister
tequila/utils/misc.py CHANGED
@@ -7,20 +7,22 @@ def to_float(number) -> float:
7
7
  """
8
8
 
9
9
  if hasattr(number, "imag"):
10
- if isclose(number.imag, 0.0, atol=1.e-6):
10
+ if isclose(number.imag, 0.0, atol=1.0e-6):
11
11
  return float64(number.real)
12
12
  else:
13
13
  raise TypeError("imaginary part detected {number}".format(number=number))
14
14
  elif hasattr(number, "evalf"):
15
15
  tmp = complex64(number.evalf())
16
- if hasattr(tmp, "imag") and isclose(tmp.imag, 0.0, atol=1.e-6):
16
+ if hasattr(tmp, "imag") and isclose(tmp.imag, 0.0, atol=1.0e-6):
17
17
  return float64(tmp.real)
18
18
  else:
19
19
  raise TypeError(
20
- "casting number {number} of type {type} fo float failed".format(number=number, type=type(number)))
20
+ "casting number {number} of type {type} fo float failed".format(number=number, type=type(number))
21
+ )
21
22
  else:
22
23
  try:
23
24
  return float64(number)
24
25
  except TypeError:
25
26
  raise TypeError(
26
- "casting number {number} of type {type} fo float failed".format(number=number, type=type(number)))
27
+ "casting number {number} of type {type} fo float failed".format(number=number, type=type(number))
28
+ )
tequila/version.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "1.9.8"
1
+ __version__ = "1.9.10"
2
2
  __author__ = "Tequila Developers "
@@ -28,8 +28,9 @@ class QubitWaveFunction:
28
28
  Does not enforce normalization.
29
29
  """
30
30
 
31
- def __init__(self, n_qubits: int, numbering: BitNumbering = BitNumbering.MSB, dense: bool = False,
32
- init_state: bool = True) -> None:
31
+ def __init__(
32
+ self, n_qubits: int, numbering: BitNumbering = BitNumbering.MSB, dense: bool = False, init_state: bool = True
33
+ ) -> None:
33
34
  """
34
35
  Initialize a QubitWaveFunction with all amplitudes set to zero.
35
36
 
@@ -43,13 +44,14 @@ class QubitWaveFunction:
43
44
  self._numbering = numbering
44
45
  self._dense = dense
45
46
  if init_state:
46
- self._state = np.zeros(2 ** self._n_qubits, dtype=complex) if dense else dict()
47
+ self._state = np.zeros(2**self._n_qubits, dtype=complex) if dense else dict()
47
48
  else:
48
49
  self._state = None
49
50
 
50
51
  @classmethod
51
- def from_wavefunction(cls, wfn: QubitWaveFunction, keymap: KeyMapABC = None, n_qubits: int = None,
52
- initial_state: BitString = None) -> QubitWaveFunction:
52
+ def from_wavefunction(
53
+ cls, wfn: QubitWaveFunction, keymap: KeyMapABC = None, n_qubits: int = None, initial_state: BitString = None
54
+ ) -> QubitWaveFunction:
53
55
  """
54
56
  Create a copy of a wavefunction.
55
57
 
@@ -66,7 +68,9 @@ class QubitWaveFunction:
66
68
  if wfn._dense and wfn._state.dtype == object:
67
69
  result = sympy.Integer(1) * result
68
70
  for index, coeff in wfn.raw_items():
69
- key = initialize_bitstring(index, wfn._n_qubits, numbering_in=wfn._numbering, numbering_out=keymap.numbering)
71
+ key = initialize_bitstring(
72
+ index, wfn._n_qubits, numbering_in=wfn._numbering, numbering_out=keymap.numbering
73
+ )
70
74
  key = keymap(key, initial_state)
71
75
  result[key] += coeff
72
76
  return result
@@ -74,8 +78,9 @@ class QubitWaveFunction:
74
78
  return deepcopy(wfn)
75
79
 
76
80
  @classmethod
77
- def from_array(cls, array: npt.NDArray[complex], numbering: BitNumbering = BitNumbering.MSB,
78
- copy: bool = True) -> QubitWaveFunction:
81
+ def from_array(
82
+ cls, array: npt.NDArray[complex], numbering: BitNumbering = BitNumbering.MSB, copy: bool = True
83
+ ) -> QubitWaveFunction:
79
84
  """
80
85
  Create a dense wavefunction from a Numpy array.
81
86
 
@@ -93,8 +98,9 @@ class QubitWaveFunction:
93
98
  return result
94
99
 
95
100
  @classmethod
96
- def from_basis_state(cls, n_qubits: int, basis_state: Union[int, BitString],
97
- numbering: BitNumbering = BitNumbering.MSB) -> QubitWaveFunction:
101
+ def from_basis_state(
102
+ cls, n_qubits: int, basis_state: Union[int, BitString], numbering: BitNumbering = BitNumbering.MSB
103
+ ) -> QubitWaveFunction:
98
104
  """
99
105
  Create a sparse wavefunction that is a basis state.
100
106
 
@@ -103,11 +109,14 @@ class QubitWaveFunction:
103
109
  :param numbering: Whether the first qubit is the most or least significant.
104
110
  :return: The created wavefunction.
105
111
  """
106
- if 2 ** n_qubits <= basis_state:
112
+ if 2**n_qubits <= basis_state:
107
113
  raise ValueError(f"Number of qubits {n_qubits} insufficient for basis state {basis_state}")
108
114
  if isinstance(basis_state, BitString):
109
- basis_state = reverse_int_bits(basis_state.integer,
110
- basis_state.nbits) if numbering != basis_state.numbering else basis_state.integer
115
+ basis_state = (
116
+ reverse_int_bits(basis_state.integer, basis_state.nbits)
117
+ if numbering != basis_state.numbering
118
+ else basis_state.integer
119
+ )
111
120
  result = QubitWaveFunction(n_qubits, numbering)
112
121
  result[basis_state] = 1.0
113
122
  return result
@@ -134,7 +143,7 @@ class QubitWaveFunction:
134
143
  result[index] = coeff
135
144
  return result
136
145
  except ValueError:
137
- raise TequilaException(f"Failed to initialize QubitWaveFunction from string:\n\"{string}\"\n")
146
+ raise TequilaException(f'Failed to initialize QubitWaveFunction from string:\n"{string}"\n')
138
147
 
139
148
  @classmethod
140
149
  def convert_from(cls, n_qubits: int, val: Union[QubitWaveFunction, int, str, numpy.ndarray]):
@@ -192,7 +201,7 @@ class QubitWaveFunction:
192
201
  if self._dense and self._numbering == out_numbering:
193
202
  return self._state.copy() if copy else self._state
194
203
  else:
195
- result = np.zeros(2 ** self._n_qubits, dtype=complex)
204
+ result = np.zeros(2**self._n_qubits, dtype=complex)
196
205
  for k, v in self.raw_items():
197
206
  if self._numbering != out_numbering:
198
207
  k = reverse_int_bits(k, self._n_qubits)
@@ -208,9 +217,11 @@ class QubitWaveFunction:
208
217
  :param copy: Whether to copy the array or use it directly.
209
218
  If False, changes to the array or wavefunction will affect each other.
210
219
  """
211
- if len(value) != 2 ** self._n_qubits:
212
- raise ValueError(f"Wavefunction of {self._n_qubits} qubits must have {2 ** self._n_qubits} amplitudes, "
213
- f"received {len(value)}")
220
+ if len(value) != 2**self._n_qubits:
221
+ raise ValueError(
222
+ f"Wavefunction of {self._n_qubits} qubits must have {2**self._n_qubits} amplitudes, "
223
+ f"received {len(value)}"
224
+ )
214
225
  self._dense = True
215
226
  if copy:
216
227
  self._state = value.copy()
@@ -238,9 +249,11 @@ class QubitWaveFunction:
238
249
 
239
250
  def items(self) -> Generator[tuple[BitString, complex]]:
240
251
  """Returns a generator of non-zero amplitudes with BitString indices."""
241
- return ((initialize_bitstring(k, self._n_qubits, self._numbering), v)
242
- for k, v in self.raw_items()
243
- if isinstance(v, sympy.Basic) or abs(v) > 1e-6)
252
+ return (
253
+ (initialize_bitstring(k, self._n_qubits, self._numbering), v)
254
+ for k, v in self.raw_items()
255
+ if isinstance(v, sympy.Basic) or abs(v) > 1e-6
256
+ )
244
257
 
245
258
  def keys(self) -> Generator[BitString]:
246
259
  """Returns a generator of BitString indices of non-zero amplitudes."""
@@ -256,16 +269,20 @@ class QubitWaveFunction:
256
269
 
257
270
  raise TequilaException("Wavefunction equality is not well-defined. Consider using isclose.")
258
271
 
259
- def isclose(self: QubitWaveFunction,
260
- other: QubitWaveFunction,
261
- rtol: float = 1e-5,
262
- atol: float = 1e-8) -> bool:
272
+ def isclose(
273
+ self: QubitWaveFunction,
274
+ other: QubitWaveFunction,
275
+ rtol: float = 1e-5,
276
+ atol: float = 1e-8,
277
+ ignore_global_phase: bool = True,
278
+ ) -> bool:
263
279
  """
264
280
  Check if two wavefunctions are close, up to a global phase.
265
281
 
266
282
  :param other: The other wavefunction.
267
283
  :param rtol: Relative tolerance.
268
284
  :param atol: Absolute tolerance.
285
+ :param ignore_global_phase: Whether to ignore global phase differences.
269
286
  :return: Whether the wavefunctions are close.
270
287
  """
271
288
  inner = self.inner(other)
@@ -273,8 +290,10 @@ class QubitWaveFunction:
273
290
  other_norm = other.norm()
274
291
  cosine_similarity = inner / (self_norm * other_norm)
275
292
 
276
- return (np.isclose(abs(cosine_similarity), 1.0, rtol, atol)
277
- and np.isclose(self_norm, other_norm, rtol, atol))
293
+ if ignore_global_phase:
294
+ cosine_similarity = abs(cosine_similarity)
295
+
296
+ return np.isclose(cosine_similarity, 1.0, rtol, atol) and np.isclose(self_norm, other_norm, rtol, atol)
278
297
 
279
298
  def __add__(self, other: QubitWaveFunction) -> QubitWaveFunction:
280
299
  if self._dense and other._dense and self._numbering == other._numbering:
@@ -365,7 +384,7 @@ class QubitWaveFunction:
365
384
  # because the __mul__ implementation of the number tries to perform some sort of array
366
385
  # operation.
367
386
  def length(self):
368
- return sum(1 for _ in self.raw_items())
387
+ return sum(1 for (k, v) in self.raw_items() if abs(v) > 1e-6)
369
388
 
370
389
  def __repr__(self):
371
390
  result = str()
@@ -373,7 +392,10 @@ class QubitWaveFunction:
373
392
  index = index.integer
374
393
  if self.numbering == BitNumbering.LSB:
375
394
  index = reverse_int_bits(index, self._n_qubits)
376
- result += f"{coeff} |{index:0{self._n_qubits}b}> "
395
+ if np.isclose(coeff.imag, 0.0):
396
+ result += f"{coeff.real:+2.4f} |{index:0{self._n_qubits}b}> "
397
+ else:
398
+ result += f"({coeff.real:+2.4f} + {coeff.imag:+2.4f}i) |{index:0{self._n_qubits}b}> "
377
399
  # If the wavefunction contains no states
378
400
  if not result:
379
401
  result = "empty wavefunction"
@@ -382,7 +404,7 @@ class QubitWaveFunction:
382
404
  def compute_expectationvalue(self, operator: QubitHamiltonian) -> numbers.Real:
383
405
  tmp = self.apply_qubitoperator(operator=operator)
384
406
  E = self.inner(other=tmp)
385
- if hasattr(E, "imag") and np.isclose(E.imag, 0.0, atol=1.e-6):
407
+ if hasattr(E, "imag") and np.isclose(E.imag, 0.0, atol=1.0e-6):
386
408
  return float(E.real)
387
409
  else:
388
410
  return E
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: tequila-basic
3
- Version: 1.9.8
3
+ Version: 1.9.10
4
4
  Summary: A High-Level Abstraction Framework for Quantum Algorithms
5
5
  Home-page: https://github.com/tequilahub/tequila
6
6
  Author: Tequila Developers
@@ -15,6 +15,15 @@ Requires-Dist: setuptools
15
15
  Requires-Dist: pytest
16
16
  Requires-Dist: openfermion~=1.0
17
17
  Requires-Dist: dataclasses; python_version < "3.7"
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: description
21
+ Dynamic: description-content-type
22
+ Dynamic: home-page
23
+ Dynamic: license-file
24
+ Dynamic: provides-extra
25
+ Dynamic: requires-dist
26
+ Dynamic: summary
18
27
 
19
28
  [![License: MIT](https://img.shields.io/badge/License-MIT-lightgrey.svg)](LICENCE) [![DOI](https://zenodo.org/badge/259718912.svg)](https://zenodo.org/badge/latestdoi/259718912) [![PyPI version](https://badge.fury.io/py/tequila-basic.svg)](https://badge.fury.io/py/tequila-basic) ![CI](https://github.com/tequilahub/tequila/actions/workflows/ci_basic.yml/badge.svg)
20
29
 
@@ -27,7 +36,8 @@ Tequila can execute the underlying quantum expectation values on state of the ar
27
36
  # Getting Started
28
37
 
29
38
  Get started with our collection of
30
- - *[Tutorials](https://tequilahub.github.io/tequila-tutorials/)*
39
+ - *[Tutorials](https://tequilahub.github.io/tequila-tutorials/)*
40
+ - *[Documentation](https://tequilahub.github.io/tequila-tutorials/docs/sphinx/)*
31
41
 
32
42
  Further sources:
33
43
  - [overview article](https://arxiv.org/abs/2011.03057)
@@ -35,8 +45,8 @@ Further sources:
35
45
  - [talks and slides](https://kottmanj.github.io/talks_and_material/)
36
46
 
37
47
  # Installation
38
- Recommended Python version is 3.9 (3.10).
39
- Tequila supports linux, osx and windows. However, not all optional dependencies are supported on windows.
48
+ Recommended Python version is 3.10 (3.11).
49
+ Tequila supports linux, osx and windows. However, not all optional dependencies (especially chemistry) are supported on windows.
40
50
 
41
51
  ## Install from PyPi
42
52
  **Do not** install like this: (Minecraft lovers excluded)
@@ -47,7 +57,7 @@ You can install tequila from PyPi as:
47
57
  pip install tequila-basic
48
58
  ```
49
59
  this will install tequila with all essential dependencies.
50
- We recommend to install some fast quantum backends, like qulacs or qibo, as well.
60
+ We recommend to install some fast quantum backends, like qulacs, as well.
51
61
  Those can be installed before or after you install tequila.
52
62
  ```bash
53
63
  # install basic tequila
@@ -148,7 +158,7 @@ print("VQE : {:+2.8}f".format(result.energy))
148
158
  print("FCI : {:+2.8}f".format(fci))
149
159
  ```
150
160
 
151
- Do you want to create your own methods? Check out the [tutorials](https://github.com/tequilahub/tequila-tutorials)!
161
+ Do you want to create your own methods? Check out the [tutorials]([https://github.com/tequilahub/tequila-tutorials](https://tequilahub.github.io/tequila-tutorials/))!
152
162
 
153
163
  # Some Research projects using Tequila
154
164
  J.S. Kottmann, A. Anand, A. Aspuru-Guzik.
@@ -313,12 +323,7 @@ pip install pyscf
313
323
  Works similar as Psi4. Classical methods are also integrated in the madness interface allowing to use them in a basis-set-free representation.
314
324
 
315
325
  # Documentation
316
- You can build the documentation by navigating to `docs` and entering `make html`.
317
- Open the documentation with a browser over like `firefox docs/build/html/index.html`
318
- Note that you will need some additional python packages like `sphinx` and `mr2` that are not explicitly listed in the requirements.txt
319
-
320
- You can also visit our prebuild online [documentation](https://tequilahub.github.io/tequila/)
321
- that will correspond to the github master branch
326
+ see [here](https://tequilahub.github.io/tequila-tutorials/docs/sphinx/)
322
327
 
323
328
  # How to contribute
324
329
  If you find any bugs or inconveniences in `tequila` please don't be shy and let us know.
@@ -330,9 +335,11 @@ Here is how that works:
330
335
  1. Make a fork of `tequila` to your own github account.
331
336
  2. Checkout the `devel` branch and make sure it is up to date with the main [github repository](https://github.com/aspuru-guzik-group/tequila).
332
337
  3. Create and checkout a new branch from `devel` via `git branch pr-my-branch-name` followed by `git checkout pr-my-branch-name`. By typing `git branch` afterwards you can check which branch is currently checked out on your computer.
333
- 4. Introduce changes to the code and commit them with git.
334
- 5. Push the changes to *your* github account
335
- 6. Log into github and create a pull request to the main [github repository](https://github.com/aspuru-guzik-group/tequila). The pull-request should be directed to the `devel` branch (but we can also change that afterwards).
338
+ 4. Introduce changes to the code.
339
+ 5. Format your code using [Ruff](https://github.com/astral-sh/ruff).
340
+ You can install Ruff with `pip install ruff`, then run the formatter with `ruff format` and the linter with `ruff check` (most IDEs also provide a way of integrating Ruff and doing this automatically).
341
+ 6. Commit them with git and push the changes to *your* github account
342
+ 7. Log into github and create a pull request to the main [github repository](https://github.com/aspuru-guzik-group/tequila). The pull-request should be directed to the `devel` branch (but we can also change that afterwards).
336
343
 
337
344
  If you plan to introduce major changes to the base library it can be beneficial to contact us first.
338
345
  This way we might be able to avoid conflicts before they arise.
@@ -400,4 +407,3 @@ They can be installed for example over visual studio.
400
407
  Tequila runs on Mac OSX.
401
408
  You might get in trouble with installing qulacs since it currently does not work with Apple's clang compiler.
402
409
  You need to install latest GNU compile (at least gcc-7 and g++7) and set them as default before installing qulacs over pip.
403
-