Skip to content

Commit cfda4b9

Browse files
committed
Moved ParameterMap to separate file.
1 parent ba95e72 commit cfda4b9

7 files changed

+300
-255
lines changed

c3/c3objs.py

-250
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Basic custom objects."""
22

3-
from typing import List, Dict, Tuple
43
import numpy as np
54
import tensorflow as tf
65
from c3.utils.utils import num3str
@@ -188,252 +187,3 @@ def set_opt_value(self, val: float) -> None:
188187
self.value = tf.acos(tf.cos(
189188
(tf.reshape(val, self.shape) + 1) * np.pi / 2
190189
)) / np.pi * 2 - 1
191-
192-
193-
class ParameterMap:
194-
"""
195-
Collects information about control and model parameters and provides different representations
196-
depending on use.
197-
"""
198-
199-
def __init__(
200-
self,
201-
instructions: list,
202-
generator=None,
203-
model=None
204-
):
205-
self.instructions = {}
206-
self.opt_map = []
207-
for instr in instructions:
208-
self.instructions[instr.name] = instr
209-
210-
# Collecting model components
211-
components = {}
212-
if model:
213-
components.update(model.couplings)
214-
components.update(model.subsystems)
215-
components.update(model.tasks)
216-
if generator:
217-
components.update(generator.devices)
218-
self.__components = components
219-
220-
par_lens = {}
221-
pars = {}
222-
# Initializing model parameters
223-
for comp in self.__components.values():
224-
for par_name, par_value in comp.params.items():
225-
par_id = (comp.name, par_name)
226-
par_lens[par_id] = par_value.length
227-
pars[par_id] = par_value
228-
229-
# Initializing control parameters
230-
for gate in self.instructions:
231-
instr = self.instructions[gate]
232-
for chan in instr.comps.keys():
233-
for comp in instr.comps[chan]:
234-
for par_name, par_value in instr.comps[chan][comp].params.items():
235-
par_id = (gate, chan, comp, par_name)
236-
par_lens[par_id] = par_value.length
237-
pars[par_id] = par_value
238-
239-
self.__par_lens = par_lens
240-
self.__pars = pars
241-
242-
self.model = model
243-
self.generator = generator
244-
245-
def get_full_params(self) -> Dict[str, Quantity]:
246-
"""
247-
Returns the full parameter vector, including model and control parameters.
248-
"""
249-
return self.__pars
250-
251-
def get_opt_units(self) -> List[str]:
252-
"""
253-
Returns a list of the units of the optimized quantities.
254-
"""
255-
units = []
256-
for equiv_ids in self.opt_map:
257-
units.append(self.__pars[equiv_ids[0]].unit)
258-
return units
259-
260-
def get_parameter(self, par_id: Tuple[str]) -> Quantity:
261-
"""
262-
Return one the current parameters.
263-
264-
Parameters
265-
----------
266-
par_id: tuple
267-
Hierarchical identifier for parameter.
268-
269-
Returns
270-
-------
271-
Quantity
272-
273-
"""
274-
try:
275-
value = self.__pars[par_id]
276-
except KeyError as ke:
277-
for id in self.__pars:
278-
if id[0] == par_id[0]:
279-
print(f"Found {id[0]}.")
280-
raise Exception(f"C3:ERROR:Parameter {par_id} not defined.") from ke
281-
return value
282-
283-
def get_parameters(self) -> List[Quantity]:
284-
"""
285-
Return the current parameters.
286-
287-
Parameters
288-
----------
289-
opt_map: list
290-
Hierarchical identifier for parameters.
291-
292-
Returns
293-
-------
294-
list of Quantity
295-
296-
"""
297-
values = []
298-
for equiv_ids in self.opt_map:
299-
try:
300-
values.append(self.__pars[equiv_ids[0]])
301-
except KeyError as ke:
302-
for par_id in self.__pars:
303-
if par_id[0] == equiv_ids[0][0]:
304-
print(f"Found {par_id[0]}.")
305-
raise Exception(f"C3:ERROR:Parameter {equiv_ids[0]} not defined.") from ke
306-
return values
307-
308-
def set_parameters(self, values: list, opt_map=None) -> None:
309-
"""Set the values in the original instruction class.
310-
311-
Parameters
312-
----------
313-
values: list
314-
List of parameter values. Can be nested, if a parameter is matrix valued.
315-
opt_map: list
316-
Corresponding identifiers for the parameter values.
317-
318-
"""
319-
val_indx = 0
320-
if opt_map is None:
321-
opt_map = self.opt_map
322-
for equiv_ids in opt_map:
323-
for id in equiv_ids:
324-
try:
325-
par = self.__pars[id]
326-
except ValueError as ve:
327-
raise Exception(f"C3:ERROR:{id} not defined.") from ve
328-
try:
329-
par.set_value(values[val_indx])
330-
except ValueError as ve:
331-
raise Exception(
332-
f"C3:ERROR:Trying to set {'-'.join(id)} to value {values[val_indx]} "
333-
f"but has to be within {par.offset:.3} .. {(par.offset + par.scale):.3}."
334-
) from ve
335-
val_indx += 1
336-
337-
def get_parameters_scaled(self) -> np.ndarray:
338-
"""
339-
Return the current parameters. This fuction should only be called by an optimizer. Are you
340-
an optimizer?
341-
342-
Parameters
343-
----------
344-
opt_map: tuple
345-
Hierarchical identifier for parameters.
346-
347-
Returns
348-
-------
349-
list of Quantity
350-
351-
"""
352-
values = []
353-
for equiv_ids in self.opt_map:
354-
par = self.__pars[equiv_ids[0]]
355-
values.append(par.get_opt_value())
356-
return np.array(values).flatten()
357-
358-
def set_parameters_scaled(self, values: list) -> None:
359-
"""
360-
Set the values in the original instruction class. This fuction should only be called by
361-
an optimizer. Are you an optimizer?
362-
363-
Parameters
364-
----------
365-
values: list
366-
List of parameter values. Matrix valued parameters need to be flattened.
367-
opt_map: list
368-
Corresponding identifiers for the parameter values.
369-
370-
"""
371-
val_indx = 0
372-
for equiv_ids in self.opt_map:
373-
par_len = self.__pars[equiv_ids[0]].length
374-
for id in equiv_ids:
375-
par = self.__pars[id]
376-
par.set_opt_value(values[val_indx:val_indx + par_len])
377-
val_indx += par_len
378-
379-
def set_opt_map(self, opt_map) -> None:
380-
"""
381-
Set the opt_map, i.e. which parameters will be optimized.
382-
"""
383-
for equiv_ids in opt_map:
384-
for pid in equiv_ids:
385-
if not pid in self.__pars:
386-
raise Exception(f"C3:ERROR:Parameter {pid} not defined.")
387-
self.opt_map = opt_map
388-
389-
def __str__(self) -> str:
390-
"""
391-
Return a multi-line human-readable string of all defined parameter names and
392-
current values.
393-
394-
Returns
395-
-------
396-
str
397-
Parameters and their values
398-
"""
399-
ret = []
400-
401-
for par_id, par in self.__pars.items():
402-
nice_id = "-".join(par_id)
403-
ret.append(f"{nice_id:38}: {par}\n")
404-
405-
return "".join(ret)
406-
407-
def str_parameters(self, opt_map) -> str:
408-
"""
409-
Return a multi-line human-readable string of the optmization parameter names and
410-
current values.
411-
412-
Parameters
413-
----------
414-
opt_map: list
415-
Optionally use only the specified parameters.
416-
417-
Returns
418-
-------
419-
str
420-
Parameters and their values
421-
"""
422-
ret = []
423-
for equiv_ids in opt_map:
424-
par_id = equiv_ids[0]
425-
par = self.__pars[equiv_ids[0]]
426-
nice_id = "-".join(par_id)
427-
ret.append(f"{nice_id:38}: {par}\n")
428-
if len(equiv_ids) > 1:
429-
for eid in equiv_ids[1:]:
430-
ret.append("-".join(eid))
431-
ret.append("\n")
432-
ret.append("\n")
433-
return "".join(ret)
434-
435-
def print_parameters(self):
436-
"""
437-
Print current parameters to stdout.
438-
"""
439-
print(self.str_parameters(self.opt_map))

0 commit comments

Comments
 (0)