Ejemplo n.º 1
0
    def auto_correlations(self):

        times = zeus.AutoCorrTime(samples=self.zeus_sampler.get_chain())
        try:
            previous_auto_correlation_times = zeus.AutoCorrTime(
                samples=self.zeus_sampler.get_chain()
                [:-self.auto_correlation_settings.check_size, :, :], )
        except IndexError:
            previous_auto_correlation_times = None

        return AutoCorrelations(
            check_size=self.auto_correlation_settings.check_size,
            required_length=self.auto_correlation_settings.required_length,
            change_threshold=self.auto_correlation_settings.change_threshold,
            times=times,
            previous_times=previous_auto_correlation_times,
        )
Ejemplo n.º 2
0
    def auto_correlations(self):

        times = zeus.AutoCorrTime(samples=self.results_internal.get_chain())
        try:
            previous_auto_correlation_times = zeus.AutoCorrTime(
                samples=self.results_internal.get_chain()
                [:-self.auto_correlation_settings.check_size, :, :], )
        except IndexError:
            logger.debug("Unable to compute previous auto correlation times.")
            previous_auto_correlation_times = None

        return AutoCorrelations(
            check_size=self.auto_correlation_settings.check_size,
            required_length=self.auto_correlation_settings.required_length,
            change_threshold=self.auto_correlation_settings.change_threshold,
            times=times,
            previous_times=previous_auto_correlation_times,
        )
Ejemplo n.º 3
0
    def fit(self, log_posterior, start, num_dim, prior_transform, save_dims=None, uid=None):

        import zeus

        filename = self.get_filename(uid)
        if os.path.exists(filename):
            self.logger.info("Not sampling, returning result from file.")
            return self.load_file(filename)

        if self.num_walkers is None:
            self.num_walkers = num_dim * 4

        self.logger.debug("Fitting framework with %d dimensions" % num_dim)

        if save_dims is None:
            save_dims = num_dim
        self.logger.debug("Fitting framework with %d dimensions" % num_dim)
        self.logger.info("Using Zeus Sampler")

        callbacks = []
        if self.autoconverge:
            # Default convergence criteria from Zeus docos. Seem reasonable.
            cb0 = zeus.callbacks.AutocorrelationCallback(ncheck=50, dact=0.01, nact=50, discard=0.5)
            cb1 = zeus.callbacks.SplitRCallback(ncheck=50, epsilon=0.01, nsplits=2, discard=0.5)
            cb2 = zeus.callbacks.MinIterCallback(nmin=50)
            callbacks = [cb0, cb1, cb2]

        pos = start(num_walkers=self.num_walkers)
        self.logger.info("Sampling posterior now")

        sampler = zeus.EnsembleSampler(self.num_walkers, num_dim, log_posterior)
        sampler.run_mcmc(pos, self.num_steps, callbacks=callbacks)

        self.logger.debug("Fit finished")

        tau = zeus.AutoCorrTime(sampler.get_chain(discard=0.5))
        burnin = int(2 * np.max(tau))
        samples = sampler.get_chain(discard=burnin, flat=True).T
        likelihood = sampler.get_log_prob(discard=burnin, flat=True)
        self._save(samples, likelihood, filename, save_dims)
        return {"chain": samples, "weights": np.ones(len(likelihood)), "posterior": likelihood}
Ejemplo n.º 4
0
    def _fit(self,
             model: AbstractPriorModel,
             analysis,
             log_likelihood_cap=None):
        """
        Fit a model using Zeus and the Analysis class which contains the data and returns the log likelihood from
        instances of the model, which the `NonLinearSearch` seeks to maximize.

        Parameters
        ----------
        model : ModelMapper
            The model which generates instances for different points in parameter space.
        analysis : Analysis
            Contains the data and the log likelihood function which fits an instance of the model to the data, returning
            the log likelihood the `NonLinearSearch` maximizes.

        Returns
        -------
        A result object comprising the Samples object that inclues the maximum log likelihood instance and full
        chains used by the fit.
        """

        pool = self.make_pool()

        fitness_function = self.fitness_function_from_model_and_analysis(
            model=model, analysis=analysis)

        if self.paths.is_object("zeus"):

            zeus_sampler = self.zeus_pickled

            zeus_state = zeus_sampler.get_last_sample()
            initial_log_posterior_list = zeus_sampler.get_last_log_prob()

            samples = self.samples_from(model=model)

            total_iterations = zeus_sampler.iteration

            if samples.converged:
                iterations_remaining = 0
            else:
                iterations_remaining = self.config_dict_run[
                    "nsteps"] - total_iterations

                logger.info(
                    "Existing Zeus samples found, resuming non-linear search.")

        else:

            zeus_sampler = zeus.EnsembleSampler(
                nwalkers=self.config_dict_search["nwalkers"],
                ndim=model.prior_count,
                logprob_fn=fitness_function.__call__,
                pool=pool,
            )

            zeus_sampler.ncall_total = 0

            initial_unit_parameter_lists, initial_parameter_lists, initial_log_posterior_list = self.initializer.initial_samples_from_model(
                total_points=zeus_sampler.nwalkers,
                model=model,
                fitness_function=fitness_function,
            )

            zeus_state = np.zeros(shape=(zeus_sampler.nwalkers,
                                         model.prior_count))

            logger.info(
                "No Zeus samples found, beginning new non-linear search.")

            for index, parameters in enumerate(initial_parameter_lists):

                zeus_state[index, :] = np.asarray(parameters)

            total_iterations = 0
            iterations_remaining = self.config_dict_run["nsteps"]

        while iterations_remaining > 0:

            if self.iterations_per_update > iterations_remaining:
                iterations = iterations_remaining
            else:
                iterations = self.iterations_per_update

            for sample in zeus_sampler.sample(
                    start=zeus_state,
                    log_prob0=initial_log_posterior_list,
                    iterations=iterations,
                    progress=True,
            ):

                pass

            zeus_sampler.ncall_total += zeus_sampler.ncall

            self.paths.save_object("zeus", zeus_sampler)

            zeus_state = zeus_sampler.get_last_sample()
            initial_log_posterior_list = zeus_sampler.get_last_log_prob()

            total_iterations += iterations
            iterations_remaining = self.config_dict_run[
                "nsteps"] - total_iterations

            samples = self.perform_update(model=model,
                                          analysis=analysis,
                                          during_analysis=True)

            if self.auto_correlations_settings.check_for_convergence:
                if zeus_sampler.iteration > self.auto_correlations_settings.check_size:
                    if samples.converged:
                        iterations_remaining = 0

            auto_correlation_time = zeus.AutoCorrTime(
                samples=zeus_sampler.get_chain())

            discard = int(3.0 * np.max(auto_correlation_time))
            thin = int(np.max(auto_correlation_time) / 2.0)
            chain = zeus_sampler.get_chain(discard=discard,
                                           thin=thin,
                                           flat=True)

            if "maxcall" in self.kwargs:
                if zeus_sampler.ncall_total > self.kwargs["maxcall"]:
                    iterations_remaining = 0

        logger.info("Zeus sampling complete.")