Ejemplo n.º 1
0
 def build_hamiltonian(self):
     hilbertspc = self.hilbertspace_initialize()
     [transmon1, transmon2, resonator] = hilbertspc
     hres = hilbertspc.diag_hamiltonian(resonator)
     h1 = hilbertspc.diag_hamiltonian(transmon1)
     h2 = hilbertspc.diag_hamiltonian(transmon2)
     g1 = 0.1  # coupling resonator-transmon1 (without charge matrix elements)
     g2 = 0.2  # coupling resonator-transmon2 (without charge matrix elements)
     dim1 = transmon1.truncated_dim
     dim2 = transmon2.truncated_dim
     _, evecs1 = transmon1.eigensys(dim1)
     _, evecs2 = transmon2.eigensys(dim2)
     gmat1 = g1 * get_matrixelement_table(
         transmon1.n_operator(), evecs1)  # coupling constants for transmon1
     gmat2 = g2 * get_matrixelement_table(transmon2.n_operator(),
                                          evecs2)  # and for transmon2
     hbd = hilbertspc.hubbard_operator
     a = hilbertspc.annihilate(resonator)
     hamiltonian0 = h1 + h2 + hres
     vcpb1 = sum([
         gmat1[j][k] * hbd(j, k, transmon1) for j in range(dim1)
         for k in range(dim1)
     ])
     vcpb2 = sum([
         gmat2[j][k] * hbd(j, k, transmon2) for j in range(dim2)
         for k in range(dim2)
     ])
     hamiltonian1 = (vcpb1 + vcpb2) * (a + a.dag())
     return hamiltonian0 + hamiltonian1
Ejemplo n.º 2
0
    def matrixelement_table(self,
                            operator: str,
                            evecs: ndarray = None,
                            evals_count: int = 6,
                            filename: str = None,
                            return_datastore: bool = False) -> ndarray:
        """Returns table of matrix elements for `operator` with respect to the eigenstates of the qubit.
        The operator is given as a string matching a class method returning an operator matrix.
        E.g., for an instance `trm` of Transmon,  the matrix element table for the charge operator is given by
        `trm.op_matrixelement_table('n_operator')`.
        When `esys` is set to `None`, the eigensystem is calculated on-the-fly.

        Parameters
        ----------
        operator:
            name of class method in string form, returning operator matrix in qubit-internal basis.
        evecs:
            if not provided, then the necessary eigenstates are calculated on the fly
        evals_count:
            number of desired matrix elements, starting with ground state (default value = 6)
        filename:
            output file name
        return_datastore:
            if set to true, the returned data is provided as a DataStore object (default value = False)
        """
        if evecs is None:
            _, evecs = self.eigensys(evals_count=evals_count)
        operator_matrix = getattr(self, operator)()
        table = get_matrixelement_table(operator_matrix, evecs)
        if filename or return_datastore:
            data_store = DataStore(system_params=self.get_initdata(),
                                   matrixelem_table=table)
        if filename:
            data_store.filewrite(filename)
        return data_store if return_datastore else table
Ejemplo n.º 3
0
    def _zeropi_operator_in_product_basis(self,
                                          zeropi_operator,
                                          zeropi_evecs=None):
        """Helper method that converts a zeropi operator into one in the product basis.

        Returns
        -------
        scipy.sparse.csc_matrix
            operator written in the product basis
        """
        zeropi_dim = self.zeropi_cutoff
        zeta_dim = self.zeta_cutoff

        if zeropi_evecs is None:
            _, zeropi_evecs = self._zeropi.eigensys(evals_count=zeropi_dim)

        op_eigen_basis = sparse.dia_matrix(
            (zeropi_dim, zeropi_dim),
            dtype=np.complex_)  # is this guaranteed to be zero?

        op_zeropi = get_matrixelement_table(zeropi_operator, zeropi_evecs)
        for n in range(zeropi_dim):
            for m in range(zeropi_dim):
                op_eigen_basis += op_zeropi[n, m] * op.hubbard_sparse(
                    n, m, zeropi_dim)

        return sparse.kron(op_eigen_basis,
                           sparse.identity(zeta_dim,
                                           format='csc',
                                           dtype=np.complex_),
                           format='csc')
Ejemplo n.º 4
0
 def g_phi_coupling_matrix(self, zeropi_states: ndarray) -> ndarray:
     """Returns a matrix of coupling strengths g^\\phi_{ll'} [cmp. Dempster et al., Eq. (18)], using the states
     from the list `zeropi_states`. Most commonly, `zeropi_states` will contain eigenvectors of the
     `DisorderedZeroPi` type.
     """
     prefactor = self.EL * (self.dEL / 2.0) * (8.0 * self.EC / self.EL) ** 0.25
     return prefactor * spec_utils.get_matrixelement_table(self._zeropi.phi_operator(), zeropi_states)
Ejemplo n.º 5
0
 def g_theta_coupling_matrix(self, zeropi_states):
     """Returns a matrix of coupling strengths i*g^\\theta_{ll'} [cmp. Dempster et al., Eq. (17)], using the states
     from the list 'zeropi_states'.
     """
     prefactor = 1j * self.ECS * (self.dC / 2.0) * (32.0 * self.EL /
                                                    self.EC)**0.25
     return prefactor * get_matrixelement_table(
         self._zeropi.n_theta_operator(), zeropi_states)
Ejemplo n.º 6
0
    def manual_hamiltonian(self, esys1=None, esys2=None):
        hilbertspc = self.hilbertspace_initialize()
        [fluxonium, zpifull] = hilbertspc

        g1 = 0.1
        dim1 = fluxonium.truncated_dim
        if esys1 is None:
            evals1, evecs1 = fluxonium.eigensys(dim1)
        else:
            evals1, evecs1 = esys1
        dim2 = zpifull.truncated_dim
        if esys2 is None:
            evals2, evecs2 = zpifull.eigensys(dim1)
        else:
            evals2, evecs2 = esys2
        h1 = hilbertspc.diag_hamiltonian(fluxonium, evals=evals1)
        h2 = hilbertspc.diag_hamiltonian(zpifull, evals=evals2)
        nmat1 = get_matrixelement_table(
            fluxonium.n_operator(), evecs1
        )  # coupling constants for fluxonium
        nmat2 = get_matrixelement_table(
            zpifull.n_theta_operator(), evecs2
        )  # coupling constants for zeropi
        hbd = hilbertspc.hubbard_operator
        vfl = sum(
            [
                nmat1[j][k] * hbd(j, k, fluxonium)
                for j in range(dim1)
                for k in range(dim1)
            ]
        )
        vzp = sum(
            [nmat2[j][k] * hbd(j, k, zpifull) for j in range(dim2) for k in range(dim2)]
        )
        bare_hamiltonian = h1 + h2
        interaction_hamiltonian = g1 * vfl * vzp
        return bare_hamiltonian, interaction_hamiltonian
Ejemplo n.º 7
0
    def matrixelement_table(self, operator: str) -> ndarray:
        """Returns table of matrix elements for `operator` with respect to the
        eigenstates of the qubit. The operator is given as a string matching a class
        method returning an operator matrix.

        Parameters
        ----------
        operator:
            name of class method in string form, returning operator matrix in
            qubit-internal basis.
        """
        _, evecs = self.eigensys()
        operator_matrix = getattr(self, operator)()
        table = get_matrixelement_table(operator_matrix, evecs)
        return table
Ejemplo n.º 8
0
    def hamiltonian(self, flux):
        hilbertspc = self.hilbertspace_initialize()
        [transmon1, transmon2, resonator] = hilbertspc

        hres = hilbertspc.diag_hamiltonian(resonator)
        # Get diagonalized transmon1 Hamiltonian as full-system operator via tensor product with identities.

        g1 = 0.1  # coupling resonator-transmon1 (without charge matrix elements)
        g2 = 0.2  # coupling resonator-transmon2 (without charge matrix elements)
        dim1 = transmon1.truncated_dim
        dim2 = transmon2.truncated_dim

        _, evecs1 = transmon1.eigensys(dim1)
        _, evecs2 = transmon2.eigensys(dim2)
        gmat1 = g1 * get_matrixelement_table(
            transmon1.n_operator(), evecs1)  # coupling constants for transmon1
        gmat2 = g2 * get_matrixelement_table(transmon2.n_operator(),
                                             evecs2)  # and for transmon2

        hbd = hilbertspc.hubbard_operator
        a = hilbertspc.annihilate(resonator)

        vcpb1 = sum([
            gmat1[j][k] * hbd(j, k, transmon1) for j in range(dim1)
            for k in range(dim1)
        ])
        vcpb2 = sum([
            gmat2[j][k] * hbd(j, k, transmon2) for j in range(dim2)
            for k in range(dim2)
        ])

        transmon1.EJ = 40.0 * np.cos(np.pi * flux)
        h1 = hilbertspc.diag_hamiltonian(transmon1)
        h2 = hilbertspc.diag_hamiltonian(transmon2)

        return h1 + h2 + hres + (vcpb1 + vcpb2) * (a + a.dag())
Ejemplo n.º 9
0
def qubit_matrixelement(sweep, param_index, qubit_subsys, qubit_operator):
    """
    For given ParameterSweep and parameter_index, calculate the matrix elements for the provided qubit operator.

    Parameters
    ----------
    sweep: ParameterSweep
    param_index: int
    qubit_subsys: QuantumSystem
    qubit_operator: ndarray
       operator within the qubit subspace

    Returns
    -------
    ndarray
    """
    bare_evecs = sweep.lookup.bare_eigenstates(param_index, qubit_subsys)
    return spectrum_utils.get_matrixelement_table(qubit_operator, bare_evecs)
Ejemplo n.º 10
0
    def identity_wrap(self, operator, subsystem, op_in_eigenbasis=False, evecs=None):
        """Wrap given operator in subspace `subsystem` in identity operators to form full Hilbert-space operator.

        Parameters
        ----------
        operator: ndarray or qutip.Qobj or str
            operator acting in Hilbert space of `subsystem`; if str, then this should be an operator name in
            the subsystem, typically not in eigenbasis
        subsystem: object derived from QuantumSystem
            subsystem where diagonal operator is defined
        op_in_eigenbasis: bool
            whether `operator` is given in the `subsystem` eigenbasis; otherwise, the internal QuantumSystem basis is
            assumed
        evecs: ndarray, optional
            internal QuantumSystem eigenstates, used to convert `operator` into eigenbasis

        Returns
        -------
        qutip.Qobj operator
        """
        dim = subsystem.truncated_dim

        if isinstance(operator, np.ndarray):
            if op_in_eigenbasis is False:
                if evecs is None:
                    _, evecs = subsystem.eigensys(evals_count=subsystem.truncated_dim)
                operator_matrixelements = get_matrixelement_table(operator, evecs)
                subsys_operator = qt.Qobj(inpt=operator_matrixelements)
            else:
                subsys_operator = qt.Qobj(inpt=operator[:dim, :dim])
        elif isinstance(operator, str):
            if evecs is None:
                _, evecs = subsystem.eigensys(evals_count=subsystem.truncated_dim)
            operator_matrixelements = subsystem.matrixelement_table(operator, evecs=evecs)
            subsys_operator = qt.Qobj(inpt=operator_matrixelements)
        elif isinstance(operator, qt.Qobj):
            subsys_operator = operator
        else:
            raise TypeError('Unsupported operator type: ', type(operator))

        operator_identitywrap_list = [qt.operators.qeye(the_subsys.truncated_dim) for the_subsys in self]
        subsystem_index = self.get_subsys_index(subsystem)
        operator_identitywrap_list[subsystem_index] = subsys_operator
        return qt.tensor(operator_identitywrap_list)
Ejemplo n.º 11
0
def qubit_matrixelement(
    sweep: "ParameterSweep",
    param_index: int,
    qubit_subsys: "QubitBaseClass",
    qubit_operator: ndarray,
) -> ndarray:
    """
    For given ParameterSweep and parameter_index, calculate the matrix elements for the provided qubit operator.

    Parameters
    ----------
    sweep:
    param_index:
    qubit_subsys:
    qubit_operator:
       operator within the qubit subspace
    """
    bare_evecs = sweep.lookup.bare_eigenstates(qubit_subsys, param_index=param_index)
    return spec_utils.get_matrixelement_table(qubit_operator, bare_evecs)
Ejemplo n.º 12
0
    def matrixelement_table(self,
                            operator,
                            evecs=None,
                            evals_count=6,
                            filename=None):
        """Returns table of matrix elements for `operator` with respect to the eigenstates of the qubit.
        The operator is given as a string matching a class method returning an operator matrix.
        E.g., for an instance `trm` of Transmon,  the matrix element table for the charge operator is given by
        `trm.op_matrixelement_table('n_operator')`.
        When `esys` is set to `None`, the eigensystem is calculated on-the-fly.

        Parameters
        ----------
        operator: str
            name of class method in string form, returning operator matrix in qubit-internal basis.
        evecs: ndarray, optional
            if not provided, then the necesssary eigenstates are calculated on the fly
        evals_count: int, optional
            number of desired matrix elements, starting with ground state (default value = 6)
        filename: str, optional
            output file name

        Returns
        -------
        ndarray
        """
        if evecs is None:
            _, evecs = self.eigensys(evals_count=evals_count)
        operator_matrix = getattr(self, operator)()
        table = get_matrixelement_table(operator_matrix, evecs)
        if filename:
            specdata = SpectrumData(energy_table=np.empty(0),
                                    system_params=self._get_metadata_dict(),
                                    param_name='const_parameters',
                                    param_vals=np.empty(0),
                                    matrixelem_table=table)
            specdata.filewrite(filename)
        return table