krotov.functionals module¶
Functionals and chi_constructor routines
Summary¶
Data:
F_avg |
Average gate fidelity |
F_re |
Real-part fidelity |
F_sm |
Square-modulus fidelity |
F_ss |
State-to-state phase-insensitive fidelity |
J_T_hs |
Hilbert-Schmidt distance measure functional \(J_{T,\text{hs}}\) |
J_T_re |
Real-part functional \(J_{T,\text{re}}\) |
J_T_sm |
Square-modulus functional \(J_{T,\text{sm}}\) |
J_T_ss |
State-to-state phase-insensitive functional \(J_{T,\text{ss}}\) |
chis_hs |
States \(\Op{\chi}_k\) for functional \(J_{T,\text{hs}}\) |
chis_re |
States \(\ket{\chi_k}\) for functional \(J_{T,\text{re}}\) |
chis_sm |
States \(\ket{\chi_k}\) for functional \(J_{T,\text{sm}}\) |
chis_ss |
States \(\ket{\chi_k}\) for functional \(J_{T,\text{ss}}\) |
f_tau |
Average of the complex overlaps with the target states |
gate |
Gate that maps basis_states to fw_states_T |
mapped_basis |
Result of applying gate to basis_states |
__all__
: F_avg
, F_re
, F_sm
, F_ss
, J_T_hs
, J_T_re
, J_T_sm
, J_T_ss
, chis_hs
, chis_re
, chis_sm
, chis_ss
, f_tau
, gate
, mapped_basis
Reference¶
-
krotov.functionals.
f_tau
(fw_states_T, objectives, tau_vals=None, **kwargs)[source]¶ Average of the complex overlaps with the target states
That is,
\[f_{\tau} = \frac{1}{N} \sum_{k=1}^{N} w_k \tau_k\]where \(\tau_k\) are the elements of tau_vals, assumed to be
\[\tau_k = \Braket{\Psi_k(T)}{\Psi_k^{\tgt}},\]in Hilbert space, or
\[\tau_k = \tr\left[\Op{\rho}_k(T)\Op{\rho}_k^{\tgt}\right]\]in Liouville space, where \(\ket{\Psi_k}\) or \(\Op{\rho}_k\) are the elements of fw_states_T, and \(\ket{\Psi_k^{\tgt}}\) or \(\Op{\rho}^{\tgt}\) are the target states from the
target
attribute of the objectives. If tau_vals are None, they will be calculated internally.\(N\) is the number of objectives, and \(w_k\) is an optional weight for each objective. For any objective that has a (custom) weight attribute, the \(w_k\) is taken from that attribute; otherwise, \(w_k = 1\). The weights, if present, are not automatically normalized, they are assumed to have values such that the resulting \(f_{\tau}\) lies in the unit circle of the complex plane. Usually, this means that the weights should sum to \(N\). The exception would be for mixed target states, where the weights should compensate for the non-unit purity. The problem is circumvented by using
J_T_hs()
for mixed target states.The kwargs are ignored, allowing the function to be used in an info_hook.
-
krotov.functionals.
F_ss
(states_T, objectives, tau_vals=None, **kwargs)[source]¶ State-to-state phase-insensitive fidelity
\[F_{\text{ss}} = \frac{1}{N} \sum_{k=1}^{N} w_k \Abs{\tau_k}^2 \quad\in [0, 1]\]with \(N\), \(w_k\) and \(\tau_k\) as in
f_tau()
.The kwargs are ignored, allowing the function to be used in an info_hook.
-
krotov.functionals.
J_T_ss
(states_T, objectives, tau_vals=None, **kwargs)[source]¶ State-to-state phase-insensitive functional \(J_{T,\text{ss}}\)
\[J_{T,\text{ss}} = 1 - F_{\text{ss}} \quad\in [0, 1].\]All arguments are passed to
F_ss()
.
-
krotov.functionals.
chis_ss
(states_T, objectives, tau_vals)[source]¶ States \(\ket{\chi_k}\) for functional \(J_{T,\text{ss}}\)
\[\Ket{\chi_k} = -\frac{\partial J_{T,\text{ss}}}{\partial \bra{\Psi_k(T)}} = \frac{1}{N} w_k \tau_k \Ket{\Psi^{\tgt}_k}\]with \(\tau_k\) and \(w_k\) as defined in
f_tau()
.
-
krotov.functionals.
F_sm
(states_T, objectives, tau_vals=None, **kwargs)[source]¶ Square-modulus fidelity
\[F_{\text{sm}} = \Abs{f_{\tau}}^2 \quad\in [0, 1].\]All arguments are passed to
f_tau()
to evaluate \(f_{\tau}\).
-
krotov.functionals.
J_T_sm
(states_T, objectives, tau_vals=None, **kwargs)[source]¶ Square-modulus functional \(J_{T,\text{sm}}\)
\[J_{T,\text{sm}} = 1 - F_{\text{sm}} \quad\in [0, 1]\]All arguments are passed to
f_tau()
while evaluating \(F_{\text{sm}}\) inF_sm()
.
-
krotov.functionals.
chis_sm
(states_T, objectives, tau_vals)[source]¶ States \(\ket{\chi_k}\) for functional \(J_{T,\text{sm}}\)
\[\Ket{\chi_k} = -\frac{\partial J_{T,\text{sm}}}{\partial \bra{\Psi_k(T)}} = \frac{1}{N^2} w_k \sum_{j}^{N} w_j\tau_j\Ket{\Psi^{\tgt}_k}\]with optional weights \(w_k\), cf.
f_tau()
(default: \(w_k=1\)). If given, the weights should generally sum to \(N\).
-
krotov.functionals.
F_re
(fw_states_T, objectives, tau_vals=None, **kwargs)[source]¶ Real-part fidelity
\[\begin{split}F_{\text{re}} = \Re[f_{\tau}] \quad\in \begin{cases} [-1, 1] & \text{in Hilbert space} \\ [0, 1] & \text{in Liouville space.} \end{cases}\end{split}\]All arguments are passed to
f_tau()
to evaluate \(f_{\tau}\).
-
krotov.functionals.
J_T_re
(fw_states_T, objectives, tau_vals=None, **kwargs)[source]¶ Real-part functional \(J_{T,\text{re}}\)
\[\begin{split}J_{T,\text{re}} = 1 - F_{\text{re}} \quad\in \begin{cases} [0, 2] & \text{in Hilbert space} \\ [0, 1] & \text{in Liouville space.} \end{cases}\end{split}\]All arguments are passed to
f_tau()
while evaluating \(F_{\text{re}}\) inF_re()
.Note
If the fw_states_T or the target states are mixed states, it is preferable to use
J_T_hs()
, as \(J_{T,\text{re}}\) may take negative values for mixed states.
-
krotov.functionals.
chis_re
(fw_states_T, objectives, tau_vals)[source]¶ States \(\ket{\chi_k}\) for functional \(J_{T,\text{re}}\)
\[\Ket{\chi_k} = -\frac{\partial J_{T,\text{re}}}{\partial \bra{\Psi_k(T)}} = \frac{1}{2N} w_k \Ket{\Psi^{\tgt}_k}\]with optional weights \(w_k\), cf.
f_tau()
(default: \(w_k=1\)). If given, the weights should generally sum to \(N\).Note: tau_vals are ignored, but are present to satisfy the requirments of the chi_constructor interface.
-
krotov.functionals.
J_T_hs
(fw_states_T, objectives, tau_vals=None, **kwargs)[source]¶ Hilbert-Schmidt distance measure functional \(J_{T,\text{hs}}\)
\[\begin{split}J_{T,\text{hs}} = \frac{1}{2N} \sum_{k=1}^{N} w_k \Norm{\Op{\rho}_k(T) - \Op{\rho}_k^{\tgt}}_{\text{hs}}^2 \quad \in \begin{cases} [0, 2] & \text{in Hilbert space} \\ [0, 1] & \text{in Liouville space} \end{cases}\end{split}\]in Liouville space (using the Hilbert-Schmidt norm), or equivalently with \(\ket{\Psi_k(T)}\) and \(\ket{\Psi_k^{tgt}}\) in Hilbert space. The functional is evaluated as
\[J_{T,\text{hs}} = \frac{1}{2N} \sum_{k=1}^{N} w_k \left( \Norm{\Op{\rho}_k(T)}_{\text{hs}}^2 + \Norm{\Op{\rho}^{\tgt}}_{\text{hs}}^2 - 2 \Re[\tau_k] \right)\]where the \(\Op{\rho}_k\) are the elements of fw_states_T, the \(\Op{\rho}_k^{\tgt}\) are the target states from the
target
attribute of the objectives, and the \(\tau_k\) are the elements of tau_vals (which will be calculated internally if passed as None).The \(w_k\) are optional weights, cf.
f_tau()
. If given, the weights should generally sum to \(N\).The kwargs are ignored, allowing the function to be used in an info_hook.
-
krotov.functionals.
chis_hs
(fw_states_T, objectives, tau_vals)[source]¶ States \(\Op{\chi}_k\) for functional \(J_{T,\text{hs}}\)
\[\Op{\chi}_k = -\frac{\partial J_{T,\text{sm}}} {\partial \langle\!\langle \Op{\rho}_k(T)\vert} = \frac{1}{2N} w_k \left(\Op{\rho}^{\tgt}_k - \Op{\rho}_k(T)\right)\]with optional weights \(w_k\), cf.
f_tau()
(default: \(w_k=1\)).This is derived from \(J_{T,\text{hs}}\) rewritten in the abstract Hilbert-Schmidt notation \(\langle\!\langle a \vert b \rangle\!\rangle \equiv \tr[a^\dagger b]\):
\[J_{T,\text{hs}} = \frac{-1}{2N} \sum_{k=1}^{N} w_k \big( \underbrace{ \langle\!\langle \Op{\rho}_k(T) \vert \Op{\rho}_k^{\tgt} \rangle\!\rangle + \langle\!\langle \Op{\rho}_k^{\tgt}\vert \Op{\rho}_k(T) \rangle\!\rangle }_{=2\Re[\tau_k]} - \underbrace{ \langle\!\langle \Op{\rho}_k(T) \vert \Op{\rho}_k(T) \rangle\!\rangle }_{=\Norm{\Op{\rho}_k(T)}_{\text{hs}}^2} - \underbrace{ \langle\!\langle \Op{\rho}_k^{\tgt} \vert \Op{\rho}_k^{\tgt} \rangle\!\rangle }_{=\Norm{\Op{\rho}^{\tgt}}_{\text{hs}}^2} \big).\]Note: tau_vals are ignored, but are present to satisfy the requirments of the chi_constructor interface.
-
krotov.functionals.
F_avg
(fw_states_T, basis_states, gate, mapped_basis_states=None)[source]¶ Average gate fidelity
\[F_{\text{avg}} = \int \big\langle \Psi \big\vert \Op{O}^\dagger \DynMap[\ketbra{\Psi}{\Psi}] \Op{O} \big\vert \Psi \big\rangle \dd \Psi\]where \(\Op{O}\) is the target gate, and \(\DynMap\) represents the dynamical map from time zero to \(T\).
In Liouville space, this is numerically evaluated as
\[F_{\text{avg}} = \frac{1}{N (N+1)} \sum_{i,j=1}^N \left( \big\langle \phi_i \big\vert \Op{O}^\dagger \Op{\rho}_{ij} \Op{O} \big\vert \phi_j \big\rangle + \big\langle \phi_i \big\vert \Op{O}^\dagger \Op{\rho}_{jj} \Op{O} \big\vert \phi_i \big\rangle \right),\]where \(\ket{\phi_i}\) is the \(i\)’th element of basis_states, and \(\Op{\rho}_{ij}\) is the \((i-1) N + j\)’th element of fw_states_T, that is, \(\Op{\rho}_{ij} = \DynMap[\ketbra{\phi_i}{\phi_j}]\), with \(N\) the dimension of the Hilbert space.
In Hilbert space (unitary dynamics), this simplifies to
\[F_{\text{avg}} = \frac{1}{N (N+1)} \left( \Abs{\tr\left[\Op{O}^\dagger \Op{U}\right]}^2 + \tr\left[\Op{O}^\dagger \Op{U} \Op{U}^\dagger \Op{O}\right] \right),\]where \(\Op{U}\) the gate that maps basis_states to the result of a forward propagation of those basis states, stored in fw_states_T.
Parameters: - fw_states_T (list[qutip.Qobj]) – The forward propagated states. For dissipative dynamics, this must be the forward propagation of the full basis of Liouville space, that is, all \(N^2\) dyadic combinations of the Hilbert space logical basis states. For unitary dynamics, the \(N\) forward-propagated basis_states.
- basis_states (list[qutip.Qobj]) – The \(N\) Hilbert space logical basis states
- gate (qutip.Qobj) – The \(N \times N\) quantum gate in the logical
subspace, e.g.
qutip.qip.gates.cnot()
. - mapped_basis_states (None or list[qutip.Qobj]) – If given, the result of
applying gate to basis_states. If not given, this will be
calculated internally via
mapped_basis()
. It is recommended to pass pre-calculated mapped_basis_states when evaluating \(F_{\text{avg}}\) repeatedly for the same target.
-
krotov.functionals.
gate
(basis_states, fw_states_T)[source]¶ Gate that maps basis_states to fw_states_T
Example
>>> from qutip import ket >>> basis = [ket(nums) for nums in [(0, 0), (0, 1), (1, 0), (1, 1)]] >>> fw_states_T = mapped_basis(qutip.gates.cnot(), basis) >>> U = gate(basis, fw_states_T) >>> assert (U - qutip.gates.cnot()).norm() < 1e-15
-
krotov.functionals.
mapped_basis
(gate, basis_states)[source]¶ Result of applying gate to basis_states
Example
>>> from qutip import ket >>> basis = [ket(nums) for nums in [(0, 0), (0, 1), (1, 0), (1, 1)]] >>> states = mapped_basis(qutip.gates.cnot(), basis) >>> assert (states[0] - ket((0,0))).norm() < 1e-15 >>> assert (states[1] - ket((0,1))).norm() < 1e-15 >>> assert (states[2] - ket((1,1))).norm() < 1e-15 # swap (1, 1) ... >>> assert (states[3] - ket((1,0))).norm() < 1e-15 # ... and (1, 0)