Skip to content

EffectiveFrame

The EffectiveFrame class represents the effective frame obtained via perturbative transformations (such as the Schrieffer-Wolff SW transformation). It is designed to compute an effective Hamiltonian from a given zeroth-order Hamiltonian and its perturbative interaction.The class supports various methods—including full diagonalization (FD) and arbitrary coupling elimination (ACE) to generate the effective Hamiltonian and corresponding frame transformations.


Parameters

When initializing an EffectiveFrame object, the following parameters are required or available:

  • H (Expr or Matrix):
    The total Hamiltonian, including the zeroth-order Hamiltonian and any perturbative terms.

    Note: The zeroth-order Hamiltonian should be diagonal in the chosen basis.
    Note: For Schrieffer-Wolff SW transformations this parameter represents only the block-diagonal part of the Hamiltonian.

  • V (Expr or Matrix, optional):
    The perturbative interaction Hamiltonian.

    Note: For full-diagonalization FD and arbitrary coupling elimination ACE, this parameter is not required and V can be included in H. If V is provided it will be included in H automatically.

  • subspaces (list, optional):
    An ordered list of RDBasis objects to consider when forming the tensor products of the finite part of the operators.

    Note: This parameter is mandatory whenever H and V are provided as Expr.

  • symbol_values (dict, optional):
    A dictionary of symbol substitutions to be applied to the Hamiltonian and perturbative terms when numerical values are required.

  • verbose (bool, optional):
    Enables verbose logging during the computation. Defaults to True.


Attributes

  • subspaces (list):
    An ordered list of RDBasis objects to consider when forming the tensor products of the finite part of the operators.

  • commutation_relations (dict):
    A dictionary containing the commutation relations computed from the bosonic subspaces of the Hamiltonian.

Note: Additional internal attributes (prefixed with __) are used to store intermediate expressions, caching results in various forms (operator, matrix, dictionary) and managing perturbative orders. These are handled internally and typically do not need to be accessed directly by the user.

Note: After executing the methods whithin this class new attributes are created to store the results of the computation.


Methods

solve(self, max_order=2, method='SW', mask=None, extract_ns=False)

Solves for the effective Hamiltonian up to a specified perturbative order using one of the supported methods:

  • SW (Regular Schrieffer-Wolff transformation)
  • FD (Full diagonalization)
  • ACE (Arbitrary Coupling Elimination)


  • Parameters:
    • max_order (int, optional):
      Maximum perturbative order to solve for (default is 2).
    • method (str, optional):
      The transformation method to use ('SW', 'FD', or 'ACE'). Default is 'SW'.
    • mask (Block or Blocks, optional):
      A 'Block' or 'Blocks' object to determine the couplings to be elimated by ACE method.
    • extract_ns (bool, optional):
      If True, applies additional substitutions to extract number operators in the final result.

get_H(self, return_form=None)

Returns the effective Hamiltonian computed by the solver.

Note: This method should be called after solve has been executed.

  • Parameters:

    • return_form (str, optional):
      Specifies the form of the returned effective Hamiltonian. Options include:

      • 'operator': Returns the result in operator form.
      • 'matrix': Returns the matrix form.
      • 'dict_operator': Returns a dictionary form whose keys are the infinite operators and the values are the projected finite subspaces scaled by the key operator.
      • 'dict_matrix': Returns a dictionary form whose keys are the infinite operators and the values are the full matrix scaled by the key operator.

      Note: The default depends on the input form of the Hamiltonian.

  • Returns: The effective Hamiltonian in the specified form.

  • New Attributes:

    • H (Expr or Matrix or dict): The effective Hamiltonian in the specified form.
    • H_corrections (dict):
      A dictionary containing the corrections to the effective Hamiltonian at each perturbative order.

get_U(self, return_form=None)

Returns the effective frame transformation \( U \), representing the transformation operator.

Note: This method should be called after solve has been executed.

  • Parameters:

    • return_form (str, optional):
      Specifies the form of the returned unitary transformation. Options include:

      • 'operator': Returns the result in operator form.
      • 'matrix': Returns the matrix form.
      • 'dict_operator': Returns a dictionary form whose keys are the infinite operators and the values are the projected finite subspaces scaled by the key operator.
      • 'dict_matrix': Returns a dictionary form whose keys are the infinite operators and the values are the full matrix scaled by the key operator.

      Note: The default depends on the input form of the Hamiltonian.

  • Returns: The unitary transformation in the specified form.

  • New Attributes:

    • U (Expr or Matrix or dict):
      The unitary transformation in the specified form.
    • U_corrections (dict):
      A dictionary containing the corrections to the unitary transformation at each perturbative order.

get_S(self, return_form=None, extract_ns=False)

Returns the generator of the effective frame transformation \( S \).

Note: This method should be called after solve has been executed.

  • Parameters:

    • return_form (str, optional):
      Specifies the form of the returned generator transformation. Options include:

      • 'operator': Returns the result in operator form.
      • 'matrix': Returns the matrix form.
      • 'dict_operator': Returns a dictionary form whose keys are the infinite operators and the values are the projected finite subspaces scaled by the key operator.
      • 'dict_matrix': Returns a dictionary form whose keys are the infinite operators and the values are the full matrix scaled by the key operator.

      Note: The default depends on the input form of the Hamiltonian. - extract_ns (bool, optional):
      If True, applies substitutions to extract bosonic number operators.

  • Returns: The generator transformation in the specified form.

  • New Attributes:

    • S (Expr or Matrix or dict):
      The generator transformation in the specified form.
    • S_corrections (dict):
      A dictionary containing the corrections to the generator transformation at each perturbative order.

rotate(self, expr, max_order=None, return_form=None, extract_ns=False)

Rotates a given expression using the computed transformation \( U \). This method is useful for rotating operators into the effective frame.

Note: This method should be called after solve has been executed.

  • Parameters:

    • expr (Expr):
      The Expr (operator or matrix) to be rotated.
    • max_order (int, optional):
      Maximum order to consider during the rotation. If not provided, the maximum order solved is used.
    • return_form (str, optional):
      Specifies the form of the rotated expression (same options as in get_H).
    • extract_ns (bool, optional):
      If True, applies substitutions to extract number operators.
  • Returns:
    The rotated expression in the specified form.


Usage Examples

System found in Qubit-flip-induced cavity mode squeezing in the strong dispersive regime of the quantum Rabi model 10.1038/srep45587

Importing the required libraries

# sympt imports
from sympt import *
# Import sympy
import sympy as sp

Setup the symbols and basis operators

# ---------------- Defining the symbols ------------------
# Order 0
omega = RDSymbol('omega', order=0, positive=True, real=True)
Omega_z = RDSymbol('Omega_z', order=0, positive=True, real=True)
# Order 1
g = RDSymbol('g', order=1, positive=True, real=True)

# ----------------- Defining the basis -------------------
# Spin basis: Finite 2x2 Hilbert space
Spin = RDBasis('sigma', dim=2)
s0, sx, sy, sz = Spin.basis # Pauli Operators
# Boson basis: Infinite bosonic Hilbert space
a = BosonOp('a')
ad = Dagger(a)

# -------------- Defining the Hamiltonian ----------------
# Unperturbed Hamiltonian H0
H0 = omega * ad * a + sp.Rational(1,2) * Omega_z * sz
display(H0)
# Interaction Hamiltonian V
V = g * (ad + a) * sx
display(V)

\(\displaystyle \frac{\Omega_{z} \sigma_{3}}{2} + \omega {a^\dagger} a\)

\(\displaystyle g \left({a^\dagger} + a\right) \sigma_{1}\)

# Deffining Effective Hamiltonian Object
Eff_frame = EffectiveFrame(H0, V, subspaces=[Spin], verbose = False)

Standard Schrieffer-Wolff Transformation

# Calculate the effective model using the Schrieffer-Wolff transformation up to the second order
Eff_frame.solve(max_order=2, method='SW')
# Obtaining the result in the operator form
H_eff_SWT = Eff_frame.get_H(return_form='operator')
H_eff_SWT

\(\displaystyle \frac{\Omega_{z} g^{2} \sigma_{3}}{\Omega_{z}^{2} - \omega^{2}} + \frac{2 \Omega_{z} g^{2} \sigma_{3} {a^\dagger} a}{\Omega_{z}^{2} - \omega^{2}} + \frac{\Omega_{z} g^{2} \sigma_{3} {a^\dagger}^{2}}{\Omega_{z}^{2} - \omega^{2}} + \frac{\Omega_{z} g^{2} \sigma_{3} a^{2}}{\Omega_{z}^{2} - \omega^{2}} + \frac{\Omega_{z} \sigma_{3}}{2} + \frac{g^{2} \omega}{\Omega_{z}^{2} - \omega^{2}} + \omega {a^\dagger} a\)

Multiblock Arbitrary Coupling Elimination

# Deffining the mask
mask = Block(fin=sx.matrix, inf=a)
# Calculate the effective model using the Mask routine up to the second order
Eff_frame.solve(max_order=2, method='ACE', mask=mask)
H_eff_Mask = Eff_frame.get_H(return_form='operator')
H_eff_Mask

\(\displaystyle \frac{\Omega_{z} g^{2} \sigma_{3}}{\Omega_{z}^{2} - \omega^{2}} + \frac{2 \Omega_{z} g^{2} \sigma_{3} {a^\dagger} a}{\Omega_{z}^{2} - \omega^{2}} + \frac{\Omega_{z} g^{2} \sigma_{3} {a^\dagger}^{2}}{\Omega_{z}^{2} - \omega^{2}} + \frac{\Omega_{z} g^{2} \sigma_{3} a^{2}}{\Omega_{z}^{2} - \omega^{2}} + \frac{\Omega_{z} \sigma_{3}}{2} + \frac{g^{2} \omega}{\Omega_{z}^{2} - \omega^{2}} + \omega {a^\dagger} a\)

Full-diagonalization

# Calculate the effective model using the Full Diagonalization routine up to the second order
Eff_frame.solve(max_order=2, method='FD')
H_eff_FD = Eff_frame.get_H(return_form='operator')
H_eff_FD

\(\displaystyle \frac{\Omega_{z} g^{2} \sigma_{3}}{\Omega_{z}^{2} - \omega^{2}} + \frac{2 \Omega_{z} g^{2} \sigma_{3} {a^\dagger} a}{\Omega_{z}^{2} - \omega^{2}} + \frac{\Omega_{z} \sigma_{3}}{2} + \frac{g^{2} \omega}{\Omega_{z}^{2} - \omega^{2}} + \omega {a^\dagger} a\)

display_dict(Eff_frame.H_corrections)

\(\displaystyle 0 : \frac{\Omega_{z} \sigma_{3}}{2} + \omega {a^\dagger} a\)

\(\displaystyle 2 : \frac{\Omega_{z} g^{2} \sigma_{3}}{\Omega_{z}^{2} - \omega^{2}} + \frac{2 \Omega_{z} g^{2} \sigma_{3} {a^\dagger} a}{\Omega_{z}^{2} - \omega^{2}} + \frac{g^{2} \omega}{\Omega_{z}^{2} - \omega^{2}}\)

Get Unitary of the Full Diagonalization

U = Eff_frame.get_U()
U

\(\begin{aligned} &1 - \frac{\Omega_{z} g^{2} \omega \sigma_{3}}{\Omega_{z}^{4} - 2 \Omega_{z}^{2} \omega^{2} + \omega^{4}} + \frac{\Omega_{z} g^{2} \sigma_{3} {a^\dagger}^{2}}{2 \Omega_{z}^{2} \omega - 2 \omega^{3}} - \frac{\Omega_{z} g^{2} \sigma_{3} a^{2}}{2 \Omega_{z}^{2} \omega - 2 \omega^{3}} - \frac{g^{2} {a^\dagger}^{2}}{2 \Omega_{z}^{2} - 2 \omega^{2}} - \frac{g^{2} a^{2}}{2 \Omega_{z}^{2} - 2 \omega^{2}} + \\ &+\frac{- \Omega_{z}^{2} g^{2} - g^{2} \omega^{2}}{2 \Omega_{z}^{4} - 4 \Omega_{z}^{2} \omega^{2} + 2 \omega^{4}} + \frac{\left(- \Omega_{z}^{2} g^{2} - g^{2} \omega^{2}\right) {a^\dagger} a}{\Omega_{z}^{4} - 2 \Omega_{z}^{2} \omega^{2} + \omega^{4}} + \left(\frac{i \Omega_{z} g \sigma_{2}}{\Omega_{z}^{2} - \omega^{2}} - \frac{g \omega \sigma_{1}}{\Omega_{z}^{2} - \omega^{2}}\right) {a^\dagger} +\\ & + \left(\frac{i \Omega_{z} g \sigma_{2}}{\Omega_{z}^{2} - \omega^{2}} + \frac{g \omega \sigma_{1}}{\Omega_{z}^{2} - \omega^{2}}\right) a \end{aligned}\)

display_dict(Eff_frame.U_corrections)

\(\displaystyle 0 : 1\)

\(\displaystyle 1 : \left(\frac{i \Omega_{z} g \sigma_{2}}{\Omega_{z}^{2} - \omega^{2}} - \frac{g \omega \sigma_{1}}{\Omega_{z}^{2} - \omega^{2}}\right) {a^\dagger} + \left(\frac{i \Omega_{z} g \sigma_{2}}{\Omega_{z}^{2} - \omega^{2}} + \frac{g \omega \sigma_{1}}{\Omega_{z}^{2} - \omega^{2}}\right) a\)

\(\begin{aligned} 2 : &- \frac{\Omega_{z} g^{2} \omega \sigma_{3}}{\Omega_{z}^{4} - 2 \Omega_{z}^{2} \omega^{2} + \omega^{4}} + \frac{\Omega_{z} g^{2} \sigma_{3} {a^\dagger}^{2}}{2 \Omega_{z}^{2} \omega - 2 \omega^{3}} - \frac{\Omega_{z} g^{2} \sigma_{3} a^{2}}{2 \Omega_{z}^{2} \omega - 2 \omega^{3}} - \frac{g^{2} {a^\dagger}^{2}}{2 \Omega_{z}^{2} - 2 \omega^{2}} - \frac{g^{2} a^{2}}{2 \Omega_{z}^{2} - 2 \omega^{2}} +\\ & + \frac{- \Omega_{z}^{2} g^{2} - g^{2} \omega^{2}}{2 \Omega_{z}^{4} - 4 \Omega_{z}^{2} \omega^{2} + 2 \omega^{4}} + \frac{\left(- \Omega_{z}^{2} g^{2} - g^{2} \omega^{2}\right) {a^\dagger} a}{\Omega_{z}^{4} - 2 \Omega_{z}^{2} \omega^{2} + \omega^{4}} \end{aligned}\)

Get the generator of the Full Diagonalization

S = Eff_frame.get_S()
S

\(\displaystyle - \frac{\Omega_{z} g^{2} \sigma_{3} {a^\dagger}^{2}}{2 \Omega_{z}^{2} \omega - 2 \omega^{3}} + \frac{\Omega_{z} g^{2} \sigma_{3} a^{2}}{2 \Omega_{z}^{2} \omega - 2 \omega^{3}} + \left(- \frac{i \Omega_{z} g \sigma_{2}}{\Omega_{z}^{2} - \omega^{2}} - \frac{g \omega \sigma_{1}}{\Omega_{z}^{2} - \omega^{2}}\right) a + \left(- \frac{i \Omega_{z} g \sigma_{2}}{\Omega_{z}^{2} - \omega^{2}} + \frac{g \omega \sigma_{1}}{\Omega_{z}^{2} - \omega^{2}}\right) {a^\dagger}\)

display_dict(Eff_frame.S_corrections)

\(\displaystyle 0 : 0.0\)

\(\displaystyle 1 : \left(- \frac{i \Omega_{z} g \sigma_{2}}{\Omega_{z}^{2} - \omega^{2}} - \frac{g \omega \sigma_{1}}{\Omega_{z}^{2} - \omega^{2}}\right) a + \left(- \frac{i \Omega_{z} g \sigma_{2}}{\Omega_{z}^{2} - \omega^{2}} + \frac{g \omega \sigma_{1}}{\Omega_{z}^{2} - \omega^{2}}\right) {a^\dagger}\)

\(\displaystyle 2 : - \frac{\Omega_{z} g^{2} \sigma_{3} {a^\dagger}^{2}}{2 \Omega_{z}^{2} \omega - 2 \omega^{3}} + \frac{\Omega_{z} g^{2} \sigma_{3} a^{2}}{2 \Omega_{z}^{2} \omega - 2 \omega^{3}}\)

Rotate a drving term into the new frame

# ----- Rotating a Drving term into the new basis ----
# Define the symbol for the driving term
E0 = RDSymbol('E0', order=0, positive=True, real=True)
omega_D = RDSymbol('omega_D', order=0, positive=True, real=True)
# Define the driving term
H_drive = E0 * sp.cos(omega_D * t) * (a + ad)
display(H_drive)

# Rotate the driving term into the new basis
Eff_frame.rotate(H_drive, max_order=1, return_form='operator').cancel()

\(\displaystyle E_{0} \cos{\omega_D t}\left({a^\dagger} + a\right)\)

Converting to operator form: 100%|██████████| 3/3 [00:00<00:00, 207.01it/s]

\(\displaystyle E_{0}\cos{\omega_D t} \left(\frac{2 g \omega \sigma_{1}}{\Omega_{z}^{2} - \omega^{2}} + {a^\dagger} + a\right)\)

License

SymPT is licensed under the MIT License. See the LICENSE file for details.


Citation

If you use SymPT in your research, please cite the following paper:

BibTeX Entry:

@misc{diotallevi2024symptcomprehensivetoolautomating,
      title={SymPT: a comprehensive tool for automating effective Hamiltonian derivations}, 
      author={Giovanni Francesco Diotallevi and Leander Reascos and Mónica Benito},
      year={2024},
      eprint={2412.10240},
      archivePrefix={arXiv},
      primaryClass={quant-ph},
      url={https://arxiv.org/abs/2412.10240}, 
}

APA Citation:

Diotallevi, G. F., Reascos, L., & Benito, M. (2024). SymPT: a comprehensive tool for automating effective Hamiltonian derivations. arXiv preprint arXiv:2412.10240.

IEEE Citation:

G. F. Diotallevi, L. Reascos, and M. Benito, "SymPT: a comprehensive tool for automating effective Hamiltonian derivations," arXiv preprint arXiv:2412.10240, 2024.


References