static FunctionNamespace.calculate_filter_function(*, duration, frequencies, sample_count=None, projection_operator=None, drives=None, shifts=None, drifts=None, result_scope='ALL', **kwargs)

Calculate a heuristic for robustness of the controls against noise.

Use this function to calculate a filter function, a heuristic that quantifies robustness of controls as a function of the noise frequency. You must express the control Hamiltonian in terms of piecewise-constant complex controls (drives), piecewise-constant real controls (shifts), and static terms (drifts); and you must select one of those terms to represent the noise that this function uses to calculate the robustness.

  • duration (float) – The total duration of the controls, \(\tau\). Must be positive and match the duration of each one of the drives and shifts.

  • frequencies (List[float]) – The list of frequencies \(\{f_j\}\) where you want to sample the filter function.

  • sample_count (int, optional) – The number of points in time, \(M\), where the function samples the toggling-frame noise operator. The function uses these samples to calculate the integral that represents the Fourier transform of the noise operator. You can increase this number to improve the precision of the filter function. Defaults to None, which means that the Fourier transformation of the noise operator is calculated exactly.

  • projection_operator (ndarray, optional) – The orthogonal projection matrix, \(P\), defining the subspace of interest. Must be Hermitian and idempotent if provided. You don’t need to provide this parameter if the Hilbert space of your interest is the full Hilbert space of your controls. Defaults to an identity matrix with same dimension as the noise operator.

  • drives (List[qctrl.dynamic.types.filter_function.Drive], optional) – The list of complex control terms in the system’s Hamiltonian. Each term has the form \(\gamma_{j}(t) C_{j} + \mathrm{H.c.}\), where \(C_{j}\) is a non-Hermitian operator and \(\gamma_{j}(t)\) is a complex piecewise-constant function between 0 and \(\tau\). Defaults to an empty list.

  • shifts (List[qctrl.dynamic.types.filter_function.Shift], optional) – The list of real control terms in the system’s Hamiltonian. Each term has the form \(\alpha_{k}(t) A_{k}\), where \(A_{k}\) is a Hermitian operator and \(\alpha_{k}(t)\) is a real piecewise- constant function between 0 and \(\tau\). Defaults to an empty list.

  • drifts (List[qctrl.dynamic.types.filter_function.Drift], optional) – The list of static terms in the system’s Hamiltonian. Each term has the form of a constant Hermitian operator \(D_l\). Defaults to an empty list.

  • result_scope (qctrl.dynamic.types.filter_function.ResultScope, optional) – Configuration for the scope of the returned data. Use this to select which data you want returned and which you want to omit. Defaults to returning all results.


The filter function \(F(f)\) sampled at the frequencies \(\{f_j\}\) that you requested, its precision, and the Fourier transformed noise operator \(\mathcal{F} \left\{ \tilde N^\prime(t) \right\}(f)\). By default, this function returns all these values for each sample. You can change this behavior using the result_scope parameter.

Return type:



This is a legacy function that will be removed in the future. The recommended way of calculating filter functions is through the calculate_graph function and the filter_function node. You can learn more about it in the How to calculate and use filter functionsfor arbitrary controls user guide.

You must provide at least one control (drives or shifts).

Exactly one of the drives, shifts, or drifts must represent the noise. If you select a drive or a shift as the noise, the function includes it in the control Hamiltonian and also in the noise Hamiltonian. However, if you select a drift as the noise, the function doesn’t include it in the control Hamiltonian (unless you add an identical noiseless drift).


The filter function provides a measure of noise robustness: the lower the value of the filter function, the less susceptible the controls are to noise of that frequency. To calculate the filter function, consider a system whose total Hamiltonian \(H(t)\) contains a control term \(H_c(t)\) and a noise term \(H_n(t)\):

\[H(t) = H_c(t) + H_n(t).\]

The control Hamiltonian defines the intended unitary operation \(U_c(t)\) as the solution of the Schrödinger equation. The noise Hamiltonian describes the noise against which you want to measure robustness.

To define the control Hamiltonian \(H(t)\), and thus the intended unitary operation \(U_c(t)\), provide a control Hamiltonian in the following form:

\[H_c(t) = \sum_j^{N_\textrm{drives}} \left( \gamma_j (t) C_{j} + \text{H.c.} \right) + \sum_k^{N_\textrm{shifts}} \alpha_k (t) A_{k} + \sum_l^{N_\textrm{drifts}} D_l.\]

To define the noise Hamiltonian \(H_n(t)\), select one of the drives, shifts, or drifts as the noise operator \(N(t)\). The noise operator is identical to the term of the control Hamiltonian that you selected, and it contributes to a noise Hamiltonian of the form:

\[H_n (t) = \beta(t) N(t),\]

where \(\beta(t)\) is a stochastic variable that represents the amplitude of the noise. The filter function measures the robustness of the controls as a function of the oscillation frequency of this stochastic variable. You can express the information about the frequency distribution of the stochastic variable in the form of its noise power spectrum \(S(f)\):

\[C(t_1, t_2) \equiv \langle \beta(t_1) \beta(t_2) \rangle_\mathrm{t} = \int_{-\infty}^\infty S(f)e^{i 2\pi f(t_2-t_1)} \mathrm{d}f.\]

Here, \(\langle\bullet\rangle_\mathrm{t}\) denotes a time average and \(C(t_1, t_2)\) is the autocorrelation function.

Add noise to one of the drives or shifts to create a multiplicative noise, which multiplies the controls. Selecting one of the drives or shifts as a noise doesn’t affect its presence in the control Hamiltonian, it only means it is also present in the noise Hamiltonian. On the other hand, you can add noise to one of the drifts to generate additive noise. Selecting one of the drifts as a noise means it is not present in the control Hamiltonian, unless you add an identical noiseless drift.

Given the intended operation \(U_c(t)\) and the noise operator \(N(t)\), this algorithm broadly follows the procedure from Reference [1], where you can find a full derivation of the formula for a filter function. First, the algorithm calculates the toggling-frame noise operator with:

\[\tilde N(t) = U_c^\dagger(t) N(t) U_c(t).\]

The algorithm removes the trace of the noise operator in the subspace of interest by applying the transformation:

\[\tilde N^\prime(t) = \tilde N(t) - \frac{\mathrm{Tr}\left( P \tilde N(t) P \right)}{\mathrm{Tr}(P)} \mathbb{I},\]

where \({P}\) is the orthogonal projector into the subspace and \(\mathbb{I}\) is the identity in the Hilbert space of the noise operator. It then goes to the frequency domain through a Fourier transform:

\[\mathcal{F} \left\{ \tilde N^\prime(t) \right\}(f) = \int_0^\tau e^{-i 2\pi f t} \tilde N^\prime(t) \mathrm{d}t.\]

The algorithm can calculate this integral exactly, or efficiently approximate it as the sum of \(M\) terms:

\[\mathcal{F} \left\{ \tilde N^\prime(t) \right\}(f) \approx \sum_{n=0}^{M-1} \frac{\tau}{M} e^{-i 2\pi f n \tau/M} \langle \tilde N^\prime (n\tau/M) \rangle,\]

where \(\langle \tilde N^\prime (t) \rangle\) represents an estimate of the noise operator at \(t\). Finally, the algorithm calculates the filter function \(F(f)\) using the following formula:

\[F(f) = \frac{1}{\mathrm{Tr}(P)} \mathrm{Tr} \left( P \mathcal{F} \left\{ \tilde N^\prime (t) \right\} \left[ \mathcal{F} \left\{ \tilde N^\prime (t) \right\} \right]^\dagger P \right).\]

This formula for the filter function comes from the first-order term of a Magnus expansion [1] of the infidelity. It allows you to estimate the average infidelity \(\mathcal{I}\) of the effective operation when both control and noise Hamiltonians are present (\(U_\mathrm{tot}(t)\)) in comparison to the intended operation (\(U_c(t)\)), where only the control Hamiltonian is present:

\[\mathcal{I} = 1 - \left\langle \left| \frac{\mathrm{Tr}\left( P U_c^\dagger (\tau) U_\mathrm{tot} (\tau) P \right)}{\mathrm{Tr}(P)} \right|^2 \right\rangle.\]

In the weak noise regime, you can estimate the infidelity \(\mathcal{I}\) as the overlap integral of the filter function \(F(f)\) and the noise power spectrum \(S(f)\) [1]:

\[\mathcal{I} \approx \int_{-\infty}^\infty S(f) F(f) \mathrm{d}f.\]



See the How to calculate and use filter functions for arbitrary controls user guide.