Template Struct UnitaryEvolver

Struct Documentation

template<int n_ctrl = Dynamic, int dim = Dynamic, typename Matrix = DMatrix<dim, dim>>
struct UnitaryEvolver

A struct to store the diagonalised drift and control Hamiltonians. On initialisation the Hamiltonians are diagonalised and the eigenvectors and values stored. This initial diagonalisation may be slow and takes \(O(\texttt{dim}^3)\) time for a \(\texttt{dim}\times \texttt{dim}\) Hamiltonian. However, it allows each step of the Suzuki-Trotter expansion to be implimented in \(O(\texttt{dim}^2)\) time with matrix multiplication and only scalar exponentiation opposed to matrix exponentiation which takes \(O(\texttt{dim}^3)\) time.

Template Parameters:
  • n_ctrl – The number of control Hamiltonians.

  • dim – The dimension of the vector space the Hamiltonians act upon.

  • Matrix – The type of matrix to use. Matrix must take the value DMatrix<dim, dim> or SMatrix for dense or sparse matrices, respectively.

Public Functions

template<typename T = Matrix>
inline UnitaryEvolver(std::enable_if_t<std::is_same<T, DMatrix<dim, dim>>::value, DMatrix<dim, dim>> drift_hamiltonian, DMatrix<dim_x_n_ctrl, dim> control_hamiltonians)

Initialises a new unitary evolver with the Hamiltonian

\[ H(t)=H_0+\sum_{j=1}^{\texttt{length}}a_j(t)H_j, \]
where \(H_0\) is the drift Hamiltonian and \(H_j\) are the control Hamiltonians modulated by control amplitudes \(a_j(t)\) which need not be specified during initialisation.

Also see us_individual, us, and u0_inverse.

Parameters:
  • drift_hamiltonian – The drift Hamiltonian.

  • control_hamiltonians – The control Hamiltonians.

template<typename T = Matrix>
inline UnitaryEvolver(std::enable_if_t<std::is_same<T, SMatrix>::value, DMatrix<dim, dim>> drift_hamiltonian, DMatrix<dim_x_n_ctrl, dim> control_hamiltonians)

Initialises a new unitary evolver with a sparse Hamiltonian.

\[ H(t)=H_0+\sum_{j=1}^{\texttt{length}}a_j(t)H_j, \]
where \(H_0\) is the drift Hamiltonian and \(H_j\) are the control Hamiltonians modulated by control amplitudes \(a_j(t)\) which need not be specified during initialisation.

Parameters:
  • drift_hamiltonian – The drift Hamiltonian.

  • control_hamiltonians – The control Hamiltonians.

inline UnitaryEvolver(size_t l, Eigen::Array<complex<double>, dim, 1> d0, vector<Eigen::Array<complex<double>, dim, 1>> ds, Matrix u0, Matrix u0_inverse, vector<Matrix> us, vector<Matrix> us_individual, vector<Matrix> us_inverse_individual, vector<Matrix> control_hamiltonians, Matrix u0_inverse_u_last)

Initialises a new unitary evolver using the struct attributes.

Parameters:
  • l – The number of control Hamiltonians. Initialises length.

  • d0 – The eigenvalues, \(\operatorname{diag}(D_0)\), of the drift Hamiltonian: \(H_0=U_0D_0U_0^\dagger\). Initialises d0.

  • ds – The eigenvalues, \(\left(\operatorname{diag}(D_i)\right)_{i=1}^{\texttt{length}}\), of the control Hamiltonians: \(H_i=U_iD_iU_i^\dagger\) for all \(i\in\left[\texttt{length}\right]\). Initialises ds.

  • u0 – The unitary transformation, \(U_0\), that diagonalises the drift Hamiltonian: \(H_0=U_0D_0U_0^\dagger\). Initialises u0.

  • u0_inverse – The inverse of the unitary transformation, \(U_0^\dagger\), that diagonalises the drift Hamiltonian: \(H_0=U_0D_0U_0^\dagger\). Initialises u0_inverse.

  • us – The unitary transformations, \((U_i^\dagger U_{i-1})_{i=1}^{\texttt{length}}\), from the eigen basis of \(H_{i-1}\) to the eigen basis of \(H_i\). Initialises us.

  • us_individual – The unitary transformations, \(\left(U_i\right)_{i=1}^{\texttt{length}}\), that diagonalise the control Hamiltonians: \(H_i=U_iD_iU_i^\dagger\) for all \(i\in\left[\texttt{length}\right]\). Initialises us_individual.

  • us_inverse_individual – The inverse of the unitary transformations, \((U_i^\dagger)_{i=1}^{\texttt{length}}\), that diagonalise the control Hamiltonians: \(H_i=U_iD_iU_i^\dagger\) for all \(i\in\left[\texttt{length}\right]\). Initialises us_inverse_individual.

  • control_hamiltonians – The control Hamiltonians: \(H_i\) for all \(i\in\left[\texttt{length}\right]\). Initialises hs.

  • u0_inverse_u_last – The unitary transformation, \(U_0^\dagger U_{\texttt{length}}\), from the eigen basis of \(H_{\texttt{length}}\) to the eigen basis of \(H_0\). Initialises u0_inverse_u_last.

inline DMatrix<dim, 1> propagate(DMatrix<Dynamic, n_ctrl> ctrl_amp, DMatrix<dim, 1> state, double dt)

Propagates the state vector using the first-order Suzuki-Trotter expansion. More precisely, a state vector, \(\psi(0)\), is evolved under the differential equation

\[ \dot\psi=-iH\psi \]
using the first-order Suzuki-Trotter expansion:
\[\begin{split} \begin{align} \psi(N\Delta t)&=\prod_{i=1}^N\prod_{j=0}^{\texttt{length}} e^{-ia_{ij}H_j\Delta t}\psi(0)+\mathcal E\\ &=\prod_{i=1}^N\prod_{j=0}^{\texttt{length}} U_je^{-ia_{ij}D_j\Delta t}U_j^\dagger\psi(0)+\mathcal E. \end{align} \end{split}\]
where \(a_{nj}\coloneqq a(n\Delta t)\), we set \(a_{n0}=1\) for notational ease, and the additive error \(\mathcal E\) is
\[\begin{split} \begin{align} \mathcal E&=\mathcal O\left( \Delta t^2\left[\sum_{i=1}^N\sum_{j=1}^{\texttt{length}}\dot a_{ij} \norm{H_j} +\sum_{i=1}^N\sum_{j,k=0}^{\texttt{length}}a_{ij}a_{ik} \norm{[H_j,H_k]}\right] \right)\\ &=\mathcal O\left( N\Delta t^2\cdot\texttt{length} \left[\omega E+\alpha^2E^2\cdot\texttt{length}\right] \right) \end{align} \end{split}\]
where \(\dot a_{nj}\coloneqq\dot a_j(n\Delta t)\) and
\[\begin{split} \begin{align} \omega&\coloneqq\max_{\substack{i\in\left[1,N\right]\\ j\in\left[1,\texttt{length}\right]}}\left|\dot a_{ij}\right|,\\ \alpha&\coloneqq\max_{\substack{i\in\left[1,N\right]\\ j\in\left[0,\texttt{length}\right]}}\left|a_{ij}\right|,\\ E&\coloneqq\max_{j\in\left[0,\texttt{length}\right]}\norm{H_j}. \end{align} \end{split}\]
Note the error is quadratic in \(\Delta t\) but linear in \(N\). We can also view this as being linear in \(\Delta t\) and linear in total evolution time \(N\Delta t\). Additionally, by Nyquist’s theorem this asymptotic error scaling will not be achieved until the time step \(\Delta t\) is smaller than \(\frac{1}{2\Omega}\) where \(\Omega\) is the largest energy or frequency in the system.

Also see propagate_all(), propagate_collection(), and get_evolution().

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\texttt{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • state\(\left[\psi(0)\right]\) The state vector to propagate.

  • dt – ( \(\Delta t\)) The time step to propagate by.

Returns:

The propagated state vector: \(\psi(N\Delta t)\).

template<int l = Dynamic>
inline DMatrix<dim, l> propagate_collection(DMatrix<Dynamic, n_ctrl> ctrl_amp, DMatrix<dim, l> states, double dt)

Propagates a collection of state vectors using the first-order Suzuki-Trotter expansion. More precisely, a collection of state vectors, \(\left(\psi_k(0)\right)_{k}\), are evolved under the differential equation

\[ \dot\psi_k=-iH\psi_k \]
using the first-order Suzuki-Trotter expansion:
\[\begin{split} \begin{align} \psi_k(N\Delta t)&=\prod_{i=1}^N\prod_{j=0}^{\texttt{length}} e^{-ia_{ij}H_j\Delta t}\psi_k(0)+\mathcal E\\ &=\prod_{i=1}^N\prod_{j=0}^{\texttt{length}} U_je^{-ia_{ij}D_j\Delta t}U_j^\dagger\psi_k(0)+\mathcal E. \end{align} \end{split}\]
where \(a_{nj}\coloneqq a(n\Delta t)\), we set \(a_{n0}=1\) for notational ease, and the addative error \(\mathcal E\) is
\[\begin{split} \begin{align} \mathcal E&=\mathcal O\left( \Delta t^2\left[\sum_{i=1}^N\sum_{j=1}^{\texttt{length}}\dot a_{ij} \norm{H_j} +\sum_{i=1}^N\sum_{j,k=0}^{\texttt{length}}a_{ij}a_{ik} \norm{[H_j,H_k]}\right] \right)\\ &=\mathcal O\left( N\Delta t^2\cdot\texttt{length} \left[\omega E+\alpha^2E^2\cdot\texttt{length}\right] \right) \end{align} \end{split}\]
where \(\dot a_{nj}\coloneqq\dot a_j(n\Delta t)\) and
\[\begin{split} \begin{align} \omega&\coloneqq\max_{\substack{i\in\left[1,N\right]\\ j\in\left[1,\texttt{length}\right]}}\left|\dot a_{ij}\right|,\\ \alpha&\coloneqq\max_{\substack{i\in\left[1,N\right]\\ j\in\left[0,\texttt{length}\right]}}\left|a_{ij}\right|,\\ E&\coloneqq\max_{j\in\left[0,\texttt{length}\right]}\norm{H_j}. \end{align} \end{split}\]
Note the error is quadratic in \(\Delta t\) but linear in \(N\). We can also view this as being linear in \(\Delta t\) and linear in total evolution time \(N\Delta t\). Additionally, by Nyquist’s theorem this asymptotic error scaling will not be achieved until the time step \(\Delta t\) is smaller than \(\frac{1}{2\Omega}\) where \(\Omega\) is the largest energy or frequency in the system.

Also see propagate(), propagate_all(), and get_evolution().

Template Parameters:

l – The number of state vectors to propagate.

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\texttt{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • states\(\left[\left(\psi(0)\right)_{k}\right]\) A collection of state vectors to propagate expressed as a matrix with each column corresponding to a state vector.

  • dt – ( \(\Delta t\)) The time step to propagate by.

Returns:

The propagated state vectors: \(\left(\psi_k(N\Delta t)\right)_k\).

inline DMatrix<dim, Dynamic> propagate_all(DMatrix<Dynamic, n_ctrl> ctrl_amp, DMatrix<dim, 1> state, double dt)

Propagates the state vector using the first-order Suzuki-Trotter expansion and returns the resulting state vector at every time step. More precisely, a state vector, \(\psi(0)\), is evolved under the differential equation

\[ \dot\psi=-iH\psi \]
using the first-order Suzuki-Trotter expansion:
\[\begin{split} \begin{align} \psi(n\Delta t)&=\prod_{i=1}^n\prod_{j=0}^{\texttt{length}} e^{-ia_{ij}H_j\Delta t}\psi(0)+\mathcal E \quad\forall n\in\left[0, N\right]\\ &=\prod_{i=1}^n\prod_{j=0}^{\texttt{length}} U_je^{-ia_{ij}D_j\Delta t}U_j^\dagger\psi(0)+\mathcal E \quad\forall n\in\left[0, N\right]. \end{align} \end{split}\]
where \(a_{nj}\coloneqq a(n\Delta t)\), we set \(a_{n0}=1\) for notational ease, and the additive error \(\mathcal E\) is
\[\begin{split} \begin{align} \mathcal E&=\mathcal O\left( \Delta t^2\left[\sum_{i=1}^N\sum_{j=1}^{\texttt{length}}\dot a_{ij} \norm{H_j} +\sum_{i=1}^N\sum_{j,k=0}^{\texttt{length}}a_{ij}a_{ik} \norm{[H_j,H_k]}\right] \right)\\ &=\mathcal O\left( N\Delta t^2\cdot\texttt{length} \left[\omega E+\alpha^2E^2\cdot\texttt{length}\right] \right) \end{align} \end{split}\]
where \(\dot a_{nj}\coloneqq\dot a_j(n\Delta t)\) and
\[\begin{split} \begin{align} \omega&\coloneqq\max_{\substack{i\in\left[1,N\right]\\ j\in\left[1,\texttt{length}\right]}}\left|\dot a_{ij}\right|,\\ \alpha&\coloneqq\max_{\substack{i\in\left[1,N\right]\\ j\in\left[0,\texttt{length}\right]}}\left|a_{ij}\right|,\\ E&\coloneqq\max_{j\in\left[0,\texttt{length}\right]}\norm{H_j}. \end{align} \end{split}\]
Note the error is quadratic in \(\Delta t\) but linear in \(N\). We can also view this as being linear in \(\Delta t\) and linear in total evolution time \(N\Delta t\). Additionally, by Nyquist’s theorem this asymptotic error scaling will not be achieved until the time step \(\Delta t\) is smaller than \(\frac{1}{2\Omega}\) where \(\Omega\) is the largest energy or frequency in the system.

Also see propagate(), propagate_collection(), and get_evolution().

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\texttt{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • state\(\left[\psi(0)\right]\) The state vector to propagate.

  • dt – ( \(\Delta t\)) The time step to propagate by.

Returns:

The propagated state vector at each time step: \(\left(\psi(n\Delta t)\right)_{n=0}^N\).

inline complex<double> evolved_expectation_value(DMatrix<Dynamic, n_ctrl> ctrl_amp, DMatrix<dim, 1> state, double dt, DMatrix<dim, dim> observable)

Calculates the expectation value with respect to an observable of an evolved state vector evolved under a control Hamiltonian modulated by the control amplitudes. The integration is performed using propagate().

Also see evolved_expectation_value_all()

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\texttt{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • state\(\left[\psi(0)\right]\) The state vector to propagate.

  • dt – ( \(\Delta t\)) The time step to propagate by.

  • observable\((\hat O)\) The observable to calculate the expectation value of.

Returns:

The expectation value of the observable: \(\langle\hat O\rangle \equiv\psi^\dagger(N\Delta t)\hat O\psi(N\Delta t)\).

inline DMatrix<Dynamic, 1> evolved_expectation_value_all(DMatrix<Dynamic, n_ctrl> ctrl_amp, DMatrix<dim, 1> state, double dt, DMatrix<dim, dim> observable)

Calculates the expectation values with respect to an observable of a time series of state vectors evolved under a control Hamiltonian modulated by the control amplitudes. The integration is performed using propagate_all().

Also see evolved_expectation_value()

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\texttt{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • state\(\left[\psi(0)\right]\) The state vector to propagate.

  • dt – ( \(\Delta t\)) The time step to propagate by.

  • observable\((\hat O)\) The observable to calculate the expectation value of.

Returns:

The expectation value of the observable: \(\left(\psi^\dagger(n\Delta t)\hat O\psi(N\Delta t)\right)_{n=0}^N\).

inline complex<double> evolved_inner_product(DMatrix<Dynamic, n_ctrl> ctrl_amp, DMatrix<dim, 1> state, double dt, DMatrix<1, dim> fixed_vector)

Calculates the real inner product of an evolved state vector with a fixed vector. The evolved state vector is evolved under a control Hamiltonian modulated by the control amplitudes. The integration is performed using propagate().

Also see evolved_inner_product_all().

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\textrm{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • state\(\left[\psi(0)\right]\) The state vector to propagate.

  • dt – ( \(\Delta t\)) The time step to propagate by.

  • fixed_vector\((\xi)\) The fixed vector to calculate the inner product with.

Returns:

The inner product of the evolved state vector with the fixed vector: \(\sum_{i=1}^\texttt{dim}\xi_i\psi_i(N\Delta t)\).

inline DMatrix<Dynamic, 1> evolved_inner_product_all(DMatrix<Dynamic, n_ctrl> ctrl_amp, DMatrix<dim, 1> state, double dt, DMatrix<1, dim> fixed_vector)

Calculates the real inner products of a time series of evolved state vectors with a fixed vector. The evolved state vector is evolved under a control Hamiltonian modulated by the control amplitudes. The integration is performed using propagate_all().

Also see evolved_inner_product().

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\textrm{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • state\(\left[\psi(0)\right]\) The state vector to propagate.

  • dt – ( \(\Delta t\)) The time step to propagate by.

  • fixed_vector\((\xi)\) The fixed vector to calculate the inner product with.

Returns:

The inner products of the evolved state vectors with the fixed vector: \(\left( \sum_{i=1}^\texttt{dim}\xi_i\psi_i(n\Delta t)\right)_{n=0}^N\).

inline std::tuple<complex<double>, Eigen::Matrix<double, Dynamic, n_ctrl>> switching_function(DMatrix<Dynamic, n_ctrl> ctrl_amp, DMatrix<dim, 1> state, double dt, DMatrix<dim, dim> cost)

Calculates the switching function for a Mayer problem with an expectation value as the cost function. More precisely if the cost function is

\[ J\left[\vec a(t)\right]\coloneqq\langle\hat O\rangle \equiv\psi^\dagger[\vec a(t);T] \hat O\psi[\vec a(t);T], \]
where \(T=N\Delta t\), then the switching function is
\[ \phi_j(t)\coloneqq\frac{\delta J}{\delta a_j(t)} =2\operatorname{Im}\left(\psi^\dagger[\vec a(t);T] \hat OU(t\to T)H_j\psi[\vec a(t);t]\right). \]
using the first-order Suzuki-Trotter expansion we can express the switching function as
\[\begin{split} \begin{align} &\phi_j(n\Delta t)=\frac{1}{\Delta t}\pdv{J}{a_{nj}}\\ &=\!2\operatorname{Im}\!\left(\psi^\dagger(T) \hat O\!\!\left[\prod_{i>n}^N\prod_{k=1}^{\texttt{length}} e^{-ia_{ik}H_k\Delta t}\right]\!\!\! \left[\prod_{k=j}^{\texttt{length}} e^{-ia_{nk}H_k\Delta t}\right]\!H_j\!\! \left[\prod_{k=0}^{j-1} e^{-ia_{nk}H_k\Delta t}\right] \!\psi(\left[n-1\right]\Delta t)\right), \end{align} \end{split}\]
where for numerical efficiency we replace \(e^{-ia_{ik}H_k\Delta t}\) with \(U_ke^{-ia_{ik}D_k\Delta t}U_k^\dagger\) as in propagate().

Also see gate_switching_function().

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\texttt{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • state\(\left[\psi(0)\right]\) The initial state vector.

  • dt – ( \(\Delta t\)) The time step.

  • cost\((\hat O)\) The observable to calculate the expectation value of.

Returns:

The expectation value, \(\psi^\dagger(T)\hat O\psi(T)\), and the switching function, \(\phi_j(n\Delta t)\) for all \(j\in\left[1,\texttt{length}\right]\) and \(n\in\left[1,N\right]\).

inline DMatrix<dim, dim> get_evolution(DMatrix<Dynamic, n_ctrl> ctrl_amp, double dt)

Computes the unitary corresponding to the evolution under the differential equation

\[ \dot U=-iHU. \]
The computation is performed using the first-order Suzuki-Trotter expansion:
\[\begin{split} \begin{align} U(N\Delta t)&=\prod_{i=1}^N\prod_{j=0}^{\textrm{length}} e^{-ia_{ij}H_j\Delta t}+\mathcal E\\ &=\prod_{i=1}^N\prod_{j=0}^{\textrm{length}} U_je^{-ia_{ij}D_j\Delta t}U_j^\dagger+\mathcal E. \end{align} \end{split}\]
where \(a_{nj}\coloneqq a(n\Delta t)\), we set $a_{n0}=1$ for notational ease, and the additive error \(\mathcal E\) is
\[\begin{split} \begin{align} \mathcal E&=\mathcal O\left( \Delta t^2\left[\sum_{i=1}^N\sum_{j=1}^{\textrm{length}}\dot a_{ij} \norm{H_j} +\sum_{i=1}^N\sum_{j,k=0}^{\textrm{length}}a_{ij}a_{ik} \norm{[H_j,H_k]}\right] \right)\\ &=\mathcal O\left( N\Delta t^2\textrm{length}\left[\omega E+\alpha^2+E^2\right] \right) \end{align} \end{split}\]
where \(\dot a_{nj}\coloneqq\dot a_j(n\Delta t)\) and
\[\begin{split} \begin{align} \omega&\coloneqq\max_{\substack{i\in\left[1,N\right]\\ j\in\left[1,\textrm{length}\right]}}\left|\dot a_{ij}\right|,\\ \alpha&\coloneqq\max_{\substack{i\in\left[1,N\right]\\ j\in\left[0,\textrm{length}\right]}}\left|a_{ij}\right|,\\ E&\coloneqq\max_{j\in\left[0,\textrm{length}\right]}\norm{H_j}. \end{align} \end{split}\]
Note the error is quadratic in \(\Delta t\) but linear in \(N\). We can also view this as being linear in \(\Delta t\) and linear in total evolution time \(N\Delta t\). Additionally, by Nyquist’s theorem this asymptotic error scaling will not be achieved until the time step \(\Delta t\) is smaller than \(\frac{1}{2\Omega}\) where \(\Omega\) is the largest energy or frequency in the system.

Also see propagate(), propagate_all(), and propagate_collection().

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\textrm{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • dt – ( \(\Delta t\)) The time step to evolve by.

Returns:

The unitary corresponding to the evolution: \(U(N\Delta t)\).

inline double evolved_gate_infidelity(DMatrix<Dynamic, n_ctrl> ctrl_amp, double dt, DMatrix<dim, dim> target)

Calculates the gate infidelity with respect to a target gate of the gate produced by the control Hamiltonian modulated by the control amplitudes. The integration is performed using get_evolution().

Also see unitary_gate_infidelity().

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\textrm{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • dt – ( \(\Delta t\)) The time step to evolve by.

  • target – The target gate to calculate the infidelity with respect to.

Returns:

The gate infidelity with respect to the target gate:

\[ \mathcal I(U(N\Delta t), \texttt{target}) \coloneqq 1-\frac{ \left|\Tr\left[\texttt{target}^\dagger\cdot U(N\Delta t)\right]\right|^2 +\texttt{dim}}{\texttt{dim}(\texttt{dim}+1)}. \]

inline std::tuple<double, Eigen::Matrix<double, Dynamic, n_ctrl>> gate_switching_function(DMatrix<Dynamic, n_ctrl> ctrl_amp, double dt, DMatrix<dim, dim> target)

Calculates the switching function for a Mayer problem with the gate infidelity as the cost function. More precisely if the cost function is

\[ J\left[\vec a(t)\right] \coloneqq\mathcal I(U\left[\vec a(t); T\right], \texttt{target}) \coloneqq 1-\frac{\left|\Tr\left[\texttt{target}^\dagger \cdot U\left[\vec a(t); T\right]\right]\right|^2 +\texttt{dim}}{\texttt{dim}(\texttt{dim}+1)}. \]
where \(T=N\Delta t\), then the switching function is
\[\begin{split} \begin{align} &\phi_j(t)\coloneqq\frac{\delta J}{\delta a_j(t)}\\ &=\frac{2}{\texttt{dim}(\texttt{dim}+1)}\operatorname{Im}\left( \Tr\left[U^\dagger(N\Delta t)\cdot\texttt{target}\right] \Tr\left[\texttt{target}^\dagger \cdot U(t\to T)H_j U[\vec a(t);t]\right]\right). \end{align} \end{split}\]
Using the first-order Suzuki-Trotter expansion we can express the switching function as
\[\begin{split} \begin{align} &\phi_j(n\Delta t)=\frac{1}{\Delta t}\pdv{J}{a_{nj}}\\ &=\!\frac{2}{\texttt{dim}(\texttt{dim}+1)}\operatorname{Im} \!\left( \Tr\!\left[U^\dagger(N\Delta t)\cdot\texttt{target}\right] \vphantom{[\prod_{k=j}^{\textrm{length}}}\right.\\ &\left.\cdot\Tr\!\left[\texttt{target}^\dagger\!\cdot\! \left[\prod_{i>n}^N\prod_{k=1}^{\textrm{length}} e^{-ia_{ik}H_k\Delta t}\right]\!\!\! \left[\prod_{k=j}^{\textrm{length}} e^{-ia_{nk}H_k\Delta t}\right]\!H_j\!\! \left[\prod_{k=0}^{j-1} e^{-ia_{nk}H_k\Delta t}\right] \! U(\left[n-1\right]\Delta t)\right]\right), \end{align} \end{split}\]
where for numerical efficiency we replace \(e^{-ia_{ik}H_k\Delta t}\) with \(U_ke^{-ia_{ik}D_k\Delta t}U_k^\dagger\) as in get_evolution().

Also see switching_function().

Parameters:
  • ctrl_amp\(\left(a_{ij}\right)\) The control amplitudes at each time step expressed as an \(N\times\textrm{length}\) matrix where the element \(a_{ij}\) corresponds to the control amplitude of the \(j\)th control Hamiltonian at the \(i\)th time step.

  • dt – ( \(\Delta t\)) The time step.

  • target – The target gate to calculate the infidelity with respect to.

Returns:

The gate infidelity, \(I(U\left[\vec a(t); T\right], \texttt{target})\) and the switching function, \(\phi_j(n\Delta t)\) for all \(j\in\left[1,\textrm{length}\right]\) and \(n\in\left[1,N\right]\).

Public Members

size_t length

The number of control Hamiltonians

Eigen::Array<complex<double>, dim, 1> d0

The eigenvalues, \(\operatorname{diag}(D_0)\), of the drift Hamiltonian: \(H_0=U_0D_0U_0^\dagger\).

vector<Eigen::Array<complex<double>, dim, 1>> ds

The eigenvalues, \(\left(\operatorname{diag}(D_i)\right)_{i=1}^{\texttt{length}}\), of the control Hamiltonians: \(H_i=U_iD_iU_i^\dagger\) for all \(i\in\left[\texttt{length}\right]\).

Also see ds, u0, and u0_inverse.

Matrix u0

The unitary transformation, \(U_0\), that diagonalises the drift Hamiltonian: \(H_0=U_0D_0U_0^\dagger\).

Also see d0, us_individual, us_inverse_individual, and hs.

Matrix u0_inverse

The inverse of the unitary transformation, \(U_0^\dagger\), that diagonalises the drift Hamiltonian: \(H_0=U_0D_0U_0^\dagger\).

Also see us_individual, d0, and u0_inverse.

vector<Matrix> us

The unitary transformations, \((U_i^\dagger U_{i-1})_{i=1}^{\texttt{length}}\), from the eigen basis of \(H_{i-1}\) to the eigen basis of \(H_i\).

Also see us_inverse_individual, u0, and d0.

vector<Matrix> us_individual

The unitary transformations, \(\left(U_i\right)_{i=1}^{\texttt{length}}\), that diagonalise the control Hamiltonians: \(H_i=U_iD_iU_i^\dagger\) for all \(i\in\left[\texttt{length}\right]\).

Also see us_individual, and us_inverse_individual.

vector<Matrix> us_inverse_individual

The inverse of the unitary transformations, \((U_i^\dagger)_{i=1}^{\texttt{length}}\), that diagonalise the control Hamiltonians: \(H_i=U_iD_iU_i^\dagger\) for all \(i\in\left[\texttt{length}\right]\).

Also see us_inverse_individual, us, ds, and hs.

vector<Matrix> hs

The control Hamiltonians: \(H_i\) for all \(i\in\left[\texttt{length}\right]\).

Also see us_individual, us, ds, and hs.

Matrix u0_inverse_u_last

The unitary transformation, \(U_0^\dagger U_{\texttt{length}}\), from the eigen basis of \(H_{\texttt{length}}\) to the eigen basis of \(H_0\).

Also see us_individual, us_inverse_individual, and ds.

Public Static Attributes

static const int dim_x_n_ctrl = (dim == Dynamic || n_ctrl == Dynamic) ? Dynamic : dim * n_ctrl

The dimension of rows in each control Hamiltonian multiplied by the number of control Hamiltonians. This is the number of rows in the control_hamiltonians argument of UnitaryEvolver::UnitaryEvolver().