tequila-basic 1.9.6__py3-none-any.whl → 1.9.8__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.
@@ -89,7 +89,6 @@ class UnaryStatePrep:
89
89
  simulator.convert_to_numpy = False
90
90
  variables = None # {k:k.name.evalf() for k in self._abstract_circuit.extract_variables()}
91
91
  wfn = simulator.simulate(initial_state=BitString.from_int(0, nbits=self.n_qubits), variables=variables)
92
- wfn.n_qubits = self._n_qubits
93
92
  equations = []
94
93
  for k in target_space:
95
94
  equations.append(wfn[k] - abstract_coefficients[k])
@@ -174,7 +173,7 @@ class UnaryStatePrep:
174
173
  :return:
175
174
  """
176
175
  try:
177
- assert (len(wfn) == len(self._target_space))
176
+ assert wfn.length() == len(self._target_space)
178
177
  for key in wfn.keys():
179
178
  try:
180
179
  assert (key in self._target_space)
@@ -46,10 +46,7 @@ class QCircuit():
46
46
  Convenience: see src/tequila/circuit/qpic.py - export_to for more
47
47
  Parameters
48
48
  """
49
- # this way we allow calling U.export_to("asd.png") instead of having to specify U.export_to(filename="asd.png")
50
- if "circuit" not in kwargs:
51
- kwargs["circuit"]=self
52
- return export_to(*args, **kwargs)
49
+ return export_to(self, *args, **kwargs)
53
50
 
54
51
  @property
55
52
  def moments(self):
@@ -389,7 +386,7 @@ class QCircuit():
389
386
  for k, v in other._parameter_map.items():
390
387
  self._parameter_map[k] += [(x[0] + offset, x[1]) for x in v]
391
388
 
392
- self._gates += other.gates
389
+ self._gates += copy.deepcopy(other.gates)
393
390
  self._min_n_qubits = max(self._min_n_qubits, other._min_n_qubits)
394
391
 
395
392
  return self
@@ -256,7 +256,7 @@ def Projector(wfn, threshold=0.0, n_qubits=None) -> QubitHamiltonian:
256
256
 
257
257
  """
258
258
 
259
- wfn = QubitWaveFunction(state=wfn, n_qubits=n_qubits)
259
+ wfn = QubitWaveFunction.convert_from(n_qubits, wfn)
260
260
 
261
261
  H = QubitHamiltonian.zero()
262
262
  for k1, v1 in wfn.items():
@@ -304,8 +304,9 @@ def KetBra(ket: QubitWaveFunction, bra: QubitWaveFunction, hermitian: bool = Fal
304
304
 
305
305
  """
306
306
  H = QubitHamiltonian.zero()
307
- ket = QubitWaveFunction(state=ket, n_qubits=n_qubits)
308
- bra = QubitWaveFunction(state=bra, n_qubits=n_qubits)
307
+
308
+ ket = QubitWaveFunction.convert_from(n_qubits, ket)
309
+ bra = QubitWaveFunction.convert_from(n_qubits, bra)
309
310
 
310
311
  for k1, v1 in bra.items():
311
312
  for k2, v2 in ket.items():
@@ -128,9 +128,9 @@ class EncodingBase(metaclass=abc.ABCMeta):
128
128
  fop = openfermion.FermionOperator(string, 1.0)
129
129
  op = self(fop)
130
130
  from tequila.wavefunction.qubit_wavefunction import QubitWaveFunction
131
- wfn = QubitWaveFunction.from_int(0, n_qubits=n_qubits)
131
+ wfn = QubitWaveFunction.from_basis_state(n_qubits, 0)
132
132
  wfn = wfn.apply_qubitoperator(operator=op)
133
- assert (len(wfn.keys()) == 1)
133
+ assert wfn.length() == 1
134
134
  key = list(wfn.keys())[0].array
135
135
  return key
136
136
 
@@ -208,11 +208,16 @@ class PySCFVQEWrapper:
208
208
  H = molecule.make_hardcore_boson_hamiltonian()
209
209
  else:
210
210
  H = molecule.make_hamiltonian()
211
+
212
+ rdm1 = None
213
+ rdm2 = None
211
214
  if self.vqe_solver is not None:
212
215
  vqe_solver_arguments = {}
213
216
  if self.vqe_solver_arguments is not None:
214
217
  vqe_solver_arguments = self.vqe_solver_arguments
215
218
  result = self.vqe_solver(H=H, circuit=self.circuit, molecule=molecule, **vqe_solver_arguments)
219
+ if hasattr(self.vqe_solver, "compute_rdms"):
220
+ rdm1, rdm2 = self.vqe_solver.compute_rdms(U=self.circuit, variables=result.variables, molecule=molecule, use_hcb=restrict_to_hcb)
216
221
  elif self.circuit is None:
217
222
  raise Exception("Orbital Optimizer: Either provide a callable vqe_solver or a circuit")
218
223
  else:
@@ -233,8 +238,9 @@ class PySCFVQEWrapper:
233
238
  # static ansatz
234
239
  U = self.circuit
235
240
 
236
- rdm1, rdm2 = molecule.compute_rdms(U=U, variables=result.variables, spin_free=True, get_rdm1=True, get_rdm2=True, use_hcb=restrict_to_hcb)
237
- rdm2 = self.reorder(rdm2, 'dirac', 'mulliken')
241
+ if rdm1 is None or rdm2 is None:
242
+ rdm1, rdm2 = molecule.compute_rdms(U=U, variables=result.variables, spin_free=True, get_rdm1=True, get_rdm2=True, use_hcb=restrict_to_hcb)
243
+ rdm2 = self.reorder(rdm2, 'dirac', 'mulliken')
238
244
  if not self.silent:
239
245
  print("{:20} : {}".format("energy", result.energy))
240
246
  if len(self.history) > 0:
@@ -259,3 +265,4 @@ class PySCFVQEWrapper:
259
265
  else:
260
266
  result += "{:30} : {}\n".format(k, v)
261
267
  return result
268
+
@@ -1737,7 +1737,7 @@ class QuantumChemistryBase:
1737
1737
 
1738
1738
  def compute_rdms(self, U: QCircuit = None, variables: Variables = None, spin_free: bool = True,
1739
1739
  get_rdm1: bool = True, get_rdm2: bool = True, ordering="dirac", use_hcb: bool = False,
1740
- rdm_trafo: QubitHamiltonian = None, decompose=None):
1740
+ rdm_trafo: QubitHamiltonian = None, evaluate=True):
1741
1741
  """
1742
1742
  Computes the one- and two-particle reduced density matrices (rdm1 and rdm2) given
1743
1743
  a unitary U. This method uses the standard ordering in physics as denoted below.
@@ -1768,7 +1768,10 @@ class QuantumChemistryBase:
1768
1768
  rdm_trafo :
1769
1769
  The rdm operators can be transformed, e.g., a^dagger_i a_j -> U^dagger a^dagger_i a_j U,
1770
1770
  where U represents the transformation. The default is set to None, implying that U equas the identity.
1771
-
1771
+ evaluate :
1772
+ if true, the tequila expectation values are evaluated directly via the tq.simulate command.
1773
+ the protocol is optimized to avoid repetation of wavefunction simulation
1774
+ if false, the rdms are returned as tq.QTensors
1772
1775
  Returns
1773
1776
  -------
1774
1777
  """
@@ -1891,13 +1894,14 @@ class QuantumChemistryBase:
1891
1894
  ops += [op]
1892
1895
  return ops
1893
1896
 
1894
- def _assemble_rdm1(evals) -> numpy.ndarray:
1897
+ def _assemble_rdm1(evals, rdm1=None) -> numpy.ndarray:
1895
1898
  """
1896
1899
  Returns spin-ful or spin-free one-particle RDM built by symmetry conditions
1897
1900
  Same symmetry with or without spin, so we can use the same function
1898
1901
  """
1899
1902
  N = n_MOs if spin_free else n_SOs
1900
- rdm1 = numpy.zeros([N, N])
1903
+ if rdm1 is None:
1904
+ rdm1 = numpy.zeros([N, N])
1901
1905
  ctr: int = 0
1902
1906
  for p in range(N):
1903
1907
  for q in range(p + 1):
@@ -1908,10 +1912,11 @@ class QuantumChemistryBase:
1908
1912
 
1909
1913
  return rdm1
1910
1914
 
1911
- def _assemble_rdm2_spinful(evals) -> numpy.ndarray:
1915
+ def _assemble_rdm2_spinful(evals, rdm2=None) -> numpy.ndarray:
1912
1916
  """ Returns spin-ful two-particle RDM built by symmetry conditions """
1913
1917
  ctr: int = 0
1914
- rdm2 = numpy.zeros([n_SOs, n_SOs, n_SOs, n_SOs])
1918
+ if rdm2 is None:
1919
+ rdm2 = numpy.zeros([n_SOs, n_SOs, n_SOs, n_SOs])
1915
1920
  for p in range(n_SOs):
1916
1921
  for q in range(p):
1917
1922
  for r in range(n_SOs):
@@ -1933,10 +1938,11 @@ class QuantumChemistryBase:
1933
1938
 
1934
1939
  return rdm2
1935
1940
 
1936
- def _assemble_rdm2_spinfree(evals) -> numpy.ndarray:
1941
+ def _assemble_rdm2_spinfree(evals, rdm2=None) -> numpy.ndarray:
1937
1942
  """ Returns spin-free two-particle RDM built by symmetry conditions """
1938
1943
  ctr: int = 0
1939
- rdm2 = numpy.zeros([n_MOs, n_MOs, n_MOs, n_MOs])
1944
+ if rdm2 is None:
1945
+ rdm2 = numpy.zeros([n_MOs, n_MOs, n_MOs, n_MOs])
1940
1946
  for p, q, r, s in product(range(n_MOs), repeat=4):
1941
1947
  if p * n_MOs + q >= r * n_MOs + s and (p >= q or r >= s):
1942
1948
  rdm2[p, q, r, s] = evals[ctr]
@@ -2012,18 +2018,25 @@ class QuantumChemistryBase:
2012
2018
  # Transform operator lists to QubitHamiltonians
2013
2019
  if (not use_hcb):
2014
2020
  qops = [_get_qop_hermitian(op) for op in qops]
2015
-
2021
+
2016
2022
  # Compute expected values
2017
- if rdm_trafo is None:
2018
- if decompose is not None:
2019
- print("MANIPULATED")
2020
- X = decompose(H=qops, U=U)
2021
- evals = simulate(X, variables=variables)
2023
+ rdm1 = None
2024
+ rdm2 = None
2025
+ from tequila import QTensor
2026
+ if evaluate:
2027
+ if rdm_trafo is None:
2028
+ evals = simulate(ExpectationValue(H=qops, U=U, shape=[len(qops)]), variables=variables)
2022
2029
  else:
2030
+ qops = [rdm_trafo.dagger()*qops[i]*rdm_trafo for i in range(len(qops))]
2023
2031
  evals = simulate(ExpectationValue(H=qops, U=U, shape=[len(qops)]), variables=variables)
2024
2032
  else:
2025
- qops = [rdm_trafo.dagger()*qops[i]*rdm_trafo for i in range(len(qops))]
2026
- evals = simulate(ExpectationValue(H=qops, U=U, shape=[len(qops)]), variables=variables)
2033
+ if rdm_trafo is None:
2034
+ evals = [ExpectationValue(H=x, U=U) for x in qops]
2035
+ N = n_MOs if spin_free else n_SOs
2036
+ rdm1 = QTensor(shape=[N,N])
2037
+ rdm2 = QTensor(shape=[N, N, N, N])
2038
+ else:
2039
+ raise TequilaException("compute_rdms: rdm_trafo was set but evaluate flag is False (not supported)")
2027
2040
 
2028
2041
  # Assemble density matrices
2029
2042
  # If self._rdm1, self._rdm2 exist, reset them if they are of the other spin-type
@@ -2044,11 +2057,11 @@ class QuantumChemistryBase:
2044
2057
  len_1 = 0
2045
2058
  evals_1, evals_2 = evals[:len_1], evals[len_1:]
2046
2059
  # Build matrices using the expectation values
2047
- self._rdm1 = _assemble_rdm1(evals_1) if get_rdm1 else self._rdm1
2060
+ self._rdm1 = _assemble_rdm1(evals_1, rdm1=rdm1) if get_rdm1 else self._rdm1
2048
2061
  if spin_free or use_hcb:
2049
- self._rdm2 = _assemble_rdm2_spinfree(evals_2) if get_rdm2 else self._rdm2
2062
+ self._rdm2 = _assemble_rdm2_spinfree(evals_2, rdm2=rdm2) if get_rdm2 else self._rdm2
2050
2063
  else:
2051
- self._rdm2 = _assemble_rdm2_spinful(evals_2) if get_rdm2 else self._rdm2
2064
+ self._rdm2 = _assemble_rdm2_spinful(evals_2, rdm2=rdm2) if get_rdm2 else self._rdm2
2052
2065
 
2053
2066
  if get_rdm2:
2054
2067
  rdm2 = NBodyTensor(elems=self.rdm2, ordering="dirac", verify=False)
@@ -9,9 +9,10 @@ from tequila.objective import Objective, Variable, assign_variable, format_varia
9
9
  from tequila.utils.exceptions import TequilaException, TequilaWarning
10
10
  from tequila.simulators.simulator_base import BackendCircuit, BackendExpectationValue
11
11
  from tequila.circuit.noise import NoiseModel
12
+ from tequila.wavefunction.qubit_wavefunction import QubitWaveFunction
12
13
 
13
- SUPPORTED_BACKENDS = ["qulacs_gpu", "qulacs",'qibo', "qiskit", "cirq", "pyquil", "symbolic", "qlm"]
14
- SUPPORTED_NOISE_BACKENDS = ["qiskit", 'cirq', 'pyquil'] # qulacs removed in v.1.9
14
+ SUPPORTED_BACKENDS = ["qulacs", "qulacs_gpu", "qibo", "qiskit", "qiskit_gpu", "cirq", "pyquil", "symbolic", "qlm"]
15
+ SUPPORTED_NOISE_BACKENDS = ["qiskit", "qiskit_gpu", "cirq", "pyquil"] # qulacs removed in v.1.9
15
16
  BackendTypes = namedtuple('BackendTypes', 'CircType ExpValueType')
16
17
  INSTALLED_SIMULATORS = {}
17
18
  INSTALLED_SAMPLERS = {}
@@ -22,7 +23,6 @@ if typing.TYPE_CHECKING:
22
23
  from tequila.objective import Objective, Variable
23
24
  from tequila.circuit.gates import QCircuit
24
25
  import numbers.Real as RealNumber
25
- from tequila.wavefunction.qubit_wavefunction import QubitWaveFunction
26
26
 
27
27
  """
28
28
  Check which simulators are installed
@@ -43,6 +43,19 @@ except ImportError:
43
43
  HAS_QISKIT = False
44
44
  HAS_QISKIT_NOISE = False
45
45
 
46
+ try:
47
+ pkg_resources.require("qiskit-aer-gpu")
48
+ from tequila.simulators.simulator_qiskit_gpu import BackendCircuitQiskitGpu, BackendExpectationValueQiskitGpu
49
+ HAS_QISKIT_GPU = True
50
+ INSTALLED_SIMULATORS["qiskit_gpu"] = BackendTypes(BackendCircuitQiskitGpu, BackendExpectationValueQiskitGpu)
51
+ INSTALLED_SAMPLERS["qiskit_gpu"] = BackendTypes(BackendCircuitQiskitGpu, BackendExpectationValueQiskitGpu)
52
+ from tequila.simulators.simulator_qiskit import HAS_NOISE as HAS_QISKIT_GPU_NOISE
53
+ if HAS_QISKIT_GPU_NOISE:
54
+ INSTALLED_NOISE_SAMPLERS["qiskit_gpu"] = BackendTypes(BackendCircuitQiskitGpu, BackendExpectationValueQiskitGpu)
55
+ except (ImportError, DistributionNotFound):
56
+ HAS_QISKIT_GPU = False
57
+ HAS_QISKIT_GPU_NOISE = False
58
+
46
59
  HAS_QIBO = True
47
60
  try:
48
61
  from tequila.simulators.simulator_qibo import BackendCircuitQibo, BackendExpectationValueQibo
@@ -82,8 +95,8 @@ except (ImportError, DistributionNotFound):
82
95
  HAS_QULACS = False
83
96
 
84
97
  try:
85
- pkg_resources.require("qulacs-gpu")
86
- import qulacs
98
+ # pkg_resources.require("qulacs-gpu")
99
+ from qulacs import QuantumStateGpu
87
100
  from tequila.simulators.simulator_qulacs_gpu import BackendCircuitQulacsGpu, BackendExpectationValueQulacsGpu
88
101
 
89
102
  HAS_QULACS_GPU = True
@@ -350,14 +363,15 @@ def compile_circuit(abstract_circuit: 'QCircuit',
350
363
  return CircType(abstract_circuit=abstract_circuit, variables=variables, noise=noise, device=device, *args, **kwargs)
351
364
 
352
365
 
353
- def simulate(objective: typing.Union['Objective', 'QCircuit','QTensor'],
366
+ def simulate(objective: typing.Union['Objective', 'QCircuit', 'QTensor'],
354
367
  variables: Dict[Union[Variable, Hashable], RealNumber] = None,
355
368
  samples: int = None,
356
369
  backend: str = None,
357
370
  noise: NoiseModel = None,
358
371
  device: str = None,
372
+ initial_state: Union[int, QubitWaveFunction] = 0,
359
373
  *args,
360
- **kwargs) -> Union[RealNumber, 'QubitWaveFunction']:
374
+ **kwargs) -> Union[RealNumber, QubitWaveFunction]:
361
375
  """Simulate a tequila objective or circuit
362
376
 
363
377
  Parameters
@@ -375,6 +389,8 @@ def simulate(objective: typing.Union['Objective', 'QCircuit','QTensor'],
375
389
  specify a noise model to apply to simulation/sampling
376
390
  device:
377
391
  a device upon which (or in emulation of which) to sample
392
+ initial_state: int or QubitWaveFunction:
393
+ the initial state of the circuit
378
394
  *args :
379
395
 
380
396
  **kwargs :
@@ -394,9 +410,9 @@ def simulate(objective: typing.Union['Objective', 'QCircuit','QTensor'],
394
410
  objective.extract_variables()))
395
411
 
396
412
  compiled_objective = compile(objective=objective, samples=samples, variables=variables, backend=backend,
397
- noise=noise,device=device, *args, **kwargs)
413
+ noise=noise, device=device, *args, **kwargs)
398
414
 
399
- return compiled_objective(variables=variables, samples=samples, *args, **kwargs)
415
+ return compiled_objective(variables=variables, samples=samples, initial_state=initial_state, *args, **kwargs)
400
416
 
401
417
 
402
418
  def draw(objective, variables=None, backend: str = None, name=None, *args, **kwargs):
@@ -7,6 +7,7 @@ from tequila.circuit.compiler import change_basis
7
7
  from tequila import BitString
8
8
  from tequila.objective.objective import Variable, format_variable_dictionary
9
9
  from tequila.circuit import compiler
10
+ from typing import Union
10
11
 
11
12
  import numbers, typing, numpy, copy, warnings
12
13
 
@@ -107,6 +108,11 @@ class BackendCircuit():
107
108
  "cc_max": True
108
109
  }
109
110
 
111
+ # Can be overwritten by backends that allow basis state initialization when sampling
112
+ supports_sampling_initialization: bool = False
113
+ # Can be overwritten by backends that allow initializing arbitrary states
114
+ supports_generic_initialization: bool = False
115
+
110
116
  @property
111
117
  def n_qubits(self) -> numbers.Integral:
112
118
  return len(self.qubit_map)
@@ -328,7 +334,7 @@ class BackendCircuit():
328
334
  """
329
335
  self.circuit = self.create_circuit(abstract_circuit=self.abstract_circuit, variables=variables)
330
336
 
331
- def simulate(self, variables, initial_state=0, *args, **kwargs) -> QubitWaveFunction:
337
+ def simulate(self, variables, initial_state: Union[int, QubitWaveFunction] = 0, *args, **kwargs) -> QubitWaveFunction:
332
338
  """
333
339
  simulate the circuit via the backend.
334
340
 
@@ -348,26 +354,43 @@ class BackendCircuit():
348
354
  the wavefunction of the system produced by the action of the circuit on the initial state.
349
355
 
350
356
  """
357
+ if isinstance(initial_state, QubitWaveFunction) and not self.supports_generic_initialization:
358
+ raise TequilaException("Backend does not support arbitrary initial states")
359
+
351
360
  self.update_variables(variables)
352
361
  if isinstance(initial_state, BitString):
353
362
  initial_state = initial_state.integer
354
- if isinstance(initial_state, QubitWaveFunction):
355
- if len(initial_state.keys()) != 1:
356
- raise TequilaException("only product states as initial states accepted")
357
- initial_state = list(initial_state.keys())[0].integer
358
363
 
359
- all_qubits = [i for i in range(self.abstract_circuit.n_qubits)]
364
+ all_qubits = list(range(self.abstract_circuit.n_qubits))
360
365
  active_qubits = self.qubit_map.keys()
361
366
 
362
- # maps from reduced register to full register
363
- keymap = KeyMapSubregisterToRegister(subregister=active_qubits, register=all_qubits)
367
+ # Keymap is only necessary if not all qubits are active
368
+ keymap_required = sorted(active_qubits) != all_qubits
369
+
370
+ # Combining keymap and general initial states is awkward, because it's not clear what should happen with
371
+ # different states on non-active qubits. For now, this is simply not allowed.
372
+ # A better solution might be to check if all components of the initial state differ only on the active qubits.
373
+ if keymap_required and isinstance(initial_state, QubitWaveFunction):
374
+ raise TequilaException("Can only set non-basis initial state if all qubits are used")
375
+
376
+ if keymap_required:
377
+ # maps from reduced register to full register
378
+ keymap = KeyMapSubregisterToRegister(subregister=active_qubits, register=all_qubits)
364
379
 
365
- result = self.do_simulate(variables=variables, initial_state=keymap.inverted(initial_state).integer, *args,
380
+ if not isinstance(initial_state, QubitWaveFunction):
381
+ mapped_initial_state = keymap.inverted(initial_state).integer if keymap_required else int(initial_state)
382
+ else:
383
+ mapped_initial_state = initial_state
384
+
385
+ result = self.do_simulate(variables=variables, initial_state=mapped_initial_state, *args,
366
386
  **kwargs)
367
- result.apply_keymap(keymap=keymap, initial_state=initial_state)
387
+
388
+ if keymap_required:
389
+ result = QubitWaveFunction.from_wavefunction(result, keymap, n_qubits=len(all_qubits), initial_state=initial_state)
390
+
368
391
  return result
369
392
 
370
- def sample(self, variables, samples, read_out_qubits=None, circuit=None, *args, **kwargs):
393
+ def sample(self, variables, samples, read_out_qubits=None, circuit=None, initial_state=0, *args, **kwargs):
371
394
  """
372
395
  Sample the circuit. If circuit natively equips paulistrings, sample therefrom.
373
396
  Parameters
@@ -387,6 +410,12 @@ class BackendCircuit():
387
410
  The result of sampling, a recreated QubitWaveFunction in the sampled basis.
388
411
 
389
412
  """
413
+ if initial_state != 0 and not self.supports_sampling_initialization:
414
+ raise TequilaException("Backend does not support initial states for sampling")
415
+
416
+ if isinstance(initial_state, QubitWaveFunction) and not self.supports_generic_initialization:
417
+ raise TequilaException("Backend does not support arbitrary initial states")
418
+
390
419
  self.update_variables(variables)
391
420
  if read_out_qubits is None:
392
421
  read_out_qubits = self.abstract_qubits
@@ -398,7 +427,9 @@ class BackendCircuit():
398
427
  circuit = self.add_measurement(circuit=self.circuit, target_qubits=read_out_qubits)
399
428
  else:
400
429
  circuit = self.add_measurement(circuit=circuit, target_qubits=read_out_qubits)
401
- return self.do_sample(samples=samples, circuit=circuit, read_out_qubits=read_out_qubits, *args, **kwargs)
430
+
431
+ return self.do_sample(samples=samples, circuit=circuit, read_out_qubits=read_out_qubits,
432
+ initial_state=initial_state, *args, **kwargs)
402
433
 
403
434
  def sample_all_z_hamiltonian(self, samples: int, hamiltonian, variables, *args, **kwargs):
404
435
  """
@@ -503,7 +534,7 @@ class BackendCircuit():
503
534
  E = E / samples * paulistring.coeff
504
535
  return E
505
536
 
506
- def do_sample(self, samples, circuit, noise, abstract_qubits=None, *args, **kwargs) -> QubitWaveFunction:
537
+ def do_sample(self, samples, circuit, noise, abstract_qubits=None, initial_state=0, *args, **kwargs) -> QubitWaveFunction:
507
538
  """
508
539
  helper function for sampling. MUST be overwritten by inheritors.
509
540
 
@@ -769,7 +800,7 @@ class BackendExpectationValue:
769
800
  raise TequilaException(
770
801
  "BackendExpectationValue received not all variables. Circuit depends on variables {}, you gave {}".format(
771
802
  self._variables, variables))
772
-
803
+
773
804
  if samples is None:
774
805
  data = self.simulate(variables=variables, *args, **kwargs)
775
806
  else:
@@ -848,7 +879,7 @@ class BackendExpectationValue:
848
879
  samples = max(1, int(self.abstract_expectationvalue.samples * total_samples))
849
880
  suggested = samples
850
881
  # samples are not necessarily set (either the user has to set it or some functions like optimize_measurements)
851
-
882
+
852
883
  if suggested is not None and suggested != samples:
853
884
  warnings.warn("simulating with samples={}, but expectationvalue carries suggested samples={}\nTry calling with samples='auto-total#ofsamples'".format(samples, suggested), TequilaWarning)
854
885
 
@@ -173,7 +173,7 @@ class BackendCircuitCirq(BackendCircuit):
173
173
  simulator = cirq.Simulator()
174
174
  backend_result = simulator.simulate(program=self.circuit, param_resolver=self.resolver,
175
175
  initial_state=initial_state)
176
- return QubitWaveFunction.from_array(arr=backend_result.final_state_vector, numbering=self.numbering)
176
+ return QubitWaveFunction.from_array(array=backend_result.final_state_vector, numbering=self.numbering)
177
177
 
178
178
  def convert_measurements(self, backend_result: cirq.Result) -> QubitWaveFunction:
179
179
  """
@@ -186,18 +186,18 @@ class BackendCircuitCirq(BackendCircuit):
186
186
  Returns
187
187
  -------
188
188
  QubitWaveFunction:
189
- the result of sampling, as a tequila QubitWavefunction.
189
+ the result of sampling, as a tequila QubitWaveFunction.
190
190
 
191
191
  """
192
192
  assert (len(backend_result.measurements) == 1)
193
193
  for key, value in backend_result.measurements.items():
194
- counter = QubitWaveFunction()
194
+ counter = QubitWaveFunction(self.n_qubits, self.numbering)
195
195
  for sample in value:
196
196
  binary = BitString.from_array(array=sample.astype(int))
197
- if binary in counter._state:
198
- counter._state[binary] += 1
197
+ if binary in counter.keys():
198
+ counter[binary] += 1
199
199
  else:
200
- counter._state[binary] = 1
200
+ counter[binary] = 1
201
201
  return counter
202
202
 
203
203
  def do_sample(self, samples, circuit, *args, **kwargs) -> QubitWaveFunction:
@@ -439,7 +439,7 @@ class BackendCircuitPyquil(BackendCircuit):
439
439
  if val > 0:
440
440
  iprep += pyquil.gates.X(i)
441
441
  backend_result = simulator.wavefunction(iprep + self.circuit, memory_map=self.resolver)
442
- return QubitWaveFunction.from_array(arr=backend_result.amplitudes, numbering=self.numbering)
442
+ return QubitWaveFunction.from_array(array=backend_result.amplitudes, numbering=self.numbering)
443
443
 
444
444
  def do_sample(self, samples, circuit, *args, **kwargs) -> QubitWaveFunction:
445
445
  """
@@ -495,7 +495,7 @@ class BackendCircuitPyquil(BackendCircuit):
495
495
  listing.append(int(letter))
496
496
  return listing
497
497
 
498
- result = QubitWaveFunction()
498
+ result = QubitWaveFunction(self.n_qubits, self.numbering)
499
499
  bit_dict = {}
500
500
  for b in backend_result:
501
501
  try:
@@ -505,7 +505,7 @@ class BackendCircuitPyquil(BackendCircuit):
505
505
 
506
506
  for k, v in bit_dict.items():
507
507
  arr = string_to_array(k)
508
- result._state[BitString.from_array(arr)] = v
508
+ result[BitString.from_array(arr)] = v
509
509
  return result
510
510
 
511
511
  def no_translation(self, abstract_circuit):
@@ -356,20 +356,20 @@ class BackendCircuitQibo(BackendCircuit):
356
356
  n_qubits = max(self.highest_qubit + 1, self.n_qubits, self.abstract_circuit.max_qubit() + 1)
357
357
  if initial_state is not None:
358
358
  if isinstance(initial_state, (int, np.int64)):
359
- wave = QubitWaveFunction.from_int(i=initial_state, n_qubits=n_qubits)
359
+ wave = QubitWaveFunction.from_basis_state(n_qubits, initial_state, self.numbering)
360
360
  elif isinstance(initial_state, str):
361
- wave = QubitWaveFunction.from_string(string=initial_state).to_array()
361
+ wave = QubitWaveFunction.from_string(initial_state, self.numbering).to_array()
362
362
  elif isinstance(initial_state, QubitWaveFunction):
363
363
  wave = initial_state
364
364
  elif isinstance(initial_state,np.ndarray):
365
- wave = QubitWaveFunction.from_array(initial_state)
365
+ wave = QubitWaveFunction.from_array(initial_state, self.numbering)
366
366
  else:
367
367
  raise TequilaQiboException('could not understand initial state of type {}'.format(type(initial_state)))
368
368
  state = wave.to_array()
369
369
  result = self.circuit(state)
370
370
  else:
371
371
  result = self.circuit()
372
- back= QubitWaveFunction.from_array(arr=result.numpy())
372
+ back= QubitWaveFunction.from_array(result.numpy(), self.numbering)
373
373
  return back
374
374
 
375
375
  def simulate(self, variables, initial_state=0, *args, **kwargs) -> QubitWaveFunction:
@@ -398,7 +398,7 @@ class BackendCircuitQibo(BackendCircuit):
398
398
  if isinstance(initial_state, BitString):
399
399
  initial_state = initial_state.integer
400
400
  if isinstance(initial_state, QubitWaveFunction):
401
- if len(initial_state.keys()) != 1:
401
+ if initial_state.length() != 1:
402
402
  return self.do_simulate(variables=variables,initial_state=initial_state, *args, **kwargs)
403
403
  initial_state = list(initial_state.keys())[0].integer
404
404
  if isinstance(initial_state,np.ndarray):
@@ -426,19 +426,18 @@ class BackendCircuitQibo(BackendCircuit):
426
426
  results transformed to tequila native QubitWaveFunction
427
427
  """
428
428
 
429
- result = QubitWaveFunction()
429
+ result = QubitWaveFunction(self.n_qubits, self.numbering)
430
430
  # todo there are faster ways
431
431
 
432
432
  for k, v in backend_result.frequencies(binary=True).items():
433
433
  converted_key = BitString.from_bitstring(other=BitString.from_binary(binary=k))
434
- result._state[converted_key] = v
435
-
434
+ result[converted_key] = v
436
435
 
437
436
  if target_qubits is not None:
438
437
  mapped_target = [self.qubit_map[q].number for q in target_qubits]
439
438
  mapped_full = [self.qubit_map[q].number for q in self.abstract_qubits]
440
439
  keymap = KeyMapRegisterToSubregister(subregister=mapped_target, register=mapped_full)
441
- result = result.apply_keymap(keymap=keymap)
440
+ result = QubitWaveFunction.from_wavefunction(result, keymap, len(mapped_target))
442
441
 
443
442
  return result
444
443
 
@@ -521,21 +520,20 @@ class BackendCircuitQibo(BackendCircuit):
521
520
  n_qubits = max(self.highest_qubit + 1, self.n_qubits, self.abstract_circuit.max_qubit() + 1)
522
521
  if initial_state is not None:
523
522
  if isinstance(initial_state, int):
524
- wave=QubitWaveFunction.from_int(i=initial_state, n_qubits=n_qubits)
523
+ wave = QubitWaveFunction.from_basis_state(n_qubits, initial_state, self.numbering)
525
524
  elif isinstance(initial_state, str):
526
- wave = QubitWaveFunction.from_string(string=initial_state).to_array()
525
+ wave = QubitWaveFunction.from_string(initial_state, self.numbering).to_array()
527
526
  elif isinstance(initial_state, QubitWaveFunction):
528
527
  wave = initial_state
529
- elif isinstance(initial_state,np.ndarray):
530
- wave = QubitWaveFunction.from_array(arr=initial_state, n_qubits=n_qubits) # silly but necessary
528
+ elif isinstance(initial_state, np.ndarray):
529
+ wave = QubitWaveFunction.from_array(initial_state, self.numbering) # silly but necessary
531
530
  else:
532
531
  raise TequilaQiboException('received an unusable initial state of type {}'.format(type(initial_state)))
533
- state=wave.to_array()
534
- result = circuit(state,nshots=samples)
532
+ state = wave.to_array()
533
+ result = circuit(state, nshots=samples)
535
534
  else:
536
535
  result = circuit(nshots=samples)
537
536
 
538
-
539
537
  back = self.convert_measurements(backend_result=result)
540
538
  return back
541
539