tequila-basic 1.9.3__py3-none-any.whl → 1.9.5__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/apps/adapt/adapt.py +1 -1
- tequila/circuit/qasm.py +25 -11
- tequila/optimizers/__init__.py +1 -14
- tequila/optimizers/optimizer_gpyopt.py +0 -2
- tequila/quantumchemistry/__init__.py +2 -0
- tequila/quantumchemistry/chemistry_tools.py +26 -15
- tequila/quantumchemistry/madness_interface.py +1 -1
- tequila/quantumchemistry/orbital_optimizer.py +16 -8
- tequila/quantumchemistry/pyscf_interface.py +1 -0
- tequila/quantumchemistry/qc_base.py +99 -16
- tequila/version.py +1 -1
- {tequila_basic-1.9.3.dist-info → tequila_basic-1.9.5.dist-info}/METADATA +11 -3
- {tequila_basic-1.9.3.dist-info → tequila_basic-1.9.5.dist-info}/RECORD +16 -17
- {tequila_basic-1.9.3.dist-info → tequila_basic-1.9.5.dist-info}/WHEEL +1 -1
- tequila/optimizers/optimizer_phoenics.py +0 -348
- {tequila_basic-1.9.3.dist-info → tequila_basic-1.9.5.dist-info}/LICENSE +0 -0
- {tequila_basic-1.9.3.dist-info → tequila_basic-1.9.5.dist-info}/top_level.txt +0 -0
tequila/apps/adapt/adapt.py
CHANGED
@@ -21,7 +21,7 @@ class AdaptParameters:
|
|
21
21
|
degeneracy_threshold: float = 5.e-4
|
22
22
|
silent: bool = False
|
23
23
|
|
24
|
-
def
|
24
|
+
def __post_init__(self):
|
25
25
|
# avoid stacking of same operator-types in a row
|
26
26
|
if "method_options" in self.optimizer_args:
|
27
27
|
if "gtol" in self.optimizer_args["method_options"]:
|
tequila/circuit/qasm.py
CHANGED
@@ -313,19 +313,33 @@ def parse_command(command: str, custom_gates_map: Dict[str, QCircuit], qregister
|
|
313
313
|
return apply_custom_gate(custom_circuit=custom_circuit, qregisters_values=qregisters_values)
|
314
314
|
|
315
315
|
if name in ("x", "y", "z", "h", "cx", "cy", "cz", "ch"):
|
316
|
-
|
317
|
-
|
318
|
-
|
316
|
+
target = get_qregister(args[0], qregisters)
|
317
|
+
control = None
|
318
|
+
if name[0].lower() == 'c':
|
319
|
+
control = get_qregister(args[0], qregisters)
|
320
|
+
target = get_qregister(args[1], qregisters)
|
321
|
+
name = name[1]
|
322
|
+
G = getattr(gates, name.upper())
|
323
|
+
return G(control=control, target=target)
|
324
|
+
|
319
325
|
if name in ("ccx", "ccy", "ccz"):
|
320
|
-
|
321
|
-
|
322
|
-
|
326
|
+
G = getattr(gates, name[2].upper())
|
327
|
+
control = [get_qregister(args[0], qregisters), get_qregister(args[1], qregisters)]
|
328
|
+
target = get_qregister(args[2], qregisters)
|
329
|
+
return G(control=control, target=target)
|
330
|
+
|
323
331
|
if name.startswith("rx(") or name.startswith("ry(") or name.startswith("rz(") or \
|
324
332
|
name.startswith("crx(") or name.startswith("cry(") or name.startswith("crz("):
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
333
|
+
angle = get_angle(name)[0]
|
334
|
+
i = name.find('(')
|
335
|
+
name = name[0:i]
|
336
|
+
name = name.upper()
|
337
|
+
name = [x for x in name]
|
338
|
+
name[-1] = name[-1].lower()
|
339
|
+
name = "".join(name)
|
340
|
+
G = getattr(gates, name)
|
341
|
+
return G(angle=angle,control=get_qregister(args[0], qregisters) if name[0] == 'C' else None,target=get_qregister(args[1 if name[0] == 'C' else 0], qregisters))
|
342
|
+
|
329
343
|
if name.startswith("U("):
|
330
344
|
angles = get_angle(name)
|
331
345
|
return gates.U(theta=angles[0], phi=angles[1], lambd=angles[2],
|
@@ -362,7 +376,7 @@ def parse_command(command: str, custom_gates_map: Dict[str, QCircuit], qregister
|
|
362
376
|
control=get_qregister(args[0], qregisters),
|
363
377
|
target=get_qregister(args[1], qregisters))
|
364
378
|
if name in ("s", "t", "sdg", "tdg"):
|
365
|
-
g = gates.Phase(pi / (2 if name.startswith("s") else 4),
|
379
|
+
g = gates.Phase(angle=pi / (2 if name.startswith("s") else 4),
|
366
380
|
control=None,
|
367
381
|
target=get_qregister(args[0], qregisters))
|
368
382
|
if name.find("dg") != -1:
|
tequila/optimizers/__init__.py
CHANGED
@@ -16,7 +16,7 @@ class _Optimizers:
|
|
16
16
|
methods: list = None
|
17
17
|
|
18
18
|
|
19
|
-
SUPPORTED_OPTIMIZERS = ['scipy', '
|
19
|
+
SUPPORTED_OPTIMIZERS = ['scipy', 'gpyopt', 'gd']
|
20
20
|
INSTALLED_OPTIMIZERS = {}
|
21
21
|
INSTALLED_OPTIMIZERS['scipy'] = _Optimizers(cls=OptimizerSciPy,
|
22
22
|
minimize=minimize_scipy,
|
@@ -37,19 +37,6 @@ try:
|
|
37
37
|
except ImportError:
|
38
38
|
has_gpyopt = False
|
39
39
|
|
40
|
-
has_phoenics = False
|
41
|
-
try:
|
42
|
-
from tequila.optimizers.optimizer_phoenics import OptimizerPhoenics
|
43
|
-
from tequila.optimizers.optimizer_phoenics import minimize as minimize_phoenics
|
44
|
-
|
45
|
-
INSTALLED_OPTIMIZERS['phoenics'] = _Optimizers(cls=OptimizerPhoenics,
|
46
|
-
minimize=minimize_phoenics,
|
47
|
-
methods=OptimizerPhoenics.available_methods())
|
48
|
-
has_phoenics = True
|
49
|
-
except ImportError:
|
50
|
-
has_phoenics = False
|
51
|
-
|
52
|
-
|
53
40
|
def show_available_optimizers(module=None):
|
54
41
|
"""
|
55
42
|
Returns
|
@@ -95,6 +95,8 @@ def Molecule(geometry: str = None,
|
|
95
95
|
if backend is None:
|
96
96
|
if basis_set is None or basis_set.lower() in ["madness", "mra", "pno"]:
|
97
97
|
backend = "madness"
|
98
|
+
basis_set = "mra"
|
99
|
+
parameters.basis_set = basis_set
|
98
100
|
if orbital_type is not None and orbital_type.lower() not in ["pno", "mra-pno"]:
|
99
101
|
warnings.warn("only PNOs supported as orbital_type without basis set. Setting to pno - You gave={}".format(orbital_type), TequilaWarning)
|
100
102
|
orbital_type = "pno"
|
@@ -569,7 +569,7 @@ class NBodyTensor:
|
|
569
569
|
return True
|
570
570
|
|
571
571
|
def __init__(self, elems: numpy.ndarray = None, active_indices: list = None, ordering: str = None,
|
572
|
-
size_full: int = None):
|
572
|
+
size_full: int = None, verify=False):
|
573
573
|
"""
|
574
574
|
Parameters
|
575
575
|
----------
|
@@ -611,7 +611,7 @@ class NBodyTensor:
|
|
611
611
|
if self.order == 4:
|
612
612
|
if ordering is None:
|
613
613
|
ordering = self.identify_ordering()
|
614
|
-
|
614
|
+
elif verify:
|
615
615
|
try: # some RDMs are really sloppy (depends on backend)
|
616
616
|
auto_ordering=self.identify_ordering()
|
617
617
|
if auto_ordering is not ordering:
|
@@ -804,20 +804,18 @@ class IntegralManager:
|
|
804
804
|
_one_body_integrals: numpy.ndarray = None
|
805
805
|
_two_body_integrals: NBodyTensor = None
|
806
806
|
_constant_term: float = None
|
807
|
-
_basis_type: str = "unknown"
|
808
807
|
_basis_name: str = "unknown"
|
809
808
|
_orbital_type: str = "unknown" # e.g. "HF", "PNO", "native"
|
810
809
|
_orbital_coefficients: numpy.ndarray = None
|
811
810
|
_active_space: ActiveSpaceData = None
|
812
811
|
_orbitals: typing.List[OrbitalData] = None
|
813
812
|
|
814
|
-
def __init__(self, one_body_integrals, two_body_integrals,
|
813
|
+
def __init__(self, one_body_integrals, two_body_integrals,
|
815
814
|
basis_name="unknown", orbital_type="unknown",
|
816
815
|
constant_term=0.0, orbital_coefficients=None, active_space=None, overlap_integrals=None, orbitals=None, *args, **kwargs):
|
817
816
|
self._one_body_integrals = one_body_integrals
|
818
817
|
self._two_body_integrals = two_body_integrals
|
819
818
|
self._constant_term = constant_term
|
820
|
-
self._basis_type = basis_type
|
821
819
|
self._basis_name = basis_name
|
822
820
|
self._orbital_type = orbital_type
|
823
821
|
|
@@ -956,9 +954,16 @@ class IntegralManager:
|
|
956
954
|
"""
|
957
955
|
c = self.get_orthonormalized_orbital_coefficients()
|
958
956
|
self.orbital_coefficients=c
|
959
|
-
self._orbital_type="orthonormalized-{}-basis".format(self.
|
957
|
+
self._orbital_type="orthonormalized-{}-basis".format(self._basis_name)
|
958
|
+
|
959
|
+
def is_unitary(self, U):
|
960
|
+
if len(U.shape) != 2: return False
|
961
|
+
if U.shape[0] != U.shape[1]: return False
|
962
|
+
test = (U.conj().T).dot(U) - numpy.eye(U.shape[0])
|
963
|
+
if not numpy.isclose(numpy.linalg.norm(test), 0.0): return False
|
964
|
+
return True
|
960
965
|
|
961
|
-
def transform_orbitals(self, U):
|
966
|
+
def transform_orbitals(self, U, name=None):
|
962
967
|
"""
|
963
968
|
Transform orbitals
|
964
969
|
Parameters
|
@@ -969,10 +974,12 @@ class IntegralManager:
|
|
969
974
|
-------
|
970
975
|
updates the structure with new orbitals: c = cU
|
971
976
|
"""
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
977
|
+
assert self.is_unitary(U)
|
978
|
+
self.orbital_coefficients = numpy.einsum("ix, xj -> ij", self.orbital_coefficients, U, optimize="greedy")
|
979
|
+
if name is None:
|
980
|
+
self._orbital_type += "-transformed"
|
981
|
+
else:
|
982
|
+
self._orbital_type = name
|
976
983
|
|
977
984
|
def get_integrals(self, orbital_coefficients=None, ordering="openfermion", ignore_active_space=False, *args, **kwargs):
|
978
985
|
"""
|
@@ -1001,7 +1008,9 @@ class IntegralManager:
|
|
1001
1008
|
active_integrals = get_active_space_integrals(one_body_integrals=h, two_body_integrals=g,
|
1002
1009
|
occupied_indices=self._active_space.frozen_reference_orbitals,
|
1003
1010
|
active_indices=self._active_space.active_orbitals)
|
1011
|
+
|
1004
1012
|
c = active_integrals[0] + c
|
1013
|
+
|
1005
1014
|
h = active_integrals[1]
|
1006
1015
|
g = NBodyTensor(elems=active_integrals[2], ordering="openfermion")
|
1007
1016
|
g.reorder(to=ordering)
|
@@ -1069,14 +1078,16 @@ class IntegralManager:
|
|
1069
1078
|
result += str(x) + "\n"
|
1070
1079
|
return result
|
1071
1080
|
|
1072
|
-
def print_basis_info(self, *args, **kwargs) -> None:
|
1073
|
-
print("{:15} : {}".format("basis_type", self._basis_type), *args, **kwargs)
|
1081
|
+
def print_basis_info(self, print_coefficients=True, *args, **kwargs) -> None:
|
1074
1082
|
print("{:15} : {}".format("basis_name", self._basis_name), *args, **kwargs)
|
1075
1083
|
print("{:15} : {}".format("orbital_type", self._orbital_type), *args, **kwargs)
|
1076
|
-
print("{:15} : {}".format("orthogonal", self.basis_is_orthogonal()), *args, **kwargs)
|
1077
|
-
print("{:15} : {}".format("functions", self.one_body_integrals.shape[0]), *args, **kwargs)
|
1084
|
+
print("{:15} : {}".format("orthogonal basis", self.basis_is_orthogonal()), *args, **kwargs)
|
1085
|
+
print("{:15} : {}".format("basis functions", self.one_body_integrals.shape[0]), *args, **kwargs)
|
1086
|
+
print("{:15} : {}".format("active orbitals", [o.idx_total for o in self.active_orbitals]), *args, **kwargs)
|
1078
1087
|
print("{:15} : {}".format("reference", [x.idx_total for x in self.reference_orbitals]), *args, **kwargs)
|
1079
1088
|
|
1089
|
+
if not print_coefficients: return
|
1090
|
+
|
1080
1091
|
print("Current Orbitals", *args, **kwargs)
|
1081
1092
|
for i,x in enumerate(self.orbitals):
|
1082
1093
|
print(x, *args, **kwargs)
|
@@ -122,7 +122,7 @@ class QuantumChemistryMadness(QuantumChemistryBase):
|
|
122
122
|
h = "failed"
|
123
123
|
g = "failed"
|
124
124
|
|
125
|
-
if "failed" in h or "failed" in g:
|
125
|
+
if (isinstance(h, str) and "failed" in h) or (isinstance(g, str) and "failed" in g):
|
126
126
|
status = "found {}_htensor.npy={}\n".format(name, "failed" not in h)
|
127
127
|
status += "found {}_gtensor.npy={}\n".format(name, "failed" not in g)
|
128
128
|
try:
|
@@ -37,7 +37,7 @@ class OptimizeOrbitalsResult:
|
|
37
37
|
self.iterations += 1
|
38
38
|
|
39
39
|
def optimize_orbitals(molecule, circuit=None, vqe_solver=None, pyscf_arguments=None, silent=False,
|
40
|
-
vqe_solver_arguments=None, initial_guess=None, return_mcscf=False, use_hcb=False, molecule_factory=None, molecule_arguments=None, *args, **kwargs):
|
40
|
+
vqe_solver_arguments=None, initial_guess=None, return_mcscf=False, use_hcb=False, molecule_factory=None, molecule_arguments=None, restrict_to_active_space=True, *args, **kwargs):
|
41
41
|
"""
|
42
42
|
|
43
43
|
Parameters
|
@@ -78,7 +78,12 @@ def optimize_orbitals(molecule, circuit=None, vqe_solver=None, pyscf_arguments=N
|
|
78
78
|
if pyscf_arguments is None:
|
79
79
|
pyscf_arguments = {"max_cycle_macro": 10, "max_cycle_micro": 3}
|
80
80
|
no = molecule.n_orbitals
|
81
|
-
|
81
|
+
|
82
|
+
if not isinstance(molecule, QuantumChemistryPySCF):
|
83
|
+
pyscf_molecule = QuantumChemistryPySCF.from_tequila(molecule=molecule, transformation=molecule.transformation)
|
84
|
+
else:
|
85
|
+
pyscf_molecule = molecule
|
86
|
+
|
82
87
|
mf = pyscf_molecule._get_hf()
|
83
88
|
result=OptimizeOrbitalsResult()
|
84
89
|
mc = mcscf.CASSCF(mf, pyscf_molecule.n_orbitals, pyscf_molecule.n_electrons)
|
@@ -118,13 +123,15 @@ def optimize_orbitals(molecule, circuit=None, vqe_solver=None, pyscf_arguments=N
|
|
118
123
|
print(wrapper)
|
119
124
|
if initial_guess is not None:
|
120
125
|
if hasattr(initial_guess, "lower"):
|
121
|
-
if "random" in initial_guess.lower():
|
122
|
-
scale =
|
126
|
+
if "random" or "near_zero" in initial_guess.lower():
|
127
|
+
scale = 1.e-3
|
128
|
+
if "random" in initial_guess.lower():
|
129
|
+
scale = 1.0
|
123
130
|
loc = 0.0
|
124
131
|
if "scale" in kwargs:
|
125
|
-
scale =
|
132
|
+
scale = float(initial_guess.split("scale")[1].split("_")[0].split("=")[1])
|
126
133
|
if "loc" in kwargs:
|
127
|
-
loc =
|
134
|
+
loc = float(initial_guess.split("loc")[1].split("_")[0].split("=")[1])
|
128
135
|
initial_guess = numpy.eye(no) + numpy.random.normal(scale=scale, loc=loc, size=no * no).reshape(no, no)
|
129
136
|
else:
|
130
137
|
raise Exception("Unknown initial_guess={}".format(initial_guess.lower()))
|
@@ -138,10 +145,11 @@ def optimize_orbitals(molecule, circuit=None, vqe_solver=None, pyscf_arguments=N
|
|
138
145
|
mc.kernel()
|
139
146
|
# make new molecule
|
140
147
|
|
141
|
-
|
148
|
+
mo_coeff = mc.mo_coeff
|
149
|
+
transformed_molecule = pyscf_molecule.transform_orbitals(orbital_coefficients=mo_coeff, name="optimized")
|
142
150
|
result.molecule=transformed_molecule
|
143
151
|
result.old_molecule=molecule
|
144
|
-
result.mo_coeff=
|
152
|
+
result.mo_coeff=mo_coeff
|
145
153
|
result.energy=mc.e_tot
|
146
154
|
|
147
155
|
if return_mcscf:
|
@@ -75,6 +75,7 @@ class QuantumChemistryPySCF(QuantumChemistryBase):
|
|
75
75
|
kwargs["two_body_integrals"] = g_ao
|
76
76
|
kwargs["one_body_integrals"] = h_ao
|
77
77
|
kwargs["orbital_coefficients"] = mo_coeff
|
78
|
+
kwargs["orbital_type"] = "hf"
|
78
79
|
|
79
80
|
if "nuclear_repulsion" not in kwargs:
|
80
81
|
kwargs["nuclear_repulsion"] = mol.energy_nuc()
|
@@ -94,7 +94,7 @@ class QuantumChemistryBase:
|
|
94
94
|
else:
|
95
95
|
self.integral_manager = self.initialize_integral_manager(active_orbitals=active_orbitals,
|
96
96
|
reference_orbitals=reference_orbitals,
|
97
|
-
orbitals=orbitals, frozen_orbitals=frozen_orbitals, orbital_type=orbital_type, *args,
|
97
|
+
orbitals=orbitals, frozen_orbitals=frozen_orbitals, orbital_type=orbital_type, basis_name=self.parameters.basis_set, *args,
|
98
98
|
**kwargs)
|
99
99
|
|
100
100
|
if orbital_type is not None and orbital_type.lower() == "native":
|
@@ -109,15 +109,23 @@ class QuantumChemistryBase:
|
|
109
109
|
|
110
110
|
@classmethod
|
111
111
|
def from_tequila(cls, molecule, transformation=None, *args, **kwargs):
|
112
|
-
c
|
112
|
+
c = molecule.integral_manager.constant_term
|
113
|
+
h1 = molecule.integral_manager.one_body_integrals
|
114
|
+
h2 = molecule.integral_manager.two_body_integrals
|
115
|
+
S = molecule.integral_manager.overlap_integrals
|
116
|
+
active_orbitals = [o.idx_total for o in molecule.integral_manager.active_orbitals]
|
113
117
|
if transformation is None:
|
114
118
|
transformation = molecule.transformation
|
119
|
+
parameters = molecule.parameters
|
115
120
|
return cls(nuclear_repulsion=c,
|
116
121
|
one_body_integrals=h1,
|
117
122
|
two_body_integrals=h2,
|
118
|
-
|
123
|
+
overlap_integrals = S,
|
124
|
+
orbital_coefficients = molecule.integral_manager.orbital_coefficients,
|
125
|
+
active_orbitals= active_orbitals,
|
119
126
|
transformation=transformation,
|
120
|
-
|
127
|
+
orbital_type=molecule.integral_manager._orbital_type,
|
128
|
+
parameters=parameters, *args, **kwargs)
|
121
129
|
|
122
130
|
def supports_ucc(self):
|
123
131
|
"""
|
@@ -543,11 +551,13 @@ class QuantumChemistryBase:
|
|
543
551
|
|
544
552
|
return manager
|
545
553
|
|
546
|
-
def transform_orbitals(self, orbital_coefficients, *args, **kwargs):
|
554
|
+
def transform_orbitals(self, orbital_coefficients, ignore_active_space=False, name=None, *args, **kwargs):
|
547
555
|
"""
|
548
556
|
Parameters
|
549
557
|
----------
|
550
|
-
orbital_coefficients: second index is new orbital indes, first is old orbital index (summed over)
|
558
|
+
orbital_coefficients: second index is new orbital indes, first is old orbital index (summed over), indices are assumed to be defined on the active space
|
559
|
+
ignore_active_space: if true orbital_coefficients are not assumed to be given in the active space
|
560
|
+
name: str, name the new orbitals
|
551
561
|
args
|
552
562
|
kwargs
|
553
563
|
|
@@ -556,9 +566,20 @@ class QuantumChemistryBase:
|
|
556
566
|
New molecule with transformed orbitals
|
557
567
|
"""
|
558
568
|
|
569
|
+
U = numpy.eye(self.integral_manager.orbital_coefficients.shape[0])
|
570
|
+
# mo_coeff by default only acts on the active space
|
571
|
+
active_indices = [o.idx_total for o in self.integral_manager.active_orbitals]
|
572
|
+
|
573
|
+
if ignore_active_space:
|
574
|
+
U = orbital_coefficients
|
575
|
+
else:
|
576
|
+
for kk,k in enumerate(active_indices):
|
577
|
+
for ll,l in enumerate(active_indices):
|
578
|
+
U[k][l] = orbital_coefficients[kk][ll]
|
579
|
+
|
559
580
|
# can not be an instance of a specific backend (otherwise we get inconsistencies with classical methods in the backend)
|
560
581
|
integral_manager = copy.deepcopy(self.integral_manager)
|
561
|
-
integral_manager.transform_orbitals(U=
|
582
|
+
integral_manager.transform_orbitals(U=U, name=name)
|
562
583
|
result = QuantumChemistryBase(parameters=self.parameters, integral_manager=integral_manager, transformation=self.transformation)
|
563
584
|
return result
|
564
585
|
|
@@ -583,7 +604,7 @@ class QuantumChemistryBase:
|
|
583
604
|
else:
|
584
605
|
integral_manager = copy.deepcopy(self.integral_manager)
|
585
606
|
integral_manager.transform_to_native_orbitals()
|
586
|
-
result = QuantumChemistryBase(parameters=self.parameters, integral_manager=integral_manager,
|
607
|
+
result = QuantumChemistryBase(parameters=self.parameters, integral_manager=integral_manager, transformation=self.transformation)
|
587
608
|
return result
|
588
609
|
|
589
610
|
|
@@ -645,6 +666,68 @@ class QuantumChemistryBase:
|
|
645
666
|
"""
|
646
667
|
return 2 * len(self.integral_manager.active_reference_orbitals)
|
647
668
|
|
669
|
+
def make_annihilation_op(self, orbital, coefficient=1.0):
|
670
|
+
"""
|
671
|
+
Compute annihilation operator on spin-orbital in qubit representation
|
672
|
+
Spin-orbital order is always (up,down,up,down,...)
|
673
|
+
"""
|
674
|
+
assert orbital<=self.n_orbitals*2
|
675
|
+
aop = openfermion.ops.FermionOperator(f'{orbital}', coefficient)
|
676
|
+
return self.transformation(aop)
|
677
|
+
|
678
|
+
def make_creation_op(self, orbital, coefficient=1.0):
|
679
|
+
"""
|
680
|
+
Compute creation operator on spin-orbital in qubit representation
|
681
|
+
Spin-orbital order is always (up,down,up,down,...)
|
682
|
+
"""
|
683
|
+
assert orbital<=self.n_orbitals*2
|
684
|
+
cop = openfermion.ops.FermionOperator(f'{orbital}^', coefficient)
|
685
|
+
return self.transformation(cop)
|
686
|
+
|
687
|
+
def make_number_op(self, orbital):
|
688
|
+
"""
|
689
|
+
Compute number operator on spin-orbital in qubit representation
|
690
|
+
Spin-orbital order is always (up,down,up,down,...)
|
691
|
+
"""
|
692
|
+
num_op = self.make_creation_op(orbital) * self.make_annihilation_op(orbital)
|
693
|
+
return num_op
|
694
|
+
|
695
|
+
def make_sz_op(self):
|
696
|
+
"""
|
697
|
+
Compute the spin_z operator of the molecule in qubit representation
|
698
|
+
"""
|
699
|
+
sz = QubitHamiltonian()
|
700
|
+
for i in range(0, self.n_orbitals * 2, 2):
|
701
|
+
one = 0.5 * self.make_creation_op(i) * self.make_annihilation_op(i)
|
702
|
+
two = 0.5 * self.make_creation_op(i+1) * self.make_annihilation_op(i+1)
|
703
|
+
sz += (one - two)
|
704
|
+
return sz
|
705
|
+
|
706
|
+
def make_sp_op(self):
|
707
|
+
"""
|
708
|
+
Compute the spin+ operator of the molecule in qubit representation
|
709
|
+
"""
|
710
|
+
sp = QubitHamiltonian()
|
711
|
+
for i in range(self.n_orbitals):
|
712
|
+
sp += self.make_creation_op(i*2) * self.make_annihilation_op(i*2 + 1)
|
713
|
+
return sp
|
714
|
+
|
715
|
+
def make_sm_op(self):
|
716
|
+
"""
|
717
|
+
Compute the spin- operator of the molecule in qubit representation
|
718
|
+
"""
|
719
|
+
sm = QubitHamiltonian()
|
720
|
+
for i in range(self.n_orbitals):
|
721
|
+
sm += self.make_creation_op(i*2 + 1) * self.make_annihilation_op(i*2)
|
722
|
+
return sm
|
723
|
+
|
724
|
+
def make_s2_op(self):
|
725
|
+
"""
|
726
|
+
Compute the spin^2 operator of the molecule in qubit representation
|
727
|
+
"""
|
728
|
+
s2_op = self.make_sm_op() * self.make_sp_op() + self.make_sz_op() * (self.make_sz_op() + 1)
|
729
|
+
return s2_op
|
730
|
+
|
648
731
|
def make_hamiltonian(self, *args, **kwargs) -> QubitHamiltonian:
|
649
732
|
"""
|
650
733
|
Parameters
|
@@ -805,13 +888,13 @@ class QuantumChemistryBase:
|
|
805
888
|
"""
|
806
889
|
if U is None:
|
807
890
|
U = QCircuit()
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
891
|
+
else:
|
892
|
+
ups = [self.transformation.up(i.idx) for i in self.orbitals]
|
893
|
+
consistency = [x in ups for x in U.qubits]
|
894
|
+
if not all(consistency):
|
895
|
+
warnings.warn(
|
896
|
+
"hcb_to_me: given circuit is not defined on all first {} qubits. Is this a HCB circuit?".format(
|
897
|
+
self.n_orbitals))
|
815
898
|
|
816
899
|
# map to alpha qubits
|
817
900
|
if condensed:
|
@@ -1939,7 +2022,7 @@ class QuantumChemistryBase:
|
|
1939
2022
|
self._rdm2 = _assemble_rdm2_spinful(evals_2) if get_rdm2 else self._rdm2
|
1940
2023
|
|
1941
2024
|
if get_rdm2:
|
1942
|
-
rdm2 = NBodyTensor(elems=self.rdm2, ordering="dirac")
|
2025
|
+
rdm2 = NBodyTensor(elems=self.rdm2, ordering="dirac", verify=False)
|
1943
2026
|
rdm2.reorder(to=ordering)
|
1944
2027
|
rdm2 = rdm2.elems
|
1945
2028
|
self._rdm2 = rdm2
|
tequila/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
__version__ = "1.9.
|
1
|
+
__version__ = "1.9.5"
|
2
2
|
__author__ = "Tequila Developers "
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: tequila-basic
|
3
|
-
Version: 1.9.
|
3
|
+
Version: 1.9.5
|
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
|
@@ -32,7 +32,7 @@ Tequila can execute the underlying quantum expectation values on state of the ar
|
|
32
32
|
- [talks and slides](https://kottmanj.github.io/talks_and_material/)
|
33
33
|
|
34
34
|
# Installation
|
35
|
-
Recommended Python version is 3.
|
35
|
+
Recommended Python version is 3.9 - 3.10.
|
36
36
|
Tequila supports linux, osx and windows. However, not all optional dependencies are supported on windows.
|
37
37
|
|
38
38
|
## Install from PyPi
|
@@ -258,6 +258,14 @@ A.G. Cadavid, I. Montalban, A. Dalal, E. Solano, N.N. Hegade
|
|
258
258
|
Efficient DCQO Algorithm within the Impulse Regime for Portfolio Optimization
|
259
259
|
[arxiv:2308.15475](https://arxiv.org/abs/2308.15475)
|
260
260
|
|
261
|
+
A. Anand, K. Brown
|
262
|
+
Hamiltonians, groups, graphs and ansätze
|
263
|
+
[arxiv:2312.17146](https://arxiv.org/abs/2312.17146)
|
264
|
+
|
265
|
+
P.W.K. Jensen, E.R. Kjellgren, P. Reinholdt, K.M. Ziems, S. Coriani, J. Kongsted, S. Sauer
|
266
|
+
Quantum Equation of Motion with Orbital Optimization for Computing Molecular Properties in Near-Term Quantum Computing
|
267
|
+
[arxiv:2312.12386](https://arxiv.org/abs/2312.12386)
|
268
|
+
|
261
269
|
Let us know, if you want your research project and/or tutorial to be included in this list!
|
262
270
|
|
263
271
|
# Dependencies
|
@@ -285,7 +293,7 @@ Currently supported
|
|
285
293
|
### [Psi4](https://github.com/psi4/psi4).
|
286
294
|
In a conda environment this can be installed with
|
287
295
|
```bash
|
288
|
-
conda install psi4 -c
|
296
|
+
conda install psi4 -c conda-forge
|
289
297
|
```
|
290
298
|
Here is a small [tutorial](https://nbviewer.org/github/tequilahub/tequila-tutorials/blob/main/chemistry/ChemistryModule.ipynb) that illustrates the usage.
|
291
299
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
tequila/__init__.py,sha256=FV8-j7GEw_VYadsZUp3M2mGRQxVUYYG3W1jiI6in3CY,1959
|
2
2
|
tequila/autograd_imports.py,sha256=t7V5uYaI0GzjD7pSjkYtiaj3BzSvkm_RL2KcYfNwNhM,1529
|
3
|
-
tequila/version.py,sha256=
|
3
|
+
tequila/version.py,sha256=TrfaFu9jLo_4f8zxqIwjs8NumC_hbB4Op1r-ZZIEnyY,57
|
4
4
|
tequila/apps/__init__.py,sha256=GJb04napv8AAx5EHxS5C1CMv9kxQeu7aA-ZMWk6X_eQ,1623
|
5
5
|
tequila/apps/_unary_state_prep_impl.py,sha256=SzRtI0Nx29ODygvYYdC1NnSTCL70wY7NTAvqhiwpMDs,21757
|
6
6
|
tequila/apps/unary_state_prep.py,sha256=QCrD9Ty2RkXc1Mh_MitFPIdaPs_fLxp_dtWVBZi0tSE,9403
|
7
7
|
tequila/apps/adapt/__init__.py,sha256=_XTo-36nJRXdM13rbPkWEowFXGdViFduINwzri5i1iM,166
|
8
|
-
tequila/apps/adapt/adapt.py,sha256=
|
8
|
+
tequila/apps/adapt/adapt.py,sha256=Wf2k7DWJaos_7se9YU6zw6ZZorcNvwCY3HQbo-ha884,19529
|
9
9
|
tequila/apps/krylov/__init__.py,sha256=Kp3WBq-_OaaxRr8G8I_DBjvjkMKNa9cDWJHLRHGNGsU,33
|
10
10
|
tequila/apps/krylov/krylov.py,sha256=z6Hpo5deawJNMW77KaOa8QIHQ8rXXCl341DVUf326_s,2274
|
11
11
|
tequila/apps/robustness/__init__.py,sha256=6BOjqcFWP3ymuit4JJ5cbzxS-G2AOCTdwcl87I-pNG8,62
|
@@ -19,7 +19,7 @@ tequila/circuit/gates.py,sha256=pOvX9_vACFyUAZRG4EGW3_aZGXysUJwUV8oFiKyLJ50,3590
|
|
19
19
|
tequila/circuit/gradient.py,sha256=Y4dNL6nkZUEkKJvaA3hxaSEa8_b_3XZwxy3j8tGsOmA,10465
|
20
20
|
tequila/circuit/noise.py,sha256=2LJ7Xq5f78x9p4imIz76l_lABQZwgNteNBFkWmUAQvo,8322
|
21
21
|
tequila/circuit/pyzx.py,sha256=XHhKoklhEcbpYkgkWHBLmKF-vyt_Oz-pX-Ctvd4nAOQ,1472
|
22
|
-
tequila/circuit/qasm.py,sha256=
|
22
|
+
tequila/circuit/qasm.py,sha256=iB5stV6Exo3bAn7ac1PgFKH53XD-57b9lpmzjavJK7k,15418
|
23
23
|
tequila/circuit/qpic.py,sha256=rjNAStvgNtqa89wJ3pmuzPoPWGZVI0gxARZuUnGtJa0,10789
|
24
24
|
tequila/grouping/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
25
25
|
tequila/grouping/binary_rep.py,sha256=VVM2o6B_RC0uH8kqE4yNxTzkGlgUm-CJTZ6z5J7R9I8,19406
|
@@ -41,21 +41,20 @@ tequila/objective/__init__.py,sha256=_BS3tVabs0zdon46nKpKmk3gI40z6KaWsjynIBMnPuc
|
|
41
41
|
tequila/objective/braket.py,sha256=10jEj7F3VWAj-fVrD4nhptrgRfrGvij84mVYcJWq4ZU,6019
|
42
42
|
tequila/objective/objective.py,sha256=8MzzTousgJf7w7rEdqGr8MU0PRF7S4kwh3BgsMMjnEg,31763
|
43
43
|
tequila/objective/qtensor.py,sha256=eSjFOEVW-kLoM8jn1RD2_E_kHVAm579Ji3_lMcJg7cE,7957
|
44
|
-
tequila/optimizers/__init__.py,sha256=
|
44
|
+
tequila/optimizers/__init__.py,sha256=1AhFyARYIfdyFGwnjOX0RDDa_kGrhiLJyjEbEm4NgZI,5086
|
45
45
|
tequila/optimizers/_containers.py,sha256=CXbWWQory_aADxlaMw4deIr03K_el-0E12GmpA0vX10,7161
|
46
46
|
tequila/optimizers/optimizer_base.py,sha256=Nc1HwlgfeB6XifoaWdFVLhdyHfeqQuhLvOtmtoFDMPY,32272
|
47
47
|
tequila/optimizers/optimizer_gd.py,sha256=QF84K2XDn_-0w9htDlEpIaaGGtfudNamIvVCgx1JkuE,39059
|
48
|
-
tequila/optimizers/optimizer_gpyopt.py,sha256
|
49
|
-
tequila/optimizers/optimizer_phoenics.py,sha256=31GBSC4P_-JqjYn3Bjmn3W7vDXW3Zn8aRxi8FWh2Uqc,13448
|
48
|
+
tequila/optimizers/optimizer_gpyopt.py,sha256=-aVuutZUScyo6_4q4PyvMMa_OVd3L8ev9Ge2fXyWGV8,11280
|
50
49
|
tequila/optimizers/optimizer_scipy.py,sha256=zqRVQ-Whr74KCGP7Zg1jQkl9S3j9s1kS4oCrCtX30gY,18949
|
51
|
-
tequila/quantumchemistry/__init__.py,sha256=
|
52
|
-
tequila/quantumchemistry/chemistry_tools.py,sha256=
|
50
|
+
tequila/quantumchemistry/__init__.py,sha256=KP99PNJYVwBcfQGwL-MB9IBLSBJNRPf-5WN9NLqT-Rg,7424
|
51
|
+
tequila/quantumchemistry/chemistry_tools.py,sha256=2zpQU8p_xV2mDQ6Q1tWqQPdAvt2OqjQV8PcGgiOo0UU,41353
|
53
52
|
tequila/quantumchemistry/encodings.py,sha256=y9h6rjq1K9IPVBMbRFQWXyBuAIZzgh2DVw2IUKtpuIM,8656
|
54
|
-
tequila/quantumchemistry/madness_interface.py,sha256=
|
55
|
-
tequila/quantumchemistry/orbital_optimizer.py,sha256=
|
53
|
+
tequila/quantumchemistry/madness_interface.py,sha256=f5c19Whb9Ene9UnkU1aKFqcGFkvN_TrR1o_G7xuC5dE,36304
|
54
|
+
tequila/quantumchemistry/orbital_optimizer.py,sha256=P_y4Q1qK-C46wgBjL4FBnSHeVSoKlzmkCG5eQWFU4_k,12376
|
56
55
|
tequila/quantumchemistry/psi4_interface.py,sha256=syNaDvlSmCsyB4f7idn3VGbMKyKo83vJHD5y5LpHwaM,29953
|
57
|
-
tequila/quantumchemistry/pyscf_interface.py,sha256=
|
58
|
-
tequila/quantumchemistry/qc_base.py,sha256=
|
56
|
+
tequila/quantumchemistry/pyscf_interface.py,sha256=XgecUnKKg2rGiKqsYCJnDQ89ekkDkKuwc3qHULLMYck,6152
|
57
|
+
tequila/quantumchemistry/qc_base.py,sha256=Bmz2lHsbtiJkb07ZZJ5EPAoW0TywQOxZgwagVHT3rEg,96531
|
59
58
|
tequila/simulators/__init__.py,sha256=VFw4sJIt4Zc0-__eYnksN8Ku9qMhbPpHJEkXMWUiD30,4
|
60
59
|
tequila/simulators/simulator_api.py,sha256=mLYA6GzujaNAGrDq1rtLQrW8tFZsCeyYnOnWRTlU6Eo,24172
|
61
60
|
tequila/simulators/simulator_base.py,sha256=93d-f4fNkJ2CtpL9OpgKcypmZH96Mdd9ESdZYn9jH48,33174
|
@@ -79,8 +78,8 @@ tequila/utils/keymap.py,sha256=RgQzeHEfRVee0-uoH-QsLYsGsXyMhEp3n33KCH-EV2k,3735
|
|
79
78
|
tequila/utils/misc.py,sha256=e62ASkFReaLJQXnBXzyYukzXZnXNoURsM1luoMeIXiE,919
|
80
79
|
tequila/wavefunction/__init__.py,sha256=q4DVL0lGFg03PogRMYA6S8MQqqmLYQiU9VNOF-YQxfQ,50
|
81
80
|
tequila/wavefunction/qubit_wavefunction.py,sha256=16Y9vRj6Yc6sBAKRUHVXJG4lJLDjWyN1b5fugf2LAmI,11881
|
82
|
-
tequila_basic-1.9.
|
83
|
-
tequila_basic-1.9.
|
84
|
-
tequila_basic-1.9.
|
85
|
-
tequila_basic-1.9.
|
86
|
-
tequila_basic-1.9.
|
81
|
+
tequila_basic-1.9.5.dist-info/LICENSE,sha256=oG1FtUav5_xrym9ByiG5emJDQRcbnAfTB08fRV9TCiE,1114
|
82
|
+
tequila_basic-1.9.5.dist-info/METADATA,sha256=dkAMyh6gVEZDDlmGeJ2NFZVvmXbjE3jpxYYrDY-7XbI,19694
|
83
|
+
tequila_basic-1.9.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
84
|
+
tequila_basic-1.9.5.dist-info/top_level.txt,sha256=VBH0gl6mDMbcLHKlO0yEAqtcq08DqBHz4gRJ9jafl5w,8
|
85
|
+
tequila_basic-1.9.5.dist-info/RECORD,,
|
@@ -1,348 +0,0 @@
|
|
1
|
-
from tequila.objective.objective import Objective
|
2
|
-
from tequila.optimizers.optimizer_base import Optimizer, OptimizerResults, dataclass
|
3
|
-
import typing
|
4
|
-
import numbers
|
5
|
-
from tequila.objective.objective import Variable
|
6
|
-
import copy
|
7
|
-
import warnings
|
8
|
-
import pickle
|
9
|
-
import time
|
10
|
-
from tequila import TequilaException
|
11
|
-
warnings.simplefilter("ignore")
|
12
|
-
with warnings.catch_warnings():
|
13
|
-
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
14
|
-
warnings.filterwarnings("ignore")
|
15
|
-
import phoenics
|
16
|
-
|
17
|
-
import numpy as np
|
18
|
-
from numpy import pi as pi
|
19
|
-
from tequila.simulators.simulator_api import compile_objective
|
20
|
-
import os
|
21
|
-
|
22
|
-
#numpy, tf, etc can get real, real, real, noisy here. We suppress it.
|
23
|
-
warnings.filterwarnings('ignore', category=DeprecationWarning)
|
24
|
-
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
|
25
|
-
warnings.filterwarnings('ignore', category=FutureWarning)
|
26
|
-
|
27
|
-
@dataclass
|
28
|
-
class PhoenicsResults(OptimizerResults):
|
29
|
-
|
30
|
-
observations: list = None
|
31
|
-
phoenics_instance: phoenics.Phoenics = None
|
32
|
-
|
33
|
-
class OptimizerPhoenics(Optimizer):
|
34
|
-
"""
|
35
|
-
wrapper to allow optimization of objectives with Phoenics, a bayesian optimizer.
|
36
|
-
See: https://github.com/aspuru-guzik-group/phoenics
|
37
|
-
"""
|
38
|
-
@classmethod
|
39
|
-
def available_methods(cls):
|
40
|
-
return ["phoenics"]
|
41
|
-
|
42
|
-
def __init__(self, maxiter, backend=None, save_history=True, minimize=True,
|
43
|
-
samples=None, silent=None, noise=None, device=None):
|
44
|
-
self._minimize = minimize
|
45
|
-
|
46
|
-
super().__init__(backend=backend, maxiter=maxiter, samples=samples,
|
47
|
-
noise=noise,device=device,
|
48
|
-
save_history=save_history, silent=silent)
|
49
|
-
|
50
|
-
def _process_for_sim(self, recommendation, passive_angles):
|
51
|
-
"""
|
52
|
-
convert from the phoenics suggestion format to a version recognizable by objectives.
|
53
|
-
Parameters
|
54
|
-
----------
|
55
|
-
recommendation: dict:
|
56
|
-
the a phoenics suggestion.
|
57
|
-
passive_angles: dict:
|
58
|
-
passive angles not optimized over.
|
59
|
-
|
60
|
-
Returns
|
61
|
-
-------
|
62
|
-
dict:
|
63
|
-
dict of Bariable, float pairs.
|
64
|
-
"""
|
65
|
-
rec = copy.deepcopy(recommendation)
|
66
|
-
for part in rec:
|
67
|
-
for k, v in part.items():
|
68
|
-
part[k] = v.item()
|
69
|
-
if passive_angles is not None:
|
70
|
-
for k, v in passive_angles.items():
|
71
|
-
part[k] = v
|
72
|
-
return rec
|
73
|
-
|
74
|
-
def _process_for_phoenics(self, pset, result, passive_angles=None):
|
75
|
-
"""
|
76
|
-
Convert results of a call to an objective into a form interpretable by phoenics.
|
77
|
-
Parameters
|
78
|
-
----------
|
79
|
-
pset: dict:
|
80
|
-
the parameters evaluated, as a dictionary
|
81
|
-
result:
|
82
|
-
the result of calling some objective, using pset as parameters.
|
83
|
-
passive_angles: dict, optional:
|
84
|
-
passive_angles, not optimized over.
|
85
|
-
|
86
|
-
Returns
|
87
|
-
-------
|
88
|
-
dict:
|
89
|
-
the a dictionary, formatted as phoenics prefers it, for use as an 'observation'.
|
90
|
-
"""
|
91
|
-
new = copy.deepcopy(pset)
|
92
|
-
for k, v in new.items():
|
93
|
-
new[k] = np.array([v], dtype=np.float32)
|
94
|
-
if passive_angles is not None:
|
95
|
-
for k in passive_angles.keys():
|
96
|
-
del new[k]
|
97
|
-
new['Energy'] = result
|
98
|
-
|
99
|
-
return new
|
100
|
-
|
101
|
-
def _make_phoenics_object(self, objective, passive_angles=None, conf=None, *args, **kwargs):
|
102
|
-
"""
|
103
|
-
instantiate phoenics, to perform optimization.
|
104
|
-
|
105
|
-
Parameters
|
106
|
-
----------
|
107
|
-
objective: Objective:
|
108
|
-
the objective to optimize over.
|
109
|
-
passive_angles: dict, optional:
|
110
|
-
a dictionary of angles not to optimize over.
|
111
|
-
conf: optional:
|
112
|
-
a user built configuration object or file, from which to initialize a phoenics object.
|
113
|
-
For advanced users only.
|
114
|
-
args
|
115
|
-
kwargs
|
116
|
-
|
117
|
-
Returns
|
118
|
-
-------
|
119
|
-
phoenics.Phoenics
|
120
|
-
a phoenics object configured to optimize an objective.
|
121
|
-
"""
|
122
|
-
if conf is not None:
|
123
|
-
if hasattr(conf, 'readlines'):
|
124
|
-
bird = phoenics.Phoenics(config_file=conf)
|
125
|
-
else:
|
126
|
-
bird = phoenics.Phoenics(config_dict=conf)
|
127
|
-
|
128
|
-
return bird
|
129
|
-
op = objective.extract_variables()
|
130
|
-
if passive_angles is not None:
|
131
|
-
for i, thing in enumerate(op):
|
132
|
-
if thing in passive_angles.keys():
|
133
|
-
op.remove(thing)
|
134
|
-
|
135
|
-
config = {"general": {"auto_desc_gen": "False", "batches": 5, "boosted": "False", "parallel": "False", "scratch_dir":os.getcwd()}}
|
136
|
-
config['parameters'] = [
|
137
|
-
{'name': k, 'periodic': 'True', 'type': 'continuous', 'size': 1, 'low': 0, 'high': 2 * pi} for k in op]
|
138
|
-
if self._minimize is True:
|
139
|
-
config['objectives'] = [{"name": "Energy", "goal": "minimize"}]
|
140
|
-
else:
|
141
|
-
config['objectives'] = [{"name": "Energy", "goal": "maximize"}]
|
142
|
-
|
143
|
-
for k,v in kwargs.items():
|
144
|
-
if hasattr(k, "lower") and k.lower() in config["general"]:
|
145
|
-
config["general"][k.lower()] = v
|
146
|
-
|
147
|
-
bird = phoenics.Phoenics(config_dict=config)
|
148
|
-
return bird
|
149
|
-
|
150
|
-
def __call__(self, objective: Objective,
|
151
|
-
maxiter=None,
|
152
|
-
variables: typing.List[Variable] = None,
|
153
|
-
initial_values: typing.Dict[Variable, numbers.Real] = None,
|
154
|
-
previous=None,
|
155
|
-
phoenics_config=None,
|
156
|
-
file_name=None,
|
157
|
-
*args,
|
158
|
-
**kwargs):
|
159
|
-
"""
|
160
|
-
Perform optimization with phoenics.
|
161
|
-
|
162
|
-
Parameters
|
163
|
-
----------
|
164
|
-
objective: Objective
|
165
|
-
the objective to optimize.
|
166
|
-
maxiter: int:
|
167
|
-
(Default value = None)
|
168
|
-
if not None, overwrite the init maxiter with new number.
|
169
|
-
variables: list:
|
170
|
-
(Default value = None)
|
171
|
-
which variables to optimize over. If None: all of the variables in objective are used.
|
172
|
-
initial_values: dict:
|
173
|
-
(Default value = None)
|
174
|
-
an initial point to begin optimization from. Random, if None.
|
175
|
-
previous:
|
176
|
-
previous observations, formatted for phoenics, to use in optimization. For use by advanced users.
|
177
|
-
phoenics_config:
|
178
|
-
a config for a phoenics object.
|
179
|
-
file_name:
|
180
|
-
a file
|
181
|
-
args
|
182
|
-
kwargs
|
183
|
-
|
184
|
-
Returns
|
185
|
-
-------
|
186
|
-
PhoenicsResults:
|
187
|
-
the results of optimization by phoenics.
|
188
|
-
|
189
|
-
"""
|
190
|
-
|
191
|
-
objective = objective.contract()
|
192
|
-
active_angles, passive_angles, variables = self.initialize_variables(objective,
|
193
|
-
initial_values=initial_values,
|
194
|
-
variables=variables)
|
195
|
-
|
196
|
-
if maxiter is None:
|
197
|
-
maxiter = 10
|
198
|
-
|
199
|
-
obs = []
|
200
|
-
bird = self._make_phoenics_object(objective, passive_angles, phoenics_config, *args, **kwargs)
|
201
|
-
if previous is not None:
|
202
|
-
if type(previous) is str:
|
203
|
-
try:
|
204
|
-
obs = pickle.load(open(previous, 'rb'))
|
205
|
-
except:
|
206
|
-
print(
|
207
|
-
'failed to load previous observations, which are meant to be a pickle file. Starting fresh.')
|
208
|
-
elif type(previous) is list:
|
209
|
-
if all([type(k) == dict for k in previous]):
|
210
|
-
obs = previous
|
211
|
-
else:
|
212
|
-
print('previous observations were not in the correct format (list of dicts). Starting fresh.')
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
if not (type(file_name) == str or file_name == None):
|
217
|
-
raise TequilaException('file_name must be a string, or None. Recieved {}'.format(type(file_name)))
|
218
|
-
|
219
|
-
best = None
|
220
|
-
best_angles = None
|
221
|
-
|
222
|
-
# avoid multiple compilations
|
223
|
-
compiled_objective = compile_objective(objective=objective, backend=self.backend,
|
224
|
-
device=self.device,
|
225
|
-
samples=self.samples, noise=self.noise)
|
226
|
-
|
227
|
-
if not self.silent:
|
228
|
-
print('phoenics has recieved')
|
229
|
-
print("objective: \n")
|
230
|
-
print(objective)
|
231
|
-
print("noise model : {}".format(self.noise))
|
232
|
-
print("samples : {}".format(self.samples))
|
233
|
-
print("maxiter : {}".format(maxiter))
|
234
|
-
print("variables : {}".format(objective.extract_variables()))
|
235
|
-
print("passive var : {}".format(passive_angles))
|
236
|
-
print('now lets begin')
|
237
|
-
for i in range(0, maxiter):
|
238
|
-
with warnings.catch_warnings():
|
239
|
-
np.testing.suppress_warnings()
|
240
|
-
warnings.simplefilter("ignore")
|
241
|
-
warnings.filterwarnings("ignore", category=FutureWarning)
|
242
|
-
|
243
|
-
precs = bird.recommend(observations=obs)
|
244
|
-
|
245
|
-
runs = []
|
246
|
-
recs = self._process_for_sim(precs, passive_angles=passive_angles)
|
247
|
-
|
248
|
-
start = time.time()
|
249
|
-
for j, rec in enumerate(recs):
|
250
|
-
En = compiled_objective(variables=rec, samples=self.samples, noise=self.noise)
|
251
|
-
runs.append((rec, En))
|
252
|
-
if not self.silent:
|
253
|
-
if self.print_level > 2:
|
254
|
-
print("energy = {:+2.8f} , angles=".format(En), rec)
|
255
|
-
else:
|
256
|
-
print("energy = {:+2.8f}".format(En))
|
257
|
-
stop = time.time()
|
258
|
-
if not self.silent:
|
259
|
-
print("Quantum Objective evaluations: {}s Wall-Time".format(stop-start))
|
260
|
-
|
261
|
-
for run in runs:
|
262
|
-
angles = run[0]
|
263
|
-
E = run[1]
|
264
|
-
if best is None:
|
265
|
-
best = E
|
266
|
-
best_angles = angles
|
267
|
-
else:
|
268
|
-
if self._minimize:
|
269
|
-
if E < best:
|
270
|
-
best = E
|
271
|
-
best_angles = angles
|
272
|
-
else:
|
273
|
-
if E > best:
|
274
|
-
best = E
|
275
|
-
best_angles = angles
|
276
|
-
|
277
|
-
if self.save_history:
|
278
|
-
self.history.energies.append(E)
|
279
|
-
self.history.angles.append(angles)
|
280
|
-
obs.append(self._process_for_phoenics(angles, E, passive_angles=passive_angles))
|
281
|
-
|
282
|
-
if file_name is not None:
|
283
|
-
with open(file_name, 'wb') as file:
|
284
|
-
pickle.dump(obs, file)
|
285
|
-
|
286
|
-
if not self.silent:
|
287
|
-
print("best energy after {} iterations : {:+2.8f}".format(self.maxiter, best))
|
288
|
-
return PhoenicsResults(energy=best, variables=best_angles, history=self.history, observations=obs,phoenics_instance=bird)
|
289
|
-
|
290
|
-
|
291
|
-
def minimize(objective: Objective,
|
292
|
-
maxiter: int = None,
|
293
|
-
samples: int = None,
|
294
|
-
variables: typing.List = None,
|
295
|
-
initial_values: typing.Dict = None,
|
296
|
-
backend: str = None,
|
297
|
-
noise=None,
|
298
|
-
device: str = None,
|
299
|
-
previous: typing.Union[str, list] = None,
|
300
|
-
phoenics_config: typing.Union[str, typing.Dict] = None,
|
301
|
-
file_name: str = None,
|
302
|
-
silent: bool = False,
|
303
|
-
*args,
|
304
|
-
**kwargs) -> PhoenicsResults:
|
305
|
-
"""
|
306
|
-
|
307
|
-
Parameters
|
308
|
-
----------
|
309
|
-
objective: Objective:
|
310
|
-
The tequila objective to optimize
|
311
|
-
initial_values: typing.Dict[typing.Hashable, numbers.Real], optional:
|
312
|
-
Initial values as dictionary of Hashable types (variable keys) and floating point numbers.
|
313
|
-
If given None they will be randomized.
|
314
|
-
variables: typing.List[typing.Hashable], optional:
|
315
|
-
List of Variables to optimize
|
316
|
-
samples: int, optional:
|
317
|
-
samples/shots to take in every run of the quantum circuits (None activates full wavefunction simulation)
|
318
|
-
maxiter: int:
|
319
|
-
how many iterations of phoenics to run.
|
320
|
-
Note that this is NOT identical to the number of times the circuit will run.
|
321
|
-
backend: str, optional:
|
322
|
-
Simulator backend, will be automatically chosen if set to None
|
323
|
-
noise: NoiseModel, optional:
|
324
|
-
a noise model to apply to the circuits of Objective.
|
325
|
-
device: optional:
|
326
|
-
the device from which to (potentially, simulatedly) sample all quantum circuits employed in optimization.
|
327
|
-
previous: optional:
|
328
|
-
Previous phoenics observations. If string, the name of a file from which to load them. Else, a list.
|
329
|
-
phoenics_config: optional:
|
330
|
-
a pre-made phoenics configuration. if str, the name of a file from which to load it; Else, a dictionary.
|
331
|
-
Individual keywords of the 'general' sections can also be passed down as kwargs
|
332
|
-
file_name: str, optional:
|
333
|
-
where to save output to, if save_to_file is True.
|
334
|
-
kwargs: dict:
|
335
|
-
Send down more keywords for single replacements in the phoenics config 'general' section, like e.g. batches=5,
|
336
|
-
boosted=True etc
|
337
|
-
Returns
|
338
|
-
-------
|
339
|
-
PhoenicsResults:
|
340
|
-
the result of an optimization by phoenics.
|
341
|
-
"""
|
342
|
-
|
343
|
-
optimizer = OptimizerPhoenics(samples=samples, backend=backend,
|
344
|
-
noise=noise,device=device,
|
345
|
-
maxiter=maxiter, silent=silent)
|
346
|
-
return optimizer(objective=objective, initial_values=initial_values, variables=variables, previous=previous,
|
347
|
-
maxiter=maxiter,
|
348
|
-
phoenics_config=phoenics_config, file_name=file_name, *args, **kwargs)
|
File without changes
|
File without changes
|