Beispiel #1
0
def build_evolution_pCN_sampler(observation_operator, u, data, noise, prior,
                                posterior, rng):
    potential = EvolutionPotential(observation_operator, data, noise)

    proposer = pCNProposer(beta=0.25, prior=prior)
    accepter = CountedAccepter(pCNAccepter(potential=potential))
    return MCMCSampler(proposer, accepter, rng)
Beispiel #2
0
def create_pCNSampler(density):
    mean = np.array([0])
    covariance = np.array([1], ndmin=2)
    prior = GaussianDistribution(mean, covariance)

    potential = AnalyticPotential(posterior=density, prior=prior)

    # beta != delta of other proposers, but
    # it could easily be translated if someone took the 30s to do it
    proposer = pCNProposer(beta=0.25, prior=prior)
    accepter = pCNAccepter(potential=potential)
    return MCMCSampler(proposer, accepter, np.random.default_rng(1))
Beispiel #3
0
def create_StandardRWSampler(density):
    mean = np.array([0])
    covariance = np.array([1], ndmin=2)
    sqrt_covariance = np.array([1], ndmin=2)
    prior = GaussianDistribution(mean, covariance)
    potential = AnalyticPotential(posterior=density, prior=prior)

    proposer = StandardRWProposer(delta=0.25,
                                  dims=1,
                                  sqrt_covariance=sqrt_covariance)
    accepter = StandardRWAccepter(potential=potential, prior=prior)
    return MCMCSampler(proposer, accepter, np.random.default_rng(1))
Beispiel #4
0
def autocorrelation(samples, tau_max):
    avg_over = int(len(samples[0, :]) / tau_max)
    assert avg_over > 0, ("Not enough samples to compute autocorrelation"
                          "with specified length")

    n_vars = len(samples[:, 0])
    ac = np.zeros((n_vars, tau_max))
    for i in range(avg_over):
        for var in range(n_vars):
            vals = samples[var, i * tau_max:(i + 1) * tau_max]
            ac[var, :] += MCMCSampler.autocorr(vals)
    ac /= avg_over

    return ac
Beispiel #5
0
def create_mcmc_sampler():
    rng = np.random.default_rng(2)

    # Proposer
    prior = Settings.Prior.get_distribution()
    proposer = pCNProposer(Settings.Sampling.beta, prior)

    # Accepter
    integrator = create_integrator()
    measurer = create_measurer()
    IC_true = PerturbedRiemannIC(Settings.Simulation.IC.ground_truth)
    observation_operator = FVMObservationOperator(PerturbedRiemannIC,
                                                  Settings.Prior.mean,
                                                  integrator, measurer)

    ground_truth = measurer(integrator(IC_true))
    noise = Settings.Noise.get_distribution()
    potential = EvolutionPotential(observation_operator, ground_truth, noise)
    accepter = CountedAccepter(pCNAccepter(potential))

    return MCMCSampler(proposer, accepter, rng)
Beispiel #6
0
def create_mcmc_sampler():
    # Proposer
    prior = Settings.Prior.get_distribution()
    # proposer = ConstSteppCNProposer(Settings.Sampling.step, prior)
    # proposer = ConstStepStandardRWProposer(Settings.Sampling.step, prior)
    proposer = VarStepStandardRWProposer(Settings.Sampling.step, prior)

    # Accepter
    integrator = create_integrator()
    measurer = create_measurer()
    IC_true = PerturbedRiemannIC(Settings.Simulation.IC.ground_truth)
    observation_operator = FVMObservationOperator(PerturbedRiemannIC,
                                                  Settings.Prior.mean,
                                                  integrator, measurer)

    ground_truth = measurer(integrator(IC_true))
    noise = Settings.Noise.get_distribution()
    potential = EvolutionPotential(observation_operator, ground_truth, noise)
    # accepter = CountedAccepter(pCNAccepter(potential))
    accepter = CountedAccepter(StandardRWAccepter(potential, prior))

    return MCMCSampler(proposer, accepter, Settings.Sampling.rng)
Beispiel #7
0
def create_AnalyticSampler(density):
    proposer = StandardRWProposer(0.25, 1)
    accepter = AnalyticAccepter(density)
    return MCMCSampler(proposer, accepter, np.random.default_rng(1))
Beispiel #8
0
def main():
    rng = np.random.default_rng(1)
    data_dir = "/home/david/fs20/thesis/code/report/data/"

    # Parameters of simulation
    K, J = 6, 4
    sim_length = 20

    # True Theta
    theta = np.array([10, 10, 1, 10])  # F, h, c, b
    r = 0.5  # noise level

    # Characteristics of system
    T = 500
    try:
        Y = np.load(data_dir + f"Y_{K=}_{J=}_{T=}.npy")
        print("Loaded existing simulation results")
    except FileNotFoundError:
        print("Running simulation to generate fake measurements")
        Y = run_lorenz96(K, J, theta, T)
        np.save(data_dir + f"Y_{K=}_{J=}_{T=}", Y)

    print(f"{Y.shape=}")

    moment_function_values = moment_function(Y, K, J)
    moment_function_means = np.mean(moment_function_values, axis=1)
    moment_function_variances = np.var(moment_function_values, axis=1)
    print(f"{moment_function_variances.shape=}")

    noise = GaussianDistribution(mean=np.zeros_like(moment_function_variances),
                                 covariance=r**2 *
                                 np.diag(moment_function_variances))

    prior_means = np.array([12, 8, 9])  # F, h, b
    prior_covariance = np.diag([10, 1, 10])

    # From theory: prior is always assumed to be centered,
    # so I do MCMC over pertubations from given prior means
    prior = GaussianDistribution(np.zeros_like(prior_means), prior_covariance)

    observation_operator = LorenzObservationOperator(K, J, sim_length,
                                                     theta[2], prior_means,
                                                     Y[:, -1])

    # don't need huge array anymore
    del Y

    potential = EvolutionPotential(observation_operator, moment_function_means,
                                   noise)

    proposer = pCNProposer(beta=0.5, prior=prior)
    accepter = CountedAccepter(pCNAccepter(potential=potential))

    sampler = MCMCSampler(proposer, accepter, rng)

    u_0 = np.array([-1.9, 1.9, 0.9])  # start close to true theta
    n_samples = 2000
    try:
        samples = np.load(data_dir +
                          f"S_{K=}_{J=}_T={sim_length}_{r=}_{n_samples=}.npy")
        print("Loaded existing sampling results")
    except FileNotFoundError:
        print("Generating samples")
        samples = sampler.run(u_0=u_0,
                              n_samples=n_samples,
                              burn_in=100,
                              sample_interval=1)
        np.save(data_dir + f"S_{K=}_{J=}_T={sim_length}_{r=}_{n_samples=}",
                samples)

    print(f"{samples.shape=}")

    # to conform with the output-shape of
    # solve_ivp. Might be worthwile to change it in the sampler,
    # but then I break older scripts
    samples = samples.T

    # Add pertubations to means
    for i in range(len(samples[0, :])):
        samples[:, i] += prior_means

    # Plot densities
    priors = [
        GaussianDistribution(mu, np.sqrt(sigma_sq))
        for mu, sigma_sq in zip(prior_means, np.diag(prior_covariance))
    ]
    intervals = [(-5, 25)] * 3
    names = ["F", "h", "b"]

    fig, plts = plt.subplots(1, 3, figsize=(20, 10))

    plot_info = zip(priors, intervals, [theta[0], theta[1], theta[3]], names,
                    plts)

    for i, (prior, interval, true_val, name, ax) in enumerate(plot_info):
        ax.hist(samples[i, :], density=True)
        x_range = np.linspace(*interval)
        ax.plot(x_range, [prior(x) for x in x_range])
        ax.axvline(true_val, c='r')
        ax.set_title(f"Prior and posterior for {name}")
        ax.set(xlabel=name, ylabel="Probability")

    fig.suptitle("Posteriors and priors")
    store_figure(f"combined_{K=}_{J=}_T={sim_length}_{r=}")

    # Average the autocorrelation
    ac = np.zeros((3, 100))
    n = 10
    for i in range(1, 1 + n):
        for var in range(3):
            ac[var, :] += MCMCSampler.autocorr(samples[var,
                                                       i * 100:(i + 1) * 100])
    ac /= n
    plt.plot(ac[0, :], label="F")
    plt.plot(ac[1, :], label="h")
    plt.plot(ac[2, :], label="b")
    plt.title("Autocorrelation")
    plt.xlabel("Lag")
    plt.legend()
    store_figure(f"lorenz_ac_avg_{K=}_{J=}_T={sim_length}_{r=}")