plot_filter_functions

qctrlvisualizer.plot_filter_functions(filter_functions, show_legend=True, x_axis_log=True, y_axis_log=True, *, figure=None)

Create a plot of the specified filter functions.

Parameters:
  • filter_functions (dict) – The dictionary of filter functions to plot. The keys should be the names of the filter functions, and the values represent the filter functions by either a dictionary with the keys ‘frequencies’, ‘inverse_powers’, and optional ‘uncertainties’; or a list of samples as dictionaries with keys ‘frequency’, ‘inverse_power’, and optional ‘inverse_power_uncertainty’. The frequencies must be in Hertz an the inverse powers and their uncertainties in seconds. If the uncertainty of an inverse power is provided, it must be non-negative.

  • show_legend (bool, optional) – Whether to add a legend to the plot. Defaults to True.

  • x_axis_log (bool, optional) – Whether the x-axis is log-scale. Defaults to True.

  • y_axis_log (bool, optional) – Whether the y-axis is log-scale. Defaults to True.

  • figure (matplotlib.figure.Figure or None, optional) – A matplotlib Figure in which to place the plot. If passed, its dimensions and axes will be overridden.

Notes

For dictionary input, the key ‘inverse_power_uncertainties’ can be used instead of ‘uncertainties’. If both are provided then the value corresponding to ‘uncertainties’ is used. For list of samples input, the key ‘inverse_power_precision’ can be used instead of ‘inverse_power_uncertainty’. If both are provided then the value corresponding to ‘inverse_power_uncertainty’ is used.

As an example, the following is valid filter_functions input

filter_functions = {
    "Primitive": {
        "frequencies": [0.0, 1.0, 2.0],
        "inverse_powers": [15., 12., 3.],
        "uncertainties": [0., 0., 0.2],
    },
    "CORPSE": [
        {"frequency": 0.0, "inverse_power": 10.},
        {"frequency": 0.5, "inverse_power": 8.5},
        {"frequency": 1.0, "inverse_power": 5., "inverse_power_uncertainty": 0.1},
        {"frequency": 1.5, "inverse_power": 2.5},
    ],
}

Examples

Compare the filter functions of a primitive control scheme to BB1. The primitive scheme is sensitive to amplitude noise, whereas BB1 suppresses amplitude noise. The Hamiltonian of the system is

\[H(t) = \frac{1 + \beta(t)}{2} [\Omega(t) \sigma_- + \Omega^*(t) \sigma_+] ,\]

where \(\Omega(t)\) is the time-dependent Rabi rate implementing each control scheme and \(\beta(t)\) is a fractional time-dependent amplitude fluctuation process.

import numpy as np
import boulderopal as bo
from qctrlvisualizer import plot_filter_functions

graph = bo.Graph()

omega_max = 2 * np.pi * 1e6  # rad/s
frequencies = omega_max * np.logspace(-8, 0, 1000, base=10)
sample_count = 3000

primitive_duration = 5e-7  # s
primitive_hamiltonian = graph.hermitian_part(
    graph.constant_pwc(omega_max, primitive_duration) * graph.pauli_matrix("M")
)
graph.filter_function(
    control_hamiltonian=primitive_hamiltonian,
    noise_operator=primitive_hamiltonian,
    frequencies=frequencies,
    sample_count=sample_count,
    name="Primitive",
)

bb1_duration = 2.5e-6  # s
bb1_rates = omega_max * np.exp(1j * np.arccos(-1 / 4) * np.array([0, 1, 3, 3, 1]))
bb1_hamiltonian = graph.hermitian_part(
    graph.pwc_signal(bb1_rates, bb1_duration) * graph.pauli_matrix("M")
)
graph.filter_function(
    control_hamiltonian=bb1_hamiltonian,
    noise_operator=bb1_hamiltonian,
    frequencies=frequencies,
    sample_count=sample_count,
    name="BB1",
)

filter_function_result = bo.execute_graph(
    graph=graph, output_node_names=["Primitive", "BB1"], execution_mode="EAGER"
)["output"]

plot_filter_functions(filter_function_result)
../_images/plot_filter_functions-1.png