示例#1
0
def test_std(logp=logp,seed=42):
    np.random.seed(seed)
    ndim = np.random.randint(2,5)
    nwalkers = 2 * ndim
    nsteps = np.random.randint(3000,5000)
    sampler = zeus.EnsembleSampler(nwalkers,ndim,logp,verbose=False)
    start = np.random.rand(nwalkers,ndim)
    sampler.run_mcmc(start,nsteps)
    assert np.all(np.abs(np.std(sampler.get_chain(flat=True),axis=0)-1.0) < 0.1)
示例#2
0
    def __init__(
        self,
        fit,
        nwalkers=50,
        processes=1,
        initspread=0.01,
        moves=None,
        verbose=True,
        sampler='emcee',
    ):

        self.fit = fit
        self.nwalkers = nwalkers
        self.numpars = fit.pars.numFree()
        self.initspread = initspread
        self.verbose = verbose
        self.sampler_mode = sampler

        mcmcpars = fit.pars.copy()

        def likefunc(parvals):
            mcmcpars.setFree(parvals)
            like = Likelihood(fit.images, fit.model, mcmcpars)
            return like.total

        pool = None if processes <= 1 else _MultiProcessPool(
            likefunc, processes)

        # for doing the mcmc sampling
        if sampler == 'emcee':
            if emcee is None:
                raise RuntimeError('emcee module not installed')
            self.sampler = emcee.EnsembleSampler(nwalkers,
                                                 self.numpars,
                                                 likefunc,
                                                 pool=pool,
                                                 moves=moves)
        elif sampler == 'zeus':
            if zeus is None:
                raise RuntimeError('zeus module not installed')
            self.sampler = zeus.EnsembleSampler(
                nwalkers,
                self.numpars,
                likefunc,
                pool=pool,
            )
        else:
            raise RuntimeError('Unknown sampler')

        # starting point
        self.pos0 = None

        # header items to write to output file
        self.header = {
            'burn': 0,
        }
示例#3
0
    def __init__(self, name, nwalkers, ndim, logprob, pool):
        self.name = name
        self.nwalkers = nwalkers
        self.ndim = ndim

        if name == 'zeus':
            import zeus
            self.sampler = zeus.EnsembleSampler(nwalkers,
                                                ndim,
                                                logprob,
                                                pool=pool,
                                                verbose=False)
        elif name == 'light':
            import zeus
            self.sampler = zeus.EnsembleSampler(nwalkers,
                                                ndim,
                                                logprob,
                                                pool=pool,
                                                verbose=False,
                                                light_mode=True)
        elif name == 'emcee':
            import emcee
            #self.state = emcee.State
            self.sampler = emcee.EnsembleSampler(nwalkers,
                                                 ndim,
                                                 logprob,
                                                 pool=pool)
        elif name == 'demc':
            import emcee
            self.sampler = emcee.EnsembleSampler(
                nwalkers,
                ndim,
                logprob,
                moves=[(emcee.moves.DEMove(), 0.9),
                       (emcee.moves.DESnookerMove(), 0.1)],
                pool=pool)
示例#4
0
def test_ncall(seed=42):
    np.random.seed(seed)
    def loglike(theta):
        assert len(theta) == 5
        a = theta[:-1]
        b = theta[1:]
        loglike.ncalls += 1
        return -2 * (100 * (b - a**2)**2 + (1 - a)**2).sum()
    loglike.ncalls = 0

    ndim = 5
    nsteps = 100
    nwalkers = 2 * ndim
    sampler = zeus.EnsembleSampler(nwalkers,ndim,loglike,verbose=False)
    start = np.random.rand(nwalkers,ndim)
    sampler.run_mcmc(start,nsteps)
    
    assert loglike.ncalls == sampler.ncall + nwalkers
示例#5
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}
示例#6
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.")

lg = Posterior(modelw)

for fNL in [-999, -500, -100, -10, 0, 10, 100, 500, 999]:
    print(fNL, lg.logpost(fNL, y, invcov, x))

np.random.seed(42)

ndim = 1  # Number of parameters/dimensions (e.g. m and c)
nwalkers = 10  # Number of walkers to use. It should be at least twice the number of dimensions.
nsteps = 1000  # Number of steps/iterations.

start = 10. * np.random.randn(nwalkers,
                              ndim)  # Initial positions of the walkers.
print(f'initial guess: {start}')

sampler = zeus.EnsembleSampler(nwalkers,
                               ndim,
                               lg.logpost,
                               args=[y, invcov, x],
                               maxiter=10000)
sampler.run_mcmc(start, nsteps)  # Run sampling
sampler.summary  # Print summary diagnostics

# flatten the chains, thin them by a factor of 15,
# and remove the burn-in (first half of the chain)
chain = sampler.get_chain(flat=True, discard=20, thin=5)

np.save(f'chains_{kind}_{case}.npy', chain)  #
示例#8
0
def multiprocessing_zeus():
    '''
    '''
    #
    fsps_emulator = Models.DESIspeculator()

    # set prior 
    priors = Infer.load_priors([
        Infer.UniformPrior(10., 10.5, label='sed'),
        Infer.FlatDirichletPrior(4, label='sed'), 
        Infer.UniformPrior(np.array([6.9e-5, 6.9e-5, 0., 0., -2.2]), np.array([7.3e-3, 7.3e-3, 3., 4., 0.4]), label='sed')
    ])
    random_theta = priors.sample() 
    wave, flux = fsps_emulator.sed(priors.transform(random_theta), 0.1)
    

    desi_mcmc = Infer.desiMCMC(prior=priors)
    t0 = time.time()
    mcmc = desi_mcmc.run(
            wave_obs=wave[0],
            flux_obs=flux[0],
            flux_ivar_obs=np.ones(flux.shape[1]),
            zred=0.1,
            sampler='zeus',
            nwalkers=20,
            burnin=10,
            opt_maxiter=1000,
            niter=100,
            pool=None, 
            debug=True)
    print()
    print('running on series takes %.f' % (time.time() - t0))
    print()

    
    import zeus 
    import multiprocessing 
    ncpu = multiprocessing.cpu_count() 
    print('%i cpus' % ncpu)

    t0 = time.time()
    lnpost_args, lnpost_kwargs = desi_mcmc._lnPost_args_kwargs(
            wave_obs=wave[0],
            flux_obs=flux[0],
            flux_ivar_obs=np.ones(flux.shape[1]),
            zred=0.1)
    start = desi_mcmc._initialize_walkers(lnpost_args, lnpost_kwargs, priors,
            nwalkers=20, opt_maxiter=1000, debug=True)

    print('--- burn-in ---') 
    pewl = Pool(processes=ncpu)
    with pewl as pool: 
        zeus_sampler = zeus.EnsembleSampler(
                desi_mcmc.nwalkers,
                desi_mcmc.prior.ndim, 
                desi_mcmc.lnPost, 
                pool=pool,
                args=lnpost_args, 
                kwargs=lnpost_kwargs)
        zeus_sampler.run_mcmc(start, 10)
    burnin = zeus_sampler.get_chain()

    print('--- running main MCMC ---') 
    pewl = Pool(processes=ncpu)
    with pewl as pool: 
        zeus_sampler = zeus.EnsembleSampler(
                desi_mcmc.nwalkers,
                desi_mcmc.prior.ndim, 
                desi_mcmc.lnPost, 
                pool=pool, 
                args=lnpost_args, 
                kwargs=lnpost_kwargs)
        zeus_sampler.run_mcmc(burnin[-1], 100)
    _chain = zeus_sampler.get_chain()
    print()
    print('running on parallel takes %.f' % (time.time() - t0))
    print()
    return None 
示例#9
0
    def fit(self,
            data,
            s,
            nsteps=100,
            outbase="output/test_",
            seed=42,
            resume=True):

        self.nsteps = nsteps

        if self.backend == 'zeus':
            param_init = []
            for i in range(self.nparams):
                if self.prior_types[i] == 'flat':
                    min, max = self.prior_params[i]
                    param_init.append((max - min) *
                                      np.random.random(self.nwalkers) + min)
                elif self.prior_types[i] == 'gauss':
                    mu, sigma = self.prior_params[i]
                    param_init.append(
                        np.random.normal(loc=mu,
                                         scale=sigma,
                                         size=self.nwalkers))
                else:
                    raise NotImplementedError

            start = np.array(param_init).T
            if not os.path.isfile(outbase + "zeus_chains.txt") or ~resume:
                np.random.seed(seed)
                with Pool() as pool:
                    sampler = zeus.EnsembleSampler(
                        self.nwalkers,
                        self.nparams,
                        self.logpost,
                        args=[data, s],
                        vectorize=False)  # Initialise the sampler
                    sampler.run_mcmc(start, nsteps)  # Run sampling
                sampler.summary  # Print summary diagnostics
                return sampler
            else:
                print(f"==> Chain file found, skipping the fit.")

        elif self.backend == 'multinest':

            print(
                f"==> Using PyMultinest. Assuming params passed are flat priors."
            )

            def prior_pmn(cube, ndim, nparams):
                for i in range(self.nparams):
                    min, max = self.prior_params[i]
                    cube[i] = cube[i] * (max - min) + min

            def loglike_pmn(cube, ndim, nparams):
                alpha, B, Snl = cube[0], cube[1], cube[2]
                return self.loglike((alpha, B, Snl), data, s)



            pmn.run(loglike_pmn, prior_pmn, self.nparams, outputfiles_basename=outbase, resume=resume, \
                verbose=True, n_live_points=self.live_points, evidence_tolerance=self.tolerance)

        else:
            raise NotImplementedError
示例#10
0
cmax = 10.  # upper range of prior

cini = np.random.uniform(cmin, cmax, Nens)  # initial c points

inisamples = np.array([mini, cini]).T  # initial samples

ndims = inisamples.shape[1]  # number of parameters/dimensions

Nburnin = 500  # number of burn-in samples
Nsamples = 500  # number of final posterior samples

# set additional args for the posterior (the data, the noise std. dev., and the abscissa)
argslist = (data, sigma, x)

# set up the sampler
sampler = zeus.EnsembleSampler(Nens, ndims, logposterior, args=argslist)

# pass the initial samples and total number of samples required
sampler.run_mcmc(inisamples, Nsamples + Nburnin)

# extract the samples (removing the burn-in)
postsamples = sampler.get_chain(flat=True, discrd=Nburnin)

# plot posterior samples (if corner.py is installed)
try:
    import matplotlib as mpl
    mpl.use("Agg")  # force Matplotlib backend to Agg
    import corner  # import corner.py
except ImportError:
    sys.exit(1)
示例#11
0
    '''The natural logarithm of the likelihood.'''
    # unpack the model parameters
    fnl = theta
    # evaluate the model
    md = model(x, fnl=fnl, has_fnl=True, has_rsd=True)
    # return the log likelihood
    return -0.5 * (y - md).dot(invcov.dot(y - md))


def logpost(theta, y, invcov, x):
    '''The natural logarithm of the posterior.'''
    return logprior(theta) + loglike(theta, y, invcov, x)


ndim = 1  # Number of parameters/dimensions (e.g. m and c)
nwalkers = 10  # Number of walkers to use. It should be at least twice the number of dimensions.
nsteps = 1000  # Number of steps/iterations.
start = 0.01 * np.random.randn(nwalkers,
                               ndim)  # Initial positions of the walkers.
print(f'initial guess: {start}')

sampler = zeus.EnsembleSampler(nwalkers, ndim, logpost,
                               args=[y, invcov, x])  # Initialise the sampler
sampler.run_mcmc(start, nsteps)  # Run sampling
#sampler.summary # Print summary diagnostics

# flatten the chains, thin them by a factor of 10, and remove the burn-in (first half of the chain)
chain = sampler.get_chain(flat=True, discard=100, thin=10)

np.save('chains.npy', chain)
示例#12
0
    def mcmc_zeus(self,
                  n_walkers,
                  n_run,
                  n_burn,
                  mean_start,
                  sigma_start,
                  mpi=False,
                  threadCount=1,
                  progress=False,
                  initpos=None,
                  backend_filename=None,
                  moves=None,
                  tune=True,
                  tolerance=0.05,
                  patience=5,
                  maxsteps=10000,
                  mu=1.0,
                  maxiter=10000,
                  pool=None,
                  vectorize=False,
                  blobs_dtype=None,
                  verbose=True,
                  check_walkers=True,
                  shuffle_ensemble=True,
                  light_mode=False):
        """
        Lightning fast MCMC with zeus: https://github.com/minaskar/zeus

        For the full list of arguments for the EnsembleSampler, see see `the zeus docs <https://zeus-mcmc.readthedocs.io/en/latest/api/sampler.html>`_.

        If you use the zeus sampler, you should cite the following papers: 2105.03468, 2002.06212.

        :param n_walkers: number of walkers per parameter
        :type n_walkers: integer
        :param n_run: number of sampling steps
        :type n_run: integer
        :param n_burn: number of burn-in steps
        :type n_burn: integer
        :param mean_start: mean of the parameter position of the initialising sample
        :type mean_start: numpy array of length the number of parameters
        :param sigma_start: spread of the parameter values (uncorrelated in each dimension) of the initialising sample
        :type sigma_start: numpy array of length the number of parameters
        :param progress:
        :type progress: bool
        :param initpos: initial walker position to start sampling (optional)
        :type initpos: numpy array of size num param x num walkser
        :param backup_filename: name of the HDF5 file where sampling state is saved (through zeus callback function)
        :type backup_filename: string
        :return: samples, ln likelihood value of samples
        :rtype: numpy 2d array, numpy 1d array
        """
        import zeus

        print('Using zeus to perform the MCMC.')

        num_param, _ = self.chain.param.num_param()

        if initpos is None:
            initpos = sampling_util.sample_ball_truncated(mean_start,
                                                          sigma_start,
                                                          self.lower_limit,
                                                          self.upper_limit,
                                                          size=n_walkers)

        if backend_filename is not None:
            backend = zeus.callbacks.SaveProgressCallback(
                filename=backend_filename, ncheck=1)
            n_run_eff = n_burn + n_run
        else:
            backend = None
            n_run_eff = n_burn + n_run

        pool = choose_pool(mpi=mpi, processes=threadCount, use_dill=True)

        sampler = zeus.EnsembleSampler(nwalkers=n_walkers,
                                       ndim=num_param,
                                       logprob_fn=self.chain.logL,
                                       moves=moves,
                                       tune=tune,
                                       tolerance=tolerance,
                                       patience=patience,
                                       maxsteps=maxsteps,
                                       mu=mu,
                                       maxiter=maxiter,
                                       pool=pool,
                                       vectorize=vectorize,
                                       blobs_dtype=blobs_dtype,
                                       verbose=verbose,
                                       check_walkers=check_walkers,
                                       shuffle_ensemble=shuffle_ensemble,
                                       light_mode=light_mode)

        sampler.run_mcmc(initpos,
                         n_run_eff,
                         progress=progress,
                         callbacks=backend)

        flat_samples = sampler.get_chain(flat=True, thin=1, discard=n_burn)

        dist = sampler.get_log_prob(flat=True, thin=1, discard=n_burn)

        return flat_samples, dist