예제 #1
0
 def check_gaussian(sampler_instance):
     KL_proposer = KL_norm(S1=sampler_instance.model.likelihood["gaussian_mixture"].covs[0],
                           S2=sampler_instance.proposer.get_covariance())
     KL_sample = KL_norm(m1=sampler_instance.model.likelihood["gaussian_mixture"].means[0],
                         S1=sampler_instance.model.likelihood["gaussian_mixture"].covs[0],
                         m2=sampler_instance.collection.mean(
                             first=int(sampler_instance.n() / 2)),
                         S2=sampler_instance.collection.cov(
                             first=int(sampler_instance.n() / 2)))
     print("KL proposer: %g ; KL sample: %g" % (KL_proposer, KL_sample))
def test_example():
    # temporarily change working directory to be able to run the files "as is"
    cwd = os.getcwd()
    try:
        os.chdir(docs_src_folder)
        info_yaml = yaml_load_file("gaussian.yaml")
        info_yaml.pop("output")
        globals_example = {}
        exec(
            open(os.path.join(docs_src_folder, "create_info.py")).read(),
            globals_example)
        assert is_equal_info(info_yaml, globals_example["info"]), (
            "Inconsistent info between yaml and interactive.")
        exec(
            open(os.path.join(docs_src_folder, "load_info.py")).read(),
            globals_example)
        globals_example["info_from_yaml"].pop("output")
        assert is_equal_info(info_yaml, globals_example["info_from_yaml"]), (
            "Inconsistent info between interactive and *loaded* yaml.")
        # Run the chain -- constant seed so results are the same!
        globals_example["info"]["sampler"]["mcmc"] = (
            globals_example["info"]["sampler"]["mcmc"] or {})
        exec(
            open(os.path.join(docs_src_folder, "run.py")).read(),
            globals_example)
        # Run the minimizer -- output doesn't matter. Just checking that it does not fail
        exec(
            open(os.path.join(docs_src_folder, "run_min.py")).read(),
            globals_example)
        # Analyze and plot -- capture print output
        stream = StringIO()
        with stdout_redirector(stream):
            exec(
                open(os.path.join(docs_src_folder, "analyze.py")).read(),
                globals_example)
        # Checking results
        mean, covmat = [
            globals_example["info"]["likelihood"]["gaussian_mixture"][x]
            for x in ["means", "covs"]
        ]
        assert (KL_norm(m1=mean,
                        S1=covmat,
                        m2=globals_example["mean"],
                        S2=globals_example["covmat"]) <= KL_tolerance
                ), ("Sampling appears not to have worked too well. Run again?")
    finally:
        # Back to the working directory of the tests, just in case
        os.chdir(cwd)
예제 #3
0
def test_post_prior(tmpdir):
    # Generate original chain
    info = {
        _output_prefix: os.path.join(str(tmpdir), "gaussian"),
        _force: True,
        _params: info_params,
        kinds.sampler: info_sampler,
        kinds.likelihood: {
            "one": None
        },
        _prior: {
            "gaussian": sampled_pdf
        }
    }
    run(info)
    info_post = {
        _output_prefix: info[_output_prefix],
        _force: True,
        _post: {
            _post_suffix: "foo",
            _post_remove: {
                _prior: {
                    "gaussian": None
                }
            },
            _post_add: {
                _prior: {
                    "target": target_pdf_prior
                }
            }
        }
    }
    post(info_post)
    # Load with GetDist and compare
    mcsamples = loadMCSamples(info_post[_output_prefix] + _post_ +
                              info_post[_post][_post_suffix])
    new_mean = mcsamples.mean(["a", "b"])
    new_cov = mcsamples.getCovMat().matrix
    assert abs(KL_norm(target["mean"], target["cov"], new_mean,
                       new_cov)) < 0.02
예제 #4
0
def test_post_prior(tmpdir):
    # Generate original chain
    info = {
        "output": os.path.join(str(tmpdir), "gaussian"),
        "force": True,
        "params": info_params,
        "sampler": info_sampler,
        "likelihood": {
            "one": None
        },
        "prior": {
            "gaussian": sampled_pdf
        }
    }
    run(info)
    info_post = {
        "output": info["output"],
        "force": True,
        "post": {
            "suffix": "foo",
            "remove": {
                "prior": {
                    "gaussian": None
                }
            },
            "add": {
                "prior": {
                    "target": target_pdf
                }
            }
        }
    }
    post(info_post)
    # Load with GetDist and compare
    mcsamples = loadMCSamples(info_post["output"] + "_post_" +
                              info_post["post"]["suffix"])
    new_mean = mcsamples.mean(["a", "b"])
    new_cov = mcsamples.getCovMat().matrix
    assert abs(KL_norm(target["mean"], target["cov"], new_mean,
                       new_cov)) < 0.02
예제 #5
0
def body_of_test(dimension=1,
                 n_modes=1,
                 info_sampler={},
                 tmpdir="",
                 modules=None):
    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()
    # Info of likelihood and prior
    ranges = np.array([[-1, 1] for _ in range(dimension)])
    while True:
        info = info_random_gaussian_mixture(ranges=ranges,
                                            n_modes=n_modes,
                                            prefix="a_",
                                            O_std_min=O_std_min,
                                            O_std_max=O_std_max,
                                            derived=True)
        if n_modes == 1:
            break
        means = info["likelihood"]["gaussian_mixture"]["means"]
        distances = chain(*[[np.linalg.norm(m1 - m2) for m2 in means[i + 1:]]
                            for i, m1 in enumerate(means)])
        if min(distances) >= distance_factor * O_std_max:
            break
    if rank == 0:
        print("Original mean of the gaussian mode:")
        print(info["likelihood"]["gaussian_mixture"]["means"])
        print("Original covmat of the gaussian mode:")
        print(info["likelihood"]["gaussian_mixture"]["covs"])
    info[_sampler] = info_sampler
    if list(info_sampler.keys())[0] == "mcmc":
        if "covmat" in info_sampler["mcmc"]:
            info[_sampler]["mcmc"]["covmat_params"] = (list(
                info["params"].keys())[:dimension])
    info[_debug] = False
    info[_debug_file] = None
    info[_output_prefix] = getattr(tmpdir, "realpath()", lambda: tmpdir)()
    if modules:
        info[_path_install] = process_modules_path(modules)
    # Delay to one chain to check that MPI communication of the sampler is non-blocking
    #    if rank == 1:
    #        info["likelihood"]["gaussian_mixture"]["delay"] = 0.1
    updated_info, products = run(info)
    # Done! --> Tests
    if rank == 0:
        if list(info_sampler.keys())[0] == "mcmc":
            ignore_rows = 0.5
        else:
            ignore_rows = 0
        results = loadCobayaSamples(updated_info,
                                    products["sample"],
                                    ignore_rows=ignore_rows,
                                    name_tag="sample")
        clusters = None
        if "clusters" in products:
            clusters = [
                loadCobayaSamples(updated_info,
                                  products["clusters"][i]["sample"],
                                  name_tag="cluster %d" % (i + 1))
                for i in products["clusters"]
            ]
        # Plots!
        try:
            import getdist.plots as gdplots
            from getdist.gaussian_mixtures import MixtureND
            mixture = MixtureND(
                info[_likelihood]["gaussian_mixture"]["means"],
                info[_likelihood]["gaussian_mixture"]["covs"],
                names=[p for p in info[_params] if "deriv" not in p],
                label="truth")
            g = gdplots.getSubplotPlotter()
            to_plot = [mixture, results]
            if clusters:
                to_plot = to_plot + clusters
            g.triangle_plot(to_plot, )
            g.export("test.png")
        except:
            print("Plotting failed!")
        # 1st test: KL divergence
        if n_modes == 1:
            cov_sample, mean_sample = results.getCov(), results.getMeans()
            KL_final = KL_norm(
                m1=info[_likelihood]["gaussian_mixture"]["means"][0],
                S1=info[_likelihood]["gaussian_mixture"]["covs"][0],
                m2=mean_sample[:dimension],
                S2=cov_sample[:dimension, :dimension])
            print("Final KL: ", KL_final)
            assert KL_final <= KL_tolerance
        # 2nd test: clusters
        else:
            if "clusters" in products:
                assert len(products["clusters"].keys()) >= n_modes, (
                    "Not all clusters detected!")
                for c2 in clusters:
                    cov_c2, mean_c2 = c2.getCov(), c2.getMeans()
                    KLs = [
                        KL_norm(m1=info[_likelihood]["gaussian_mixture"]
                                ["means"][i_c1],
                                S1=info[_likelihood]["gaussian_mixture"]
                                ["covs"][i_c1],
                                m2=mean_c2[:dimension],
                                S2=cov_c2[:dimension, :dimension])
                        for i_c1 in range(n_modes)
                    ]
                    extra_tol = 4 * n_modes if n_modes > 1 else 1
                    assert min(KLs) <= KL_tolerance * extra_tol
            else:
                assert 0, "Could not check sample convergence: multimodal but no clusters"
        # 3rd test: Evidence
        if "logZ" in products:
            logZprior = sum(np.log(ranges[:, 1] - ranges[:, 0]))
            assert (products["logZ"] - logZ_nsigmas * products["logZstd"] <
                    -logZprior <
                    products["logZ"] + logZ_nsigmas * products["logZstd"])
예제 #6
0
def test_post_likelihood(tmpdir):
    """
    Swaps likelihood "gaussian" for "target".

    It also tests aggregated chi2's by removing and adding a likelihood to an existing
    type.
    """
    # Generate original chain
    info_params_local = deepcopy(info_params)
    info_params_local["dummy"] = 0
    dummy_loglike_add = 0.1
    dummy_loglike_remove = 0.01
    info = {
        _output_prefix: os.path.join(str(tmpdir), "gaussian"),
        _force: True,
        _params: info_params_local,
        kinds.sampler: info_sampler,
        kinds.likelihood: {
            "gaussian": {
                "external": sampled_pdf,
                "type": "A"
            },
            "dummy": {
                "external": lambda dummy: 1,
                "type": "B"
            },
            "dummy_remove": {
                "external": lambda dummy: dummy_loglike_add,
                "type": "B"
            }
        }
    }
    info_run_out, sampler_run = run(info)
    info_post = {
        _output_prefix: info[_output_prefix],
        _force: True,
        _post: {
            _post_suffix: "foo",
            _post_remove: {
                kinds.likelihood: {
                    "gaussian": None,
                    "dummy_remove": None
                }
            },
            _post_add: {
                kinds.likelihood: {
                    "target": {
                        "external": target_pdf,
                        "type": "A",
                        "output_params": ["cprime"]
                    },
                    "dummy_add": {
                        "external": lambda dummy: dummy_loglike_remove,
                        "type": "B"
                    }
                }
            }
        }
    }
    info_post_out, products_post = post(info_post)
    # Load with GetDist and compare
    mcsamples = loadMCSamples(info_post[_output_prefix] + _post_ +
                              info_post[_post][_post_suffix])
    new_mean = mcsamples.mean(["a", "b"])
    new_cov = mcsamples.getCovMat().matrix
    assert abs(KL_norm(target["mean"], target["cov"], new_mean,
                       new_cov)) < 0.02
    assert np.allclose(products_post["sample"]["chi2__A"],
                       products_post["sample"]["chi2__target"])
    assert np.allclose(
        products_post["sample"]["chi2__B"],
        products_post["sample"]["chi2__dummy"] +
        products_post["sample"]["chi2__dummy_add"])
예제 #7
0
def body_of_sampler_test(info_sampler: SamplersDict,
                         dimension=1,
                         n_modes=1,
                         tmpdir="",
                         packages_path=None,
                         skip_not_installed=False,
                         fixed=False,
                         random_state=None):
    # Info of likelihood and prior
    ranges = np.array([[-1, 1] for _ in range(dimension)])
    if fixed:
        info = fixed_info.copy()
    else:
        info = generate_random_info(n_modes, ranges, random_state=random_state)

    if mpi.is_main_process():
        print("Original mean of the gaussian mode:")
        print(info["likelihood"]["gaussian_mixture"]["means"])
        print("Original covmat of the gaussian mode:")
        print(info["likelihood"]["gaussian_mixture"]["covs"])
    info["sampler"] = info_sampler
    sampler_name = list(info_sampler)[0]
    if random_state is not None:
        info_sampler[sampler_name]["seed"] = random_state.integers(0, 2**31)
    if sampler_name == "mcmc":
        if "covmat" in info_sampler["mcmc"]:
            info["sampler"]["mcmc"]["covmat_params"] = (list(
                info["params"])[:dimension])
    info["debug"] = False
    info["debug_file"] = None
    info["output"] = os.path.join(tmpdir, 'out_chain')
    if packages_path:
        info["packages_path"] = process_packages_path(packages_path)

    updated_info, sampler = install_test_wrapper(skip_not_installed, run, info)
    products = sampler.products()
    products["sample"] = mpi.gather(products["sample"])
    # Done! --> Tests
    if mpi.is_main_process():
        if sampler_name == "mcmc":
            ignore_rows = 0.5
        else:
            ignore_rows = 0
        results = MCSamplesFromCobaya(updated_info,
                                      products["sample"],
                                      ignore_rows=ignore_rows,
                                      name_tag="sample")
        clusters = None
        if "clusters" in products:
            clusters = [
                MCSamplesFromCobaya(updated_info,
                                    products["clusters"][i]["sample"],
                                    name_tag="cluster %d" % (i + 1))
                for i in products["clusters"]
            ]
        # Plots!
        if not is_travis():
            try:
                import getdist.plots as gdplots
                from getdist.gaussian_mixtures import MixtureND
                sampled_params = [
                    p for p, v in info["params"].items() if "prior" not in v
                ]
                mixture = MixtureND(
                    info["likelihood"]["gaussian_mixture"]["means"],
                    info["likelihood"]["gaussian_mixture"]["covs"],
                    names=sampled_params,
                    label="truth")
                g = gdplots.getSubplotPlotter()
                to_plot = [mixture, results]
                if clusters:
                    to_plot += clusters
                g.triangle_plot(to_plot, params=sampled_params)
                g.export("test.png")
            except:
                print("Plotting failed!")
        # 1st test: KL divergence
        if n_modes == 1:
            cov_sample, mean_sample = results.getCov(
                dimension), results.getMeans()
            KL_final = KL_norm(
                m1=info["likelihood"]["gaussian_mixture"]["means"][0],
                S1=info["likelihood"]["gaussian_mixture"]["covs"][0],
                m2=mean_sample[:dimension],
                S2=cov_sample)
            print("Final KL: ", KL_final)
            assert KL_final <= KL_tolerance
        # 2nd test: clusters
        else:
            if "clusters" in products:
                assert len(products["clusters"]) >= n_modes, (
                    "Not all clusters detected!")
                for i, c2 in enumerate(clusters):
                    cov_c2, mean_c2 = c2.getCov(), c2.getMeans()
                    KLs = [
                        KL_norm(m1=info["likelihood"]["gaussian_mixture"]
                                ["means"][i_c1],
                                S1=info["likelihood"]["gaussian_mixture"]
                                ["covs"][i_c1],
                                m2=mean_c2[:dimension],
                                S2=cov_c2[:dimension, :dimension])
                        for i_c1 in range(n_modes)
                    ]
                    extra_tol = 4 * n_modes if n_modes > 1 else 1
                    print("Final KL for cluster %d: %g", i, min(KLs))
                    assert min(KLs) <= KL_tolerance * extra_tol
            else:
                assert 0, "Could not check sample convergence: multimodal but no clusters"
        # 3rd test: Evidence
        if "logZ" in products:
            logZprior = sum(np.log(ranges[:, 1] - ranges[:, 0]))
            assert (products["logZ"] - logZ_nsigmas * products["logZstd"] <
                    -logZprior <
                    products["logZ"] + logZ_nsigmas * products["logZstd"])