def eigensys(self, evals_count=6, filename=None): """Calculates eigenvalues and corresponding eigenvectors using `scipy.linalg.eigh`. Returns two numpy arrays containing the eigenvalues and eigenvectors, respectively. Parameters ---------- evals_count: int, optional number of desired eigenvalues/eigenstates (default value = 6) filename: str, optional path and filename without suffix, if file output desired (default value = None) Returns ------- ndarray, ndarray eigenvalues, eigenvectors """ evals, evecs = self._esys_calc(evals_count) if filename: specdata = SpectrumData('const_parameters', param_vals=np.empty(0), energy_table=evals, system_params=self._get_metadata_dict(), state_table=evecs) specdata.filewrite(filename) return evals, evecs
def _recast_bare_eigendata(self, static_eigendata, bare_eigendata): """ Parameters ---------- static_eigendata: list of eigensystem tuples bare_eigendata: list of eigensystem tuples Returns ------- list of SpectrumData """ specdata_list = [] for index, subsys in enumerate(self.hilbertspace): if subsys in self.subsys_update_list: evals_count = subsys.truncated_dim dim = subsys.hilbertdim() esys_dtype = subsys._evec_dtype energy_table = np.empty(shape=(self.param_count, evals_count), dtype=np.float_) state_table = np.empty(shape=(self.param_count, dim, evals_count), dtype=esys_dtype) for j in range(self.param_count): energy_table[j] = bare_eigendata[j][index][0] state_table[j] = bare_eigendata[j][index][1] specdata_list.append(SpectrumData(self.param_name, self.param_vals, energy_table, subsys.__dict__, state_table)) else: specdata_list.append(SpectrumData(self.param_name, self.param_vals, energy_table=static_eigendata[index][0], system_params=subsys.__dict__, state_table=static_eigendata[index][1])) return specdata_list
def get_matelements_vs_paramvals(self, operator, param_name, param_vals, evals_count=6, filename=None): """Calculates matrix elements for a varying system parameter, given an array of parameter values. Returns a `SpectrumData` object containing matrix element data, eigenvalue data, and eigenstate data.. Parameters ---------- operator: str name of class method in string form, returning operator matrix param_name: str name of parameter to be varied param_vals: ndarray parameter values to be plugged in evals_count: int, optional number of desired eigenvalues (sorted from smallest to largest) (default value = 6) filename: str, optional write data to file if path and filename are specified (default value = None) Returns ------- SpectrumData object """ previous_paramval = getattr(self, param_name) paramvals_count = len(param_vals) eigenvalue_table = np.zeros((paramvals_count, evals_count), dtype=np.float_) eigenstate_table = np.empty(shape=(paramvals_count, self.hilbertdim(), evals_count), dtype=np.complex_) matelem_table = np.empty(shape=(paramvals_count, evals_count, evals_count), dtype=np.complex_) for index, paramval in tqdm(enumerate(param_vals), total=len(param_vals), **TQDM_KWARGS): setattr(self, param_name, paramval) evals, evecs = self.eigensys(evals_count) eigenstate_table[index] = evecs eigenvalue_table[index] = evals matelem_table[index] = self.matrixelement_table( operator, evals_count=evals_count) setattr(self, param_name, previous_paramval) spectrumdata = SpectrumData(param_name, param_vals, eigenvalue_table, self._get_metadata_dict(), state_table=eigenstate_table, matrixelem_table=matelem_table) if filename: spectrumdata.filewrite(filename) return spectrumdata
def get_spectrum_vs_paramvals(self, hamiltonian_func, param_vals, evals_count=10, get_eigenstates=False, param_name="external_parameter", filename=None): """Return eigenvalues (and optionally eigenstates) of the full Hamiltonian as a function of a parameter. Parameter values are specified as a list or array in `param_vals`. The Hamiltonian `hamiltonian_func` must be a function of that particular parameter, and is expected to internally set subsystem parameters. If a `filename` string is provided, then eigenvalue data is written to that file. Parameters ---------- hamiltonian_func: function of one parameter function returning the Hamiltonian in `qutip.Qobj` format param_vals: ndarray of floats array of parameter values evals_count: int, optional number of desired energy levels (default value = 10) get_eigenstates: bool, optional set to true if eigenstates should be returned as well (default value = False) param_name: str, optional name for the parameter that is varied in `param_vals` (default value = "external_parameter") filename: str, optional write data to file if path/filename is provided (default value = None) Returns ------- SpectrumData object """ paramvals_count = len(param_vals) eigenenergy_table = np.empty((paramvals_count, evals_count)) if get_eigenstates: eigenstatesQobj_table = [0] * paramvals_count else: eigenstatesQobj_table = None for param_index, paramval in tqdm(enumerate(param_vals), total=len(param_vals), **TQDM_KWARGS): paramval = param_vals[param_index] hamiltonian = hamiltonian_func(paramval) if get_eigenstates: eigenenergies, eigenstates_Qobj = hamiltonian.eigenstates(eigvals=evals_count) eigenenergy_table[param_index] = eigenenergies eigenstatesQobj_table[param_index] = eigenstates_Qobj else: eigenenergies = hamiltonian.eigenenergies(eigvals=evals_count) eigenenergy_table[param_index] = eigenenergies spectrumdata = SpectrumData(param_name, param_vals, eigenenergy_table, self.__dict__, state_table=eigenstatesQobj_table) if filename: spectrumdata.filewrite(filename) return spectrumdata
def test_plot_wavefunction(self): testname = self.file_str + '_1' specdata = SpectrumData.create_from_fileread(DATADIR + testname) self.qbt = self.qbt_type.create_from_dict( specdata._get_metadata_dict()) self.qbt.plot_wavefunction(esys=None, which=5, mode='real') self.qbt.plot_wavefunction(esys=None, which=9, mode='abs_sqr')
def test_matrixelement_table(self): testname = self.file_str + '_5' specdata = SpectrumData.create_from_fileread(DATADIR + testname) self.qbt = self.qbt_type.create_from_dict( specdata._get_metadata_dict()) matelem_reference = specdata.matrixelem_table return self.matrixelement_table(self.op1_str, matelem_reference)
def get_difference_spectrum(self, initial_state_ind=0): """Takes spectral data of energy eigenvalues and subtracts the energy of a select state, given by its state index. Parameters ---------- initial_state_ind: int or (i1, i2, ...) index of the initial state whose energy is supposed to be subtracted from the spectral data Returns ------- SpectrumData object """ param_count = self.param_count evals_count = self.evals_count diff_eigenenergy_table = np.empty(shape=(param_count, evals_count)) for param_index in tqdm(range(param_count), **TQDM_KWARGS): eigenenergies = self.dressed_specdata.energy_table[param_index] if isinstance(initial_state_ind, int): eigenenergy_index = initial_state_ind else: eigenenergy_index = self.hilbertspace.lookup_dressed_index(initial_state_ind, param_index) diff_eigenenergies = eigenenergies - eigenenergies[eigenenergy_index] diff_eigenenergy_table[param_index] = diff_eigenenergies return SpectrumData(self.param_name, self.param_vals, diff_eigenenergy_table, self.hilbertspace.__dict__)
def test_eigenvecs(self): testname = self.file_str + '_2' specdata = SpectrumData.create_from_fileread(DATADIR + testname) self.qbt = self.qbt_type.create_from_dict( specdata._get_metadata_dict()) evecs_reference = specdata.state_table return self.eigenvecs(evecs_reference)
def test_plot_matelem_vs_paramvals(self): testname = self.file_str + '_1' specdata = SpectrumData.create_from_fileread(DATADIR + testname) self.qbt = self.qbt_type.create_from_dict( specdata._get_metadata_dict()) self.plot_matelem_vs_paramvals(self.op1_str, self.param_name, self.param_list, select_elems=[(0, 0), (1, 4), (1, 0)])
def test_get_spectrum_vs_paramvals(self): testname = self.file_str + '_4' specdata = SpectrumData.create_from_fileread(DATADIR + testname) self.qbt = self.qbt_type.create_from_dict( specdata._get_metadata_dict()) self.param_list = specdata.param_vals evecs_reference = specdata.state_table evals_reference = specdata.energy_table return self.get_spectrum_vs_paramvals(self.param_name, self.param_list, evals_reference, evecs_reference)
def eigenvals(self, evals_count=6, filename=None): """Calculates eigenvalues using `scipy.linalg.eigh`, returns numpy array of eigenvalues. Parameters ---------- evals_count: int number of desired eigenvalues/eigenstates (default value = 6) filename: str, optional path and filename without suffix, if file output desired (default value = None) Returns ------- ndarray """ evals = self._evals_calc(evals_count) if filename: specdata = SpectrumData('const_parameters', param_vals=np.empty(0), energy_table=evals, system_params=self._get_metadata_dict()) specdata.filewrite(filename) return evals
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('const_parameters', param_vals=np.empty(0), energy_table=np.empty(0), system_params=self._get_metadata_dict(), matrixelem_table=table) specdata.filewrite(filename) return table
def _recast_dressed_eigendata(self, dressed_eigendata): """ Parameters ---------- dressed_eigendata: list of tuple(evals, qutip evecs) Returns ------- SpectrumData """ evals_count = self.evals_count energy_table = np.empty(shape=(self.param_count, evals_count), dtype=np.float_) state_table = [] # for dressed states, entries are Qobj for j in range(self.param_count): energy_table[j] = dressed_eigendata[j][0] state_table.append(dressed_eigendata[j][1]) specdata = SpectrumData(self.param_name, self.param_vals, energy_table, state_table=state_table, system_params=self.hilbertspace._get_metadata_dict()) return specdata
def get_n_photon_qubit_spectrum(self, photonnumber, initial_state_labels=0): """ Extracts energies for transitions among qubit states only, while all oscillator subsystems maintain their excitation level. Parameters ---------- photonnumber: int number of photons used in transition initial_state_labels: tuple(int1, int2, ...) bare-state labels of the initial state whose energy is supposed to be subtracted from the spectral data Returns ------- SpectrumData object """ def generate_target_states_list(): target_states_list = [] for subsys_index, qbt_subsys in self.hilbertspace.qbt_subsys_list: initial_qbt_state = initial_state_labels[subsys_index] for state_label in range(initial_qbt_state + 1, qbt_subsys.truncated_dim): target_labels = list(initial_state_labels) target_labels[subsys_index] = state_label target_states_list.append(tuple(target_labels)) return target_states_list target_states_list = generate_target_states_list() difference_energies_table = [] for param_index in range(self.param_count): difference_energies = [] initial_energy = self.lookup_energy_bare_index(initial_state_labels, param_index) for target_labels in target_states_list: target_energy = self.lookup_energy_bare_index(target_labels, param_index) if target_energy is None or initial_energy is None: difference_energies.append(np.NaN) else: difference_energies.append((target_energy - initial_energy) / photonnumber) difference_energies_table.append(difference_energies) return target_states_list, SpectrumData(self.param_name, self.param_vals, np.asarray(difference_energies_table), self.hilbertspace.__dict__)
def test_print_matrixelements(self): testname = self.file_str + '_1' specdata = SpectrumData.create_from_fileread(DATADIR + testname) self.qbt = self.qbt_type.create_from_dict( specdata._get_metadata_dict()) self.print_matrixelements(self.op2_str)
def test_plot_evals_vs_paramvals(self): testname = self.file_str + '_1' specdata = SpectrumData.create_from_fileread(DATADIR + testname) self.qbt = self.qbt_type.create_from_dict( specdata._get_metadata_dict()) return self.plot_evals_vs_paramvals(self.param_name, self.param_list)
def get_spectrum_vs_paramvals(self, param_name, param_vals, evals_count=6, subtract_ground=False, get_eigenstates=False, filename=None): """Calculates eigenvalues for a varying system parameter, given an array of parameter values. Returns a `SpectrumData` object with `energy_data[n]` containing eigenvalues calculated for parameter value `param_vals[n]`. Parameters ---------- param_name: str name of parameter to be varied param_vals: ndarray parameter values to be plugged in evals_count: int, optional number of desired eigenvalues (sorted from smallest to largest) (default value = 6) subtract_ground: bool, optional if True, eigenvalues are returned relative to the ground state eigenvalue (default value = False) get_eigenstates: bool, optional return eigenstates along with eigenvalues (default value = False) filename: str, optional write data to file if path and filename are specified (default value = None) Returns ------- SpectrumData object """ previous_paramval = getattr(self, param_name) paramvals_count = len(param_vals) eigenvalue_table = np.zeros((paramvals_count, evals_count), dtype=np.float_) if get_eigenstates: eigenstate_table = np.empty(shape=(paramvals_count, self.hilbertdim(), evals_count), dtype=self._evec_dtype) else: eigenstate_table = None for index, paramval in tqdm(enumerate(param_vals), total=len(param_vals), **TQDM_KWARGS): setattr(self, param_name, paramval) if get_eigenstates: evals, evecs = self.eigensys(evals_count) eigenstate_table[index] = evecs else: evals = self.eigenvals(evals_count) eigenvalue_table[index] = np.real( evals ) # for complex-hermitean H, eigenvalues have type np.complex_ if subtract_ground: eigenvalue_table[index] -= evals[0] setattr(self, param_name, previous_paramval) spectrumdata = SpectrumData(param_name, param_vals, eigenvalue_table, self._get_metadata_dict(), state_table=eigenstate_table) if filename: spectrumdata.filewrite(filename) return spectrumdata