Basics#
Interactive use of the scqubits
library from a jupyter notebook starts with importing the scqubits
library.
[2]:
import numpy as np
import scqubits as scq
Example: Transmon qubit#
To illustrate basic functionality built into scqubits, we consider the implementation of the transmon qubit as an example. Each qubit type is represented by a class that accomplishes storage of relevant data, such as circuit parameters, and provides a collection of methods used for common computations and plotting. (A more systematic discussion of the set of qubits available in scqubits is given in the subsequent section.)
An instance of the transmon qubit is set up by creating an instance of the class Transmon
and providing the necessary system parameters for initialization:
[3]:
transmon = scq.Transmon(
EJ=30.0,
EC=1.2,
ng=0.3,
ncut=31
)
Or, alternatively, we can use the graphical user interface (if the ipywidgets
package is installed):
[4]:
tmon = scq.Transmon.create()
Warning
scqubits does not check convergence with respect to Hilbert space truncation. For example, in the case of the transmon qubit, this regards the charge cutoff ncut
. Responsibility to establish convergence with respect to cutoffs lies with the user.
Computing and plotting energy spectra#
The energy eigenvalues of the transmon Hamiltonian are obtained by calling the eigenvals()
method. The optional parameter evals_count
specifies the sought number of eigenenergies:
[5]:
transmon.eigenvals(evals_count=12)
[5]:
array([-21.82665096, -6.1637235 , 8.0193175 , 20.04763559,
30.53712535, 38.70154385, 54.55166998, 67.49080961,
90.05007774, 107.1126152 , 135.67738991, 156.68121682])
To plot eigenenergies as a function of one of the qubit parameters (EJ
, EC
, or ng
), the first step is to generate an array of values for the desired parameter. Then, call the method plot_evals_vs_paramvals
, specifying the parameter to be varied as a string. The following is an example for eigenenergies as a function of offset charge ng
:
[6]:
ng_list = np.linspace(-2, 2, 220)
transmon.plot_evals_vs_paramvals('ng', ng_list, evals_count=5, subtract_ground=False);
Plotting routines generally return a matplotlib.Figure and a matplotlib.axes object, in case further processing is desired.
The full eigensystem consisting of both eigenvalues and eigenvectors is obtained through the method eigensys()
. For the transmon qubit, the calculation proceeds in the charge basis, and uses scipy.linalg.eigh
for matrix diagonalization. Accordingly, the eigenvector corresponding to the lowest eigenvalue is evecs.T[0]
.
[7]:
evals, evecs = transmon.eigensys()
Plotting energy dispersion#
The sensitivity of energy levels (or, more specifically, transition energies) to changes in an external parameter like the offset charge are important for qubit’s dephasing time. Plots of the energy dispersion, can be obtained easily:
either for individual energy levels:
[20]:
EJvals = np.linspace(0.1, 35, 100)
tmon.plot_dispersion_vs_paramvals('ng', 'EJ', EJvals, ref_param='EC', levels=(0,1,2));
or for transition energies:
[19]:
EJvals = np.linspace(0.1, 35, 100)
tmon.plot_dispersion_vs_paramvals('ng', 'EJ', EJvals, ref_param='EC', transitions=(((0,1), (0,2))));
Plotting wavefunctions#
For a qubit as simple as the transmon, wavefunctions are one-dimensional and can be plotted easily. The first option, is to employ the discrete charge basis (n
):
[9]:
transmon.plot_n_wavefunction(esys=None, which=0, mode='real');
Here, esys=None
signifies that the eigensystem is not provided as an argument, but should be calculated fresh. which=0
specifies that the ground state wavefunction is to be plotted. Finally, mode='real'
is asking for a plot of the real parts of the wavefunction amplitudes.
The options for mode
are:
mode keyword |
extracted function of amplitudes |
---|---|
|
real part of wavefunction amplitudes |
|
imaginary part of wavefunction amplitudes |
|
absolute value of wavefunction amplitudes |
|
absolute value squared of wavefunction amplitudes |
Instead of the charge-basis representation, the transmon wavefunction can also be plotted in phi representation by switching from n
to phi
. Multiple wavefunctions can be plotted simultaneously by feeding a tuple to the argument which
:
[10]:
transmon.plot_phi_wavefunction(esys=None, which=[0,1,2,3,4], mode='real');
Wavefunctions are displayed on top of the cosine potential, and are offset by their corresponding eigenenergies.
Evaluating and visualizing matrix elements#
For a number of purposes, one needs to compute matrix elements of operators such as the charge operator with respect to the eigenstates of the system. For a display of the matrix elements of the operator n_operator
(the charge number operator), use:
[11]:
transmon.plot_matrixelements('n_operator', evals_count=10);
An alternative way to display matrix elements is to use a pure 2d representation with text representation of each matrix element entry. Here, we use the example of the .cos_phi_operator
:
[12]:
transmon.plot_matrixelements('cos_phi_operator', evals_count=10, show3d=False, show_numbers=True);
To store the matrix elements in a numpy array, utilize the method matrixelement_table()
:
[13]:
nmat = transmon.matrixelement_table('sin_phi_operator', evals_count=3)
nmat
[13]:
array([[0.+6.93889390e-018j, 0.-4.71298793e-001j, 0.-1.26356452e-003j],
[0.+4.71298793e-001j, 0.-1.38777878e-017j, 0.-5.72832824e-001j],
[0.+1.26356452e-003j, 0.+5.72832824e-001j, 0.+2.35410818e-101j]])
Sometimes it is useful to plot matrix elements as a function of an external parameter. This is accomplished by the method plot_matelem_vs_paramvals()
, here for the dependence of charge-operator matrix elements on the offset charge ng
:
[14]:
ng_list = np.linspace(-2, 2, 220)
transmon.plot_matelem_vs_paramvals('n_operator', 'ng', ng_list, select_elems=4);
[ ]: