Esempio n. 1
0
    def _compute_dressed_specdata_sweep(
            self, bare_specdata_list: List[SpectrumData]) -> SpectrumData:
        """
        Calculates and returns all dressed spectral data.
        """
        self._bare_hamiltonian_constant = self._compute_bare_hamiltonian_constant(
            bare_specdata_list)
        param_indices = range(self.param_count)
        func = functools.partial(self._compute_dressed_eigensystem,
                                 bare_specdata_list=bare_specdata_list)
        target_map = cpu_switch.get_map_method(self.num_cpus)

        with utils.InfoBar(
                "Parallel compute dressed eigensys [num_cpus={}]".format(
                    self.num_cpus),
                self.num_cpus,
        ):
            dressed_eigendata = list(
                target_map(
                    func,
                    tqdm(
                        param_indices,
                        desc="Dressed spectrum",
                        leave=False,
                        disable=self.tqdm_disabled,
                    ),
                ))
        dressed_specdata = self._recast_dressed_eigendata(dressed_eigendata)
        del dressed_eigendata
        return dressed_specdata
Esempio n. 2
0
 def _compute_bare_specdata_sweep(self) -> List[SpectrumData]:
     """
     Pre-calculates all bare spectral data needed for the interactive explorer display.
     """
     bare_eigendata_constant = [self._compute_bare_spectrum_constant()
                                ] * self.param_count
     target_map = cpu_switch.get_map_method(self.num_cpus)
     with utils.InfoBar(
             "Parallel compute bare eigensys [num_cpus={}]".format(
                 self.num_cpus),
             self.num_cpus,
     ):
         bare_eigendata_varying = list(
             target_map(
                 self._compute_bare_spectrum_varying,
                 tqdm(
                     self.param_vals,
                     desc="Bare spectra",
                     leave=False,
                     disable=self.tqdm_disabled,
                 ),
             ))
     bare_specdata_list = self._recast_bare_eigendata(
         bare_eigendata_constant, bare_eigendata_varying)
     del bare_eigendata_constant
     del bare_eigendata_varying
     return bare_specdata_list
Esempio n. 3
0
    def _subsys_bare_spectrum_sweep(self, subsystem) -> ndarray:
        """

        Parameters
        ----------
        subsystem:
            subsystem for which the bare spectrum sweep is to be computed

        Returns
        -------
            multidimensional array of the format
            array[p1, p2, p3, ..., pN] = np.asarray[[evals, evecs]]
        """
        fixed_paramnames = self._paramnames_no_subsys_update(subsystem)
        reduced_parameters = self._parameters.create_reduced(fixed_paramnames)
        total_count = np.prod(
            [len(param_vals) for param_vals in reduced_parameters])

        multi_cpu = self._num_cpus > 1
        target_map = cpu_switch.get_map_method(self._num_cpus)

        with utils.InfoBar(
                "Parallel compute bare eigensys [num_cpus={}]".format(
                    self._num_cpus),
                self._num_cpus,
        ) as p:
            bare_eigendata = tqdm(
                target_map(
                    functools.partial(
                        self._update_subsys_compute_esys,
                        self._update_hilbertspace,
                        subsystem,
                    ),
                    itertools.product(*reduced_parameters.paramvals_list),
                ),
                total=total_count,
                desc="Bare spectra",
                leave=False,
                disable=multi_cpu,
            )

        bare_eigendata = np.asarray(list(bare_eigendata), dtype=object)
        bare_eigendata = bare_eigendata.reshape(
            (*reduced_parameters.counts, 2))

        # Bare spectral data was only computed once for each parameter that has no
        # update effect on the subsystems. Now extend the array to reflect this
        # for the full parameter array by repeating
        for name in fixed_paramnames:
            index = self._parameters.index_by_name[name]
            param_count = self._parameters.counts[index]
            bare_eigendata = np.repeat(bare_eigendata, param_count, axis=index)

        return bare_eigendata
Esempio n. 4
0
    def _dressed_spectrum_sweep(
        self, ) -> Tuple[NamedSlotsNdarray, NamedSlotsNdarray]:
        """

        Returns
        -------
            NamedSlotsNdarray[<paramname1>, <paramname2>, ...] of eigenvalues,
            likewise for eigenvectors
        """
        multi_cpu = self._num_cpus > 1
        target_map = cpu_switch.get_map_method(self._num_cpus)
        total_count = np.prod(self._parameters.counts)

        with utils.InfoBar(
                "Parallel compute dressed eigensys [num_cpus={}]".format(
                    self._num_cpus),
                self._num_cpus,
        ) as p:
            spectrum_data = list(
                tqdm(
                    target_map(
                        functools.partial(
                            self._update_and_compute_dressed_esys,
                            self._hilbertspace,
                            self._evals_count,
                            self._update_hilbertspace,
                        ),
                        itertools.product(*self._parameters.ranges),
                    ),
                    total=total_count,
                    desc="Dressed spectrum",
                    leave=False,
                    disable=multi_cpu,
                ))

        spectrum_data = np.asarray(spectrum_data, dtype=object)
        spectrum_data = spectrum_data.reshape((*self._parameters.counts, 2))
        slotparamvals_by_name = OrderedDict(
            self._parameters.ordered_dict.copy())

        evals = np.asarray(spectrum_data[..., 0].tolist())
        evecs = spectrum_data[..., 1]

        return NamedSlotsNdarray(evals,
                                 slotparamvals_by_name), NamedSlotsNdarray(
                                     evecs, slotparamvals_by_name)
Esempio n. 5
0
    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)
Esempio n. 6
0
    def get_spectrum_vs_paramvals(
        self,
        param_name: str,
        param_vals: ndarray,
        evals_count: int = 6,
        subtract_ground: bool = False,
        get_eigenstates: bool = False,
        filename: str = None,
        num_cpus: int = settings.NUM_CPUS,
    ) -> SpectrumData:
        """Calculates eigenvalues/eigenstates 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:
            name of parameter to be varied
        param_vals:
            parameter values to be plugged in
        evals_count:
            number of desired eigenvalues (sorted from smallest to largest)
            (default value = 6)
        subtract_ground:
            if True, eigenvalues are returned relative to the ground state eigenvalue
            (default value = False)
        get_eigenstates:
            return eigenstates along with eigenvalues (default value = False)
        filename:
            file name if direct output to disk is wanted
        num_cpus:
            number of cores to be used for computation
            (default value: settings.NUM_CPUS)
        """
        previous_paramval = getattr(self, param_name)
        tqdm_disable = num_cpus > 1 or settings.PROGRESSBAR_DISABLED

        target_map = get_map_method(num_cpus)
        if not get_eigenstates:
            func = functools.partial(self._evals_for_paramval,
                                     param_name=param_name,
                                     evals_count=evals_count)
            with 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=tqdm_disable,
                        ),
                    ))
            eigenvalue_table = np.asarray(eigenvalue_table)
            eigenstate_table = None
        else:
            func = functools.partial(self._esys_for_paramval,
                                     param_name=param_name,
                                     evals_count=evals_count)
            with InfoBar(
                    "Parallel computation of eigenvalues [num_cpus={}]".format(
                        num_cpus),
                    num_cpus,
            ):
                # Note that it is useful here that the outermost eigenstate object is
                # a list, as for certain applications the necessary hilbert space
                # dimension can vary with paramvals
                eigensystem_mapdata = list(
                    target_map(
                        func,
                        tqdm(
                            param_vals,
                            desc="Spectral data",
                            leave=False,
                            disable=tqdm_disable,
                        ),
                    ))
            eigenvalue_table, eigenstate_table = recast_esys_mapdata(
                eigensystem_mapdata)

        if subtract_ground:
            for param_index, _ in enumerate(param_vals):
                eigenvalue_table[param_index] -= eigenvalue_table[param_index][
                    0]

        setattr(self, param_name, previous_paramval)
        specdata = SpectrumData(
            eigenvalue_table,
            self.get_initdata(),
            param_name,
            param_vals,
            state_table=eigenstate_table,
        )
        if filename:
            specdata.filewrite(filename)

        return SpectrumData(
            eigenvalue_table,
            self.get_initdata(),
            param_name,
            param_vals,
            state_table=eigenstate_table,
        )