def generate_lookup(self): bare_specdata_list = [] for index, subsys in enumerate(self): evals, evecs = subsys.eigensys(evals_count=subsys.truncated_dim) bare_specdata_list.append(storage.SpectrumData(energy_table=[evals], state_table=[evecs], system_params=subsys.get_initdata())) evals, evecs = self.eigensys(evals_count=self.dimension) dressed_specdata = storage.SpectrumData(energy_table=[evals], state_table=[evecs], system_params=self.get_initdata()) self._lookup = spec_lookup.SpectrumLookup(self, bare_specdata_list=bare_specdata_list, dressed_specdata=dressed_specdata)
def _recast_bare_eigendata( self, static_eigendata: List[List[Tuple[ndarray, ndarray]]], bare_eigendata: List[List[Tuple[ndarray, ndarray]]], ) -> List[SpectrumData]: specdata_list = [] for index, subsys in enumerate(self._hilbertspace): if subsys in self.subsys_update_list: eigendata = bare_eigendata else: eigendata = static_eigendata 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] = eigendata[j][index][0] state_table[j] = eigendata[j][index][1] specdata_list.append( storage.SpectrumData( energy_table, system_params={}, param_name=self.param_name, param_vals=self.param_vals, state_table=state_table, )) return specdata_list
def generate_diffspec_sweep(sweep, initial_state_ind=0): """Takes spectral data of energy eigenvalues and subtracts the energy of a select state, given by its state index. Parameters ---------- sweep: ParameterSweep 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 """ lookup = sweep.lookup param_count = sweep.param_count evals_count = sweep.evals_count diff_eigenenergy_table = np.empty(shape=(param_count, evals_count)) for param_index in tqdm( range(param_count), desc="difference spectrum", leave=False, disable=settings.PROGRESSBAR_DISABLED, ): eigenenergies = sweep.dressed_specdata.energy_table[param_index] if isinstance(initial_state_ind, int): eigenenergy_index = initial_state_ind else: eigenenergy_index = lookup.dressed_index(initial_state_ind, param_index) diff_eigenenergies = eigenenergies - eigenenergies[eigenenergy_index] diff_eigenenergy_table[param_index] = diff_eigenenergies return storage.SpectrumData(diff_eigenenergy_table, sweep.system_params, sweep.param_name, sweep.param_vals)
def get_spectrum_vs_paramvals(self, param_vals, update_hilbertspace, evals_count=10, get_eigenstates=False, param_name="external_parameter", num_cpus=settings.NUM_CPUS): """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 ---------- param_vals: ndarray of floats array of parameter values update_hilbertspace: function update_hilbertspace(param_val) specifies how a change in the external parameter affects the Hilbert space components 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") num_cpus: int, optional number of cores to be used for computation (default value: settings.NUM_CPUS) Returns ------- SpectrumData object """ target_map = cpu_switch.get_map_method(num_cpus) if get_eigenstates: func = functools.partial(self._esys_for_paramval, update_hilbertspace=update_hilbertspace, evals_count=evals_count) with utils.InfoBar("Parallel computation of eigenvalues [num_cpus={}]".format(num_cpus), num_cpus): eigensystem_mapdata = list(target_map(func, tqdm(param_vals, desc='Spectral data', leave=False, disable=(num_cpus > 1)))) eigenvalue_table, eigenstate_table = spec_utils.recast_esys_mapdata(eigensystem_mapdata) else: func = functools.partial(self._evals_for_paramval, update_hilbertspace=update_hilbertspace, evals_count=evals_count) with utils.InfoBar("Parallel computation of eigensystems [num_cpus={}]".format(num_cpus), num_cpus): eigenvalue_table = list(target_map(func, tqdm(param_vals, desc='Spectral data', leave=False, disable=(num_cpus > 1)))) eigenvalue_table = np.asarray(eigenvalue_table) eigenstate_table = None return storage.SpectrumData(eigenvalue_table, self.get_initdata(), param_name, param_vals, state_table=eigenstate_table)
def _recast_dressed_eigendata( self, dressed_eigendata: List[Tuple[ndarray, QutipEigenstates]]) -> 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] = np.real_if_close(dressed_eigendata[j][0]) state_table.append(dressed_eigendata[j][1]) specdata = storage.SpectrumData(energy_table, system_params={}, param_name=self.param_name, param_vals=self.param_vals, state_table=state_table) return specdata
def generate_qubit_transitions_sweep(sweep, photonnumber, initial_state_labels): """ Extracts energies for transitions among qubit states only, while all oscillator subsys_list maintain their excitation level. Parameters ---------- sweep: ParameterSweep 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 ------- list, SpectrumData list of transition target states, spectrum data """ lookup = sweep.lookup target_states_list = spec_utils.generate_target_states_list( sweep, initial_state_labels) difference_energies_table = [] for param_index in range(sweep.param_count): difference_energies = [] initial_energy = lookup.energy_bare_index(initial_state_labels, param_index) for target_labels in target_states_list: target_energy = 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) data = np.asarray(difference_energies_table) specdata = storage.SpectrumData(data, sweep.system_params, sweep.param_name, sweep.param_vals) return target_states_list, specdata
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 = storage.SpectrumData(energy_table, system_params={}, param_name=self.param_name, param_vals=self.param_vals, state_table=state_table) return specdata