-
Notifications
You must be signed in to change notification settings - Fork 36
/
c2.py
executable file
·175 lines (155 loc) · 5.37 KB
/
c2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
"""Object that deals with the closed loop optimal control."""
import os
import time
import hjson
import pickle
import inspect
from c3.optimizers.optimizer import Optimizer
from c3.utils.utils import log_setup
class C2(Optimizer):
"""
Object that deals with the closed loop optimal control.
Parameters
----------
dir_path : str
Filepath to save results
eval_func : callable
infidelity function to be minimized
pmap : ParameterMap
Identifiers for the parameter vector
algorithm : callable
From the algorithm library
options : dict
Options to be passed to the algorithm
run_name : str
User specified name for the run, will be used as root folder
"""
def __init__(
self,
dir_path,
eval_func,
pmap,
algorithm,
exp_right=None,
options={},
run_name=None,
):
super().__init__(pmap=pmap, algorithm=algorithm)
self.eval_func = eval_func
self.options = options
self.exp_right = exp_right
self.__dir_path = dir_path
self.__run_name = run_name
def set_eval_func(self, eval_func):
"""
Setter for the eval function.
Parameters
----------
eval_func : callable
Function to be evaluated
"""
self.eval_func = eval_func
def log_setup(self) -> None:
"""
Create the folders to store data.
Parameters
----------
dir_path : str
Filepath
run_name : str
User specified name for the run
"""
dir_path = os.path.abspath(self.__dir_path)
run_name = self.__run_name
if run_name is None:
run_name = self.eval_func.__name__ + self.algorithm.__name__
self.logdir = log_setup(dir_path, run_name)
self.logname = "calibration.log"
# We create a copy of the source code of the evaluation function in the log
with open(os.path.join(self.logdir, "eval_func.py"), "w") as eval_source:
eval_source.write(inspect.getsource(self.eval_func))
def optimize_controls(self) -> None:
"""
Apply a search algorithm to your gateset given a fidelity function.
"""
self.log_setup()
self.start_log()
self.picklefilename = self.logdir + "dataset.pickle"
print(f"C3:STATUS:Saving as: {os.path.abspath(self.logdir + self.logname)}")
x_init = self.pmap.get_parameters_scaled()
try:
self.algorithm(
x_init,
fun=self.fct_to_min,
fun_grad=self.fct_to_min_autograd,
grad_lookup=self.lookup_gradient,
options=self.options,
)
except KeyboardInterrupt:
pass
with open(os.path.join(self.logdir, "best_point_" + self.logname), "r") as file:
best_params = hjson.load(file)["optim_status"]["params"]
self.pmap.set_parameters(best_params)
self.end_log()
measurements = []
with open(self.picklefilename, "rb") as pickle_file:
while True:
try:
measurements.append(pickle.load(pickle_file))
except EOFError:
break
learn_from = {}
learn_from["seqs_grouped_by_param_set"] = measurements
learn_from["opt_map"] = self.pmap.opt_map
with open(self.picklefilename, "wb+") as pickle_file:
pickle.dump(learn_from, pickle_file)
def goal_run(self, current_params):
"""
Evaluate the goal function for current parameters.
Parameters
----------
current_params : tf.Tensor
Vector representing the current parameter values.
Returns
-------
tf.float64
Value of the goal function
"""
self.pmap.set_parameters_scaled(current_params)
# There could be more processing happening here, i.e. an exp could
# generate signals for an experiment and send those to eval_func.
params = self.pmap.get_parameters()
goal, results, results_std, seqs, shots = self.eval_func(params)
self.optim_status["params"] = [
par.numpy().tolist() for par in self.pmap.get_parameters()
]
self.optim_status["goal"] = float(goal)
self.optim_status["time"] = time.asctime()
self.evaluation += 1
self.log_pickle(params, seqs, results, results_std, shots)
return goal
def log_pickle(self, params, seqs, results, results_std, shots):
"""
Save a pickled version of the performed experiment, suitable for model learning.
Parameters
----------
params : tf.Tensor
Vector of parameter values
seqs : list
Strings identifying the performed instructions
results : list
Values of the goal function
results_std : list
Standard deviation of the results, in the case of noisy data
shots : list
Number of repetitions used in averaging noisy data
"""
data_entry = {
"params": params,
"seqs": seqs,
"results": results,
"results_std": results_std,
"shots": shots,
}
with open(self.picklefilename, "ab") as file:
pickle.dump(data_entry, file)