2.1. Modelling a Simple TablePulseTemplate¶
This example demonstrates how to set up a simple TablePulseTemplate.
Assume we want to model a pulse as depicted by the figure above. Since
the structure is relatively simple and relies only on a few critical
points between which the values are interpolated (indicated by the
crosses in the figure), we will do so by using a TablePulseTemplate
and setting values at appropriate times. First, let us instantiate a
TablePulseTemplate
object:
In [1]:
from qctoolkit.pulses import TablePulseTemplate
template = TablePulseTemplate(identifier='foo')
For our first try, let’s just fix some values for the parameters. Let us
set \(t_a\) = 2, \(v_a\) = 2, \(t_b\) = 4, \(v_b\) = 3,
\(t_{end}\) = 6. Our pulse then holds a value of 0 for 2 units of
time, then jumps to 2 and subsequently ramps to 3 over the next 2 units
of time. Finally, it returns to holding 0 for another 2 units of time.
The supporting points for the table are thus (0,0), (2,2), (4,3), (6,0).
We add these to our TablePulseTemplate
object template
with the
correct interpolation strategies as follows:
In [2]:
template.add_entry(0, 0)
template.add_entry(2, 2, interpolation='hold')
template.add_entry(4, 3, interpolation='linear')
template.add_entry(6, 0, interpolation='jump')
Note that we could omit the first instruction: If the time value of the
first call to add_entry
is greater than zero, a starting entry (0,0)
is automatically set. Note further that the interpolation set for an
entry always applies to the range from the previous entry to the new
entry. Thus, the value for the first entry is always ignored. The
default value for interpolation is ‘hold’. ‘hold’ and ‘jump’ differ in
that ‘hold’ will hold the previous value until the new entry is reached
while ‘jump’ will immediately assume the value of the new entry.
We plot template
to see if everything is correct (ignore the
matplotlib warning here):
In [3]:
%matplotlib notebook
from qctoolkit.pulses import plot
try:
plot(template, sample_rate=100)
except:
pass
<IPython.core.display.Javascript object>
Alright, we got what we wanted.
Note that the time domain in pulse defintions does not correspond to any fixed real world time unit. The mapping from a single time unit in a pulse definition to real time in execution is made by setting a sample rate when converting the pulse templates to waveforms. For more on this, see The Sequencing Process: Obtaining Pulse Instances From Pulse Templates.
2.1.1. Introducing Parameters¶
Now we want to make the template parameterizable. This allows us to
reuse the template for pulses with similar structure. Say we would like
to have the same pulse, but the intermediate linear interpolation part
should last 4 units of time instead of only 2. Instead of creating
another template with hardcoded values, we instruct the
TablePulseTemplate
instance to rely on parameters.
In [4]:
param_template = TablePulseTemplate()
param_template.add_entry('ta', 'va', interpolation='hold')
param_template.add_entry('tb', 'vb', interpolation='linear')
param_template.add_entry('tend', 0, interpolation='jump')
Instead of using numerical values, we simply insert parameter names in
our calls to add_entry
. You can use any combination of numerical
values or parameters names here. Note that we also gave our object the
optional identifier ‘foo’. Our param_template
thus now defines a set
of parameters.
In [5]:
print(param_template.parameter_names)
{'va', 'ta', 'tb', 'tend', 'vb'}
We now have a pulse template that we can instantiate with different parameter values, which we simply provide as a dictionary. To achieve the same pulse as above:
In [6]:
%matplotlib notebook
parameters = {'ta': 2,
'va': 2,
'tb': 4,
'vb': 3,
'tend': 6}
plot(param_template, parameters, sample_rate=100)
<IPython.core.display.Javascript object>
To instantiate the pulse with longer intermediate linear interpolation
we now simply adjust the parameter values without touching the
param_template
itself:
In [7]:
%matplotlib notebook
parameters = {'ta': 2,
'va': 2,
'tb': 6,
'vb': 3,
'tend': 8}
plot(param_template, parameters, sample_rate=100)
<IPython.core.display.Javascript object>