Initial import
This commit is contained in:
commit
56a50eead3
820 changed files with 192077 additions and 0 deletions
42
libLSS/samplers/ares/ares_bias.hpp
Normal file
42
libLSS/samplers/ares/ares_bias.hpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/ares_bias.hpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#ifndef __LIBLSS_ARES_BIAS_HPP
|
||||
#define __LIBLSS_ARES_BIAS_HPP
|
||||
|
||||
#include "libLSS/tools/console.hpp"
|
||||
#include "libLSS/samplers/core/types_samplers.hpp"
|
||||
#include "libLSS/mcmc/global_state.hpp"
|
||||
#include <boost/format.hpp>
|
||||
|
||||
namespace LibLSS {
|
||||
namespace ARES {
|
||||
inline double& extract_bias(MarkovState& state, int c)
|
||||
{
|
||||
using boost::format;
|
||||
return (*state.get<ArrayType1d>(format("galaxy_bias_%d") % c)->array)[0];
|
||||
}
|
||||
|
||||
template<typename InitializerArray>
|
||||
void ensure_bias_size(MarkovState& state, unsigned int c, const InitializerArray& init_a)
|
||||
{
|
||||
using boost::format;
|
||||
auto& a = (*state.get<ArrayType1d>(format("galaxy_bias_%d") % c)->array);
|
||||
size_t old_sz = a.size();
|
||||
if (old_sz < init_a.size()) {
|
||||
a.resize(boost::extents[init_a.size()]);
|
||||
for (size_t i = old_sz; i < init_a.size(); i++)
|
||||
a[i] = init_a[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
536
libLSS/samplers/ares/gibbs_messenger.cpp
Normal file
536
libLSS/samplers/ares/gibbs_messenger.cpp
Normal file
|
@ -0,0 +1,536 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/gibbs_messenger.cpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#include <Eigen/Core>
|
||||
#include <cmath>
|
||||
#include <boost/format.hpp>
|
||||
#include <CosmoTool/fourier/fft/fftw_calls.hpp>
|
||||
#include "libLSS/samplers/core/random_number.hpp"
|
||||
#include "libLSS/samplers/ares/gibbs_messenger.hpp"
|
||||
#include "libLSS/tools/mpi_fftw_helper.hpp"
|
||||
#include "libLSS/samplers/ares/ares_bias.hpp"
|
||||
#include "libLSS/tools/fused_array.hpp"
|
||||
#include "libLSS/tools/fused_assign.hpp"
|
||||
#include "libLSS/tools/array_tools.hpp"
|
||||
|
||||
using namespace LibLSS;
|
||||
using boost::format;
|
||||
using boost::extents;
|
||||
using LibLSS::ARES::extract_bias;
|
||||
|
||||
typedef boost::multi_array_types::extent_range range;
|
||||
|
||||
typedef Eigen::Map<Eigen::ArrayXd, Eigen::Aligned> MappedArray;
|
||||
|
||||
/* (data,s) -> t sampler
|
||||
*/
|
||||
|
||||
MessengerSampler::MessengerSampler(MPI_Communication * comm_)
|
||||
: comm(comm_), constrainedGeneration(true), mgr(0)
|
||||
{
|
||||
}
|
||||
|
||||
MessengerSampler::~MessengerSampler()
|
||||
{
|
||||
if (mgr != 0)
|
||||
delete mgr;
|
||||
}
|
||||
|
||||
void MessengerSampler::restore(MarkovState& state)
|
||||
{
|
||||
initialize(state);
|
||||
}
|
||||
|
||||
void MessengerSampler::initialize(MarkovState& state)
|
||||
{
|
||||
ArrayType *messenger;
|
||||
Console& cons = Console::instance();
|
||||
|
||||
cons.print<LOG_INFO>("Initialize Messenger sampler");
|
||||
cons.indent();
|
||||
|
||||
N0 = state.get<SLong>("N0")->value;
|
||||
N1 = state.get<SLong>("N1")->value;
|
||||
N2 = state.get<SLong>("N2")->value;
|
||||
|
||||
mgr = new FFTMgr(N0, N1, N2, comm);
|
||||
|
||||
startN0 = mgr->startN0;
|
||||
localN0 = mgr->localN0;
|
||||
|
||||
Ntot = N0*N1*N2;
|
||||
localNtot = localN0*N1*N2;
|
||||
|
||||
N_k = state.get<SLong>("NUM_MODES")->value;
|
||||
|
||||
rng = state.get<RandomGen>("random_generator");
|
||||
|
||||
cons.print<LOG_DEBUG>("Allocating messenger field");
|
||||
messenger = new ArrayType(extents[range(startN0,startN0+localN0)][N1][N2]);
|
||||
messenger->setRealDims(ArrayDimension(N0, N1, N2));
|
||||
cons.print<LOG_DEBUG>(format("Allocated messenger_field %p") % messenger->array->data());
|
||||
cons.print<LOG_DEBUG>("Allocating messenger field");
|
||||
messenger_mask = new ArrayType(extents[range(startN0,startN0+localN0)][N1][N2]);
|
||||
messenger_mask->setRealDims(ArrayDimension(N0, N1, N2));
|
||||
cons.print<LOG_DEBUG>("Allocating mixed data field");
|
||||
data_field = new ArrayType(extents[range(startN0,startN0+localN0)][N1][N2]);
|
||||
data_field->setRealDims(ArrayDimension(N0, N1, N2));
|
||||
|
||||
state.newElement("messenger_field", messenger);
|
||||
state.newElement("messenger_mask", messenger_mask);
|
||||
state.newElement("messenger_tau", messenger_tau = new SDouble());
|
||||
state.newElement("data_field", data_field);
|
||||
|
||||
cons.unindent();
|
||||
cons.print<LOG_INFO>("Done");
|
||||
}
|
||||
|
||||
void MessengerSampler::sample(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_DEBUG> ctx("MessengerSampler::sample");
|
||||
ArrayType& s_field = static_cast<ArrayType&>(state["s_field"]);
|
||||
ArrayType::ArrayType& m_field = *state.get<ArrayType>("messenger_field")->array;
|
||||
ArrayType& data_field = static_cast<ArrayType&>(state["data_field"]);
|
||||
// We need the 3d messenger mask/window
|
||||
ArrayType& W = *messenger_mask;
|
||||
// We need the random generator
|
||||
SDouble& tau = *messenger_tau;
|
||||
double sqrt_tau = std::sqrt(tau);
|
||||
|
||||
if (constrainedGeneration) {
|
||||
#pragma omp parallel
|
||||
{
|
||||
auto &rng_g = rng->get();
|
||||
const auto &W_tmp = W.array->data();
|
||||
const auto &s_tmp = s_field.array->data();
|
||||
const auto &d_tmp = data_field.array->data();
|
||||
const auto &m_tmp = m_field.data();
|
||||
#pragma omp for schedule(static)
|
||||
for (long i = 0; i < localNtot; i++) {
|
||||
double A = rng_g.gaussian();
|
||||
double Wi = W_tmp[i];
|
||||
double si = s_tmp[i];
|
||||
double di = d_tmp[i];
|
||||
double mu, sigma;
|
||||
|
||||
if (Wi > 0) {
|
||||
mu = (si * Wi + tau * di) / (Wi + tau);
|
||||
sigma = std::sqrt( (Wi*tau) / (Wi + tau) );
|
||||
} else if (Wi < 0){
|
||||
mu = si;
|
||||
sigma = sqrt_tau;
|
||||
} else {
|
||||
mu = di;
|
||||
sigma = 0;
|
||||
}
|
||||
|
||||
m_tmp[i] = mu + sigma * A;
|
||||
}
|
||||
} // end of parallel region
|
||||
} else {
|
||||
for (long i = 0; i < localNtot; i++) {
|
||||
double A = rng->get().gaussian();
|
||||
double Wi = W.array->data()[i];
|
||||
double m_i = m_field.data()[i];
|
||||
double& di = data_field.array->data()[i];
|
||||
|
||||
if (Wi > 0)
|
||||
di = m_i + std::sqrt(Wi)*A;
|
||||
else
|
||||
di = 0;
|
||||
Console::instance().c_assert(!std::isnan(di), "Data is a NaN");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* t-> s sampler
|
||||
*/
|
||||
|
||||
MessengerSignalSampler::MessengerSignalSampler(MPI_Communication* comm)
|
||||
: flat_key(0), tmp_fourier(0), tmp_fourier_m(0), tmp_m_field(0), tmp_real_field(0), analysis_plan(0), synthesis_plan(0),
|
||||
constrainedGeneration(true), comm(comm), mgr(0)
|
||||
{
|
||||
}
|
||||
|
||||
void MessengerSignalSampler::restore(MarkovState& state)
|
||||
{
|
||||
initialize(state);
|
||||
}
|
||||
|
||||
void MessengerSignalSampler::initialize(MarkovState& state)
|
||||
{
|
||||
Console& cons = Console::instance();
|
||||
ConsoleContext<LOG_INFO> ctx("Messenger-Signal sampler");
|
||||
|
||||
N0 = static_cast<SLong&>(state["N0"]);
|
||||
N1 = static_cast<SLong&>(state["N1"]);
|
||||
N2 = static_cast<SLong&>(state["N2"]);
|
||||
|
||||
mgr = new FFTMgr(N0, N1, N2, comm);
|
||||
|
||||
// This for MPI support
|
||||
startN0 = mgr->startN0;
|
||||
localN0 = mgr->localN0;
|
||||
fourierLocalSize = mgr->allocator_real.minAllocSize;
|
||||
|
||||
N_k = state.get<SLong>("NUM_MODES")->value;
|
||||
|
||||
L0 = static_cast<SDouble&>(state["L0"]);
|
||||
L1 = static_cast<SDouble&>(state["L1"]);
|
||||
L2 = static_cast<SDouble&>(state["L2"]);
|
||||
|
||||
if (tmp_fourier) {
|
||||
error_helper<ErrorBadState>("MessengerSignalSampler has already been initialized.");
|
||||
}
|
||||
|
||||
|
||||
cons.print<LOG_DEBUG>("Allocating x field");
|
||||
x_field = new ArrayType(extents[range(startN0,startN0+localN0)][N1][N2]);
|
||||
x_field->setRealDims(ArrayDimension(N0, N1, N2));
|
||||
cons.print<LOG_DEBUG>("Allocating s field");
|
||||
s_field = new ArrayType(extents[range(startN0,startN0+localN0)][N1][N2]);
|
||||
s_field->setRealDims(ArrayDimension(N0, N1, N2));
|
||||
state.newElement("x_field", x_field);
|
||||
state.newElement("s_field", s_field, true);
|
||||
|
||||
s_field->eigen().fill(0);
|
||||
x_field->eigen().fill(0);
|
||||
|
||||
Ntot = N0*N1*N2;
|
||||
Ntot_k = N0*N1*(N2/2+1);
|
||||
|
||||
localNtot = localN0*N1*N2;
|
||||
localNtot_k = localN0*N1*(N2/2+1);
|
||||
|
||||
volume = L0*L1*L2;
|
||||
volNorm = volume/Ntot;
|
||||
|
||||
ctx.print(format("fourierLocalSize = %d") % fourierLocalSize);
|
||||
tmp_fourier = MFCalls::alloc_complex(fourierLocalSize);
|
||||
tmp_fourier_m = MFCalls::alloc_complex(fourierLocalSize);
|
||||
|
||||
|
||||
#ifndef ARES_MPI_FFTW
|
||||
ctx.print("Creating FFTW plans for Messenger-Signal");
|
||||
tmp_m_field = new ArrayType(boost::extents[range(startN0,startN0+localN0)][N1][N2]);
|
||||
ctx.print(format("Allocated tmp_m_field %p") % tmp_m_field->array->origin());
|
||||
analysis_plan = MFCalls::plan_dft_r2c_3d(
|
||||
N0, N1, N2,
|
||||
x_field->array->data(),
|
||||
tmp_fourier,
|
||||
FFTW_DESTROY_INPUT|FFTW_MEASURE);
|
||||
synthesis_plan = MFCalls::plan_dft_c2r_3d(
|
||||
N0, N1, N2,
|
||||
tmp_fourier,
|
||||
x_field->array->data(),
|
||||
FFTW_DESTROY_INPUT|FFTW_MEASURE);
|
||||
#else
|
||||
ctx.print("Creating MPI/FFTW plans for Messenger-Signal");
|
||||
tmp_real_field = MFCalls::alloc_real(fourierLocalSize*2);
|
||||
analysis_plan = MFCalls::plan_dft_r2c_3d(
|
||||
N0, N1, N2,
|
||||
tmp_real_field,
|
||||
tmp_fourier,
|
||||
comm->comm(),
|
||||
// FFTW_MPI_TRANSPOSED_OUT|
|
||||
FFTW_DESTROY_INPUT|FFTW_MEASURE);
|
||||
synthesis_plan = MFCalls::plan_dft_c2r_3d(
|
||||
N0, N1, N2,
|
||||
tmp_fourier,
|
||||
tmp_real_field,
|
||||
comm->comm(),
|
||||
//FFTW_MPI_TRANSPOSED_IN|
|
||||
FFTW_DESTROY_INPUT|FFTW_MEASURE);
|
||||
#endif
|
||||
ctx.print(format("allocated tmp_fourier(%p) tmp_fourier_m(%p) and tmp_real_field(%p)") % tmp_fourier % tmp_fourier_m% tmp_real_field);
|
||||
ctx.print("Done creating FFTW plans for Messenger-Signal");
|
||||
}
|
||||
|
||||
|
||||
MessengerSignalSampler::~MessengerSignalSampler()
|
||||
{
|
||||
if (tmp_fourier) {
|
||||
Console::instance().print<LOG_INFO>("Cleaning up Messenger-Signal");
|
||||
|
||||
#ifdef ARES_MPI_FFTW
|
||||
delete tmp_m_field;
|
||||
#endif
|
||||
if (flat_key)
|
||||
delete flat_key;
|
||||
if (tmp_fourier)
|
||||
MFCalls::free(tmp_fourier);
|
||||
if (tmp_fourier_m)
|
||||
MFCalls::free(tmp_fourier_m);
|
||||
if (tmp_real_field)
|
||||
MFCalls::free(tmp_real_field);
|
||||
if (analysis_plan)
|
||||
MFCalls::destroy_plan(analysis_plan);
|
||||
if (synthesis_plan)
|
||||
MFCalls::destroy_plan(synthesis_plan);
|
||||
|
||||
if (mgr)
|
||||
delete mgr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MessengerSignalSampler::sample(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_DEBUG> ctx("MessengerSignalSampler::sample");
|
||||
RandomGen& rng = static_cast<RandomGen&>(state["random_generator"]);
|
||||
ArrayType& m_field = *state.get<ArrayType>("messenger_field");
|
||||
ArrayType1d::ArrayType& P_info = *state.get<ArrayType1d>("powerspectrum")->array;
|
||||
SDouble& tau = static_cast<SDouble&>(state["messenger_tau"]);
|
||||
IArrayType::ArrayType& P_key = *state.get<IArrayType>("k_keys")->array; // Built by powerspec_tools
|
||||
|
||||
ArrayType& x = *x_field;
|
||||
ArrayType& s = *s_field;
|
||||
double alpha = 1/std::sqrt(double(Ntot));
|
||||
Console& cons = Console::instance();
|
||||
|
||||
ctx.print("Sample messenger-signal");
|
||||
|
||||
if (state.get<SBool>("messenger_signal_blocked")->value && constrainedGeneration)
|
||||
return;
|
||||
|
||||
// We have to initialize this lazily. k_keys is created by powerspectrum samplers.
|
||||
if (flat_key == 0) {
|
||||
IArrayType *keys = state.get<IArrayType>("k_keys");
|
||||
flat_key = new FlatIntType( keys->array->data(), boost::extents[keys->array->num_elements()] );
|
||||
}
|
||||
|
||||
#pragma omp parallel
|
||||
{
|
||||
auto &rng_g = rng.get();
|
||||
const auto &data = x.array->data();
|
||||
#pragma omp for schedule(static)
|
||||
for (long i = 0; i < localNtot; i++) {
|
||||
data[i] = rng_g.gaussian()*alpha;
|
||||
}
|
||||
}
|
||||
copy_padded_data(*x.array, tmp_real_field, true);
|
||||
// This destroy the x_field. Not a problem. synthesis is regenerating it
|
||||
MFCalls::execute(analysis_plan);
|
||||
#ifdef ARES_MPI_FFTW
|
||||
copy_padded_data(*m_field.array, tmp_real_field);
|
||||
MFCalls::execute_r2c(analysis_plan, tmp_real_field, tmp_fourier_m);
|
||||
#else
|
||||
// This destroy the m_field. Could be annoying.
|
||||
tmp_m_field->eigen() = m_field.eigen();
|
||||
FCalls::execute_r2c(analysis_plan, m_field.array->data(), tmp_fourier_m);
|
||||
#endif
|
||||
|
||||
if (constrainedGeneration) {
|
||||
double scaler = 1/volNorm;
|
||||
double T = tau * volume;
|
||||
|
||||
boost::multi_array<double, 1> sqrtP(boost::extents[N_k]);
|
||||
boost::multi_array<double, 1> A1(boost::extents[N_k]);
|
||||
boost::multi_array<double, 1> A2(boost::extents[N_k]);
|
||||
|
||||
LibLSS::copy_array(sqrtP,
|
||||
b_fused<double>(P_info,
|
||||
[this,scaler](double x)->double const { return x < 0 ? 0 : std::sqrt(x*volume);}
|
||||
)
|
||||
);
|
||||
LibLSS::copy_array(A1,
|
||||
b_fused<double>(P_info, sqrtP,
|
||||
[this,scaler,T](double x,double y)->double const { return x < 0 ? 0 : y/(T+x*volume*scaler); })
|
||||
);
|
||||
LibLSS::copy_array(A2,
|
||||
b_fused<double>(P_info,
|
||||
[this,scaler,T](double x)->double const { return x < 0 ? 0 : std::sqrt(T/(T+x*volume*scaler)); })
|
||||
);
|
||||
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (long i = 0; i < localNtot_k; i++) {
|
||||
long key = (*flat_key)[i];
|
||||
double color_P = sqrtP[key];
|
||||
double aux1 = A1[key];
|
||||
double aux2 = A2[key];
|
||||
MFCalls::complex_type& white_phase = tmp_fourier_m[i];
|
||||
MFCalls::complex_type& random_phase = tmp_fourier[i];
|
||||
MFCalls::complex_type& colored_phase = tmp_fourier_m[i];
|
||||
|
||||
random_phase[0] = aux1 * white_phase[0] + aux2 * random_phase[0];
|
||||
random_phase[1] = aux1 * white_phase[1] + aux2 * random_phase[1];
|
||||
|
||||
colored_phase[0] = color_P * random_phase[0];
|
||||
colored_phase[1] = color_P * random_phase[1];
|
||||
}
|
||||
if (startN0 == 0 && localN0 > 1) {
|
||||
tmp_fourier[0][0] = 0;
|
||||
tmp_fourier[0][1] = 0;
|
||||
tmp_fourier_m[0][0] = 0;
|
||||
tmp_fourier_m[0][1] = 0;
|
||||
}
|
||||
} else {
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (long i = 0; i < localNtot_k; i++) {
|
||||
double P = P_info[(*flat_key)[i]] * volume;
|
||||
double color_P = std::sqrt(P);
|
||||
MFCalls::complex_type& white_phase = tmp_fourier_m[i];
|
||||
MFCalls::complex_type& random_phase = tmp_fourier[i];
|
||||
MFCalls::complex_type& colored_phase = tmp_fourier_m[i];
|
||||
|
||||
colored_phase[0] = color_P * random_phase[0];
|
||||
colored_phase[1] = color_P * random_phase[1];
|
||||
}
|
||||
}
|
||||
|
||||
ctx.print("Fourier synthesis of phases");
|
||||
// Regenerate a correct x_field
|
||||
MFCalls::execute(synthesis_plan);
|
||||
copy_unpadded_data(tmp_real_field, *x.array, true);
|
||||
|
||||
ctx.print("Fourier synthesis of signal");
|
||||
// Generate the colored s field
|
||||
#ifdef ARES_MPI_FFTW
|
||||
MFCalls::execute_c2r(synthesis_plan, tmp_fourier_m, tmp_real_field);
|
||||
copy_unpadded_data(tmp_real_field, *s.array);
|
||||
#else
|
||||
FCalls::execute_c2r(synthesis_plan, tmp_fourier_m, s.array->data());
|
||||
if (constrainedGeneration) {
|
||||
// Restore m_field
|
||||
m_field.eigen() = tmp_m_field->eigen();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Just renormalize
|
||||
array::scaleArray3d(*s.array, 1.0/volume);
|
||||
array::scaleArray3d(*x.array, 1.0/volume);
|
||||
|
||||
// Generate m_field in mock mode
|
||||
if (!constrainedGeneration) {
|
||||
double sq_tau = sqrt(tau);
|
||||
|
||||
// Populate m_field
|
||||
for (long i = 0; i < localNtot; i++)
|
||||
m_field.array->data()[i] = s.array->data()[i] + rng.get().gaussian()*sq_tau;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (catalog,meta) -> data
|
||||
*/
|
||||
|
||||
|
||||
void CatalogProjectorSampler::initialize(MarkovState& state)
|
||||
{
|
||||
Ncat = static_cast<SLong&>(state["NCAT"]);
|
||||
}
|
||||
|
||||
void CatalogProjectorSampler::restore(MarkovState& state)
|
||||
{
|
||||
Ncat = static_cast<SLong&>(state["NCAT"]);
|
||||
}
|
||||
|
||||
void CatalogProjectorSampler::sample(MarkovState& state)
|
||||
{
|
||||
RandomGen& rng = static_cast<RandomGen&>(state["random_generator"]);
|
||||
ArrayType& W = *state.get<ArrayType>("messenger_mask");
|
||||
SDouble *messenger_tau = state.get<SDouble>("messenger_tau");
|
||||
ArrayType& G = *state.get<ArrayType>("growth_factor");
|
||||
ArrayType& data_field = *state.get<ArrayType>("data_field");
|
||||
// Just do vectorized operation here
|
||||
MappedArray map_W = W.eigen();
|
||||
MappedArray growth = G.eigen();
|
||||
MappedArray map_data = data_field.eigen();
|
||||
ConsoleContext<LOG_DEBUG> ctx("regenerate_W");
|
||||
double heat = state.getScalar<double>("ares_heat");
|
||||
|
||||
ctx.print("Rebuild the projected data and covariance matrix");
|
||||
// Clear up W first
|
||||
map_W.fill(0);
|
||||
if (!mockGeneration)
|
||||
map_data.fill(0);
|
||||
for (int c = 0; c < Ncat; c++) {
|
||||
ctx.print(format("Looking at catalog %d") % c);
|
||||
|
||||
SelArrayType& sel_field = *state.get<SelArrayType>(format("galaxy_synthetic_sel_window_%d") % c);
|
||||
ArrayType& g_field = *state.get<ArrayType>(format("galaxy_data_%d") % c);
|
||||
double& bias = extract_bias(state, c);
|
||||
double nmean = state.get<SDouble>(format("galaxy_nmean_%d") % c)->value;
|
||||
MappedArray g_data = g_field.eigen();
|
||||
MappedArray map_sel = sel_field.eigen();
|
||||
|
||||
if (!mockGeneration)
|
||||
map_data += (g_data - nmean * map_sel) * bias * growth;
|
||||
|
||||
map_W += map_sel * nmean * bias*bias * growth * growth;
|
||||
}
|
||||
map_W /= heat;
|
||||
|
||||
ctx.print("Finish weights");
|
||||
|
||||
// Hmm... I cannot use the vectorized instruction here as it depends on the positivity of map_W[i]. Just do a loop
|
||||
double tau_inverse = 0; // This is the inverse of minimum covariance
|
||||
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (long n = 0; n < map_W.size(); n++) {
|
||||
double& val = map_W[n];
|
||||
|
||||
if (val > 0) {
|
||||
if (val > tau_inverse)
|
||||
tau_inverse = val;
|
||||
val = 1/val;
|
||||
} else
|
||||
val = 0;
|
||||
}
|
||||
ctx.print(format("Got partial_tau = %lg") % (1/tau_inverse));
|
||||
|
||||
comm->all_reduce(MPI_IN_PLACE, &tau_inverse, 1, translateMPIType<double>(), MPI_MAX);
|
||||
double tau = 1/tau_inverse;
|
||||
|
||||
messenger_tau->value = tau;
|
||||
|
||||
if (!mockGeneration)
|
||||
map_data *= map_W;
|
||||
else {
|
||||
for (int c = 0; c < Ncat; c++) {
|
||||
SelArrayType& sel_field = *state.get<SelArrayType>(format("galaxy_synthetic_sel_window_%d") % c);
|
||||
double& bias = extract_bias(state, c);
|
||||
double nmean = state.get<SDouble>(format("galaxy_nmean_%d") % c)->value;
|
||||
MappedArray map_sel = sel_field.eigen();
|
||||
ArrayType& s_field = *state.get<ArrayType>("s_field");
|
||||
ArrayType& g_field = *state.get<ArrayType>(format("galaxy_data_%d") % c);
|
||||
MappedArray s_data = s_field.eigen();
|
||||
MappedArray g_data = g_field.eigen();
|
||||
Eigen::ArrayXd err(map_sel.size());
|
||||
|
||||
ctx.print(format("Catalog %d: Generate mock data with nmean = %lg, bias = %lg") % c % nmean % bias);
|
||||
|
||||
err = map_sel * nmean;
|
||||
|
||||
g_data = err*(1+bias*growth*s_data);
|
||||
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (long i = 0; i < err.size(); i++) {
|
||||
double E = err[i];
|
||||
if (E > 0) {
|
||||
g_data[i] += rng.get().gaussian() * sqrt(E);
|
||||
} else {
|
||||
g_data[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma omp parallel for schedule(static)
|
||||
for (long n = 0; n < map_W.size(); n++) {
|
||||
if (map_W[n] > 0)
|
||||
map_W[n] = std::max(double(0), map_W[n] - tau);
|
||||
else
|
||||
map_W[n] = -1;
|
||||
}
|
||||
ctx.print(format("Got tau = %lg") % tau );
|
||||
}
|
102
libLSS/samplers/ares/gibbs_messenger.hpp
Normal file
102
libLSS/samplers/ares/gibbs_messenger.hpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/gibbs_messenger.hpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#ifndef __LIBLSS_GIBBS_MESSENGER_HPP
|
||||
#define __LIBLSS_GIBBS_MESSENGER_HPP
|
||||
|
||||
#include <CosmoTool/fourier/fft/fftw_calls.hpp>
|
||||
#include "libLSS/mpi/generic_mpi.hpp"
|
||||
#include "libLSS/mcmc/global_state.hpp"
|
||||
#include "libLSS/tools/fftw_allocator.hpp"
|
||||
#include "libLSS/samplers/core/markov.hpp"
|
||||
#include "libLSS/samplers/core/random_number.hpp"
|
||||
#include "libLSS/samplers/core/types_samplers.hpp"
|
||||
#include "libLSS/tools/mpi_fftw_helper.hpp"
|
||||
|
||||
namespace LibLSS {
|
||||
|
||||
namespace GibbsMessenger {
|
||||
|
||||
namespace details {
|
||||
|
||||
typedef FFTW_Manager_3d<double> FFTMgr;
|
||||
|
||||
class MessengerSampler: public MarkovSampler {
|
||||
protected:
|
||||
long N0, N1, N2, Ntot, N_k;
|
||||
long localN0, startN0, localNtot;
|
||||
ArrayType *messenger_mask, *data_field;
|
||||
SDouble *messenger_tau;
|
||||
RandomGen *rng;
|
||||
bool constrainedGeneration;
|
||||
MPI_Communication *comm;
|
||||
FFTMgr *mgr;
|
||||
public:
|
||||
MessengerSampler(MPI_Communication *comm);
|
||||
virtual ~MessengerSampler();
|
||||
|
||||
virtual void restore(MarkovState& state);
|
||||
virtual void initialize(MarkovState& state);
|
||||
virtual void sample(MarkovState& state);
|
||||
|
||||
void setMockGeneration(bool b) { constrainedGeneration = !b; }
|
||||
|
||||
};
|
||||
|
||||
class MessengerSignalSampler: public MarkovSampler {
|
||||
protected:
|
||||
typedef boost::multi_array_ref< IArrayType::ArrayType::element, 1> FlatIntType;
|
||||
long fourierLocalSize;
|
||||
FCalls::plan_type analysis_plan, synthesis_plan;
|
||||
FCalls::complex_type *tmp_fourier, *tmp_fourier_m;
|
||||
FlatIntType *flat_key;
|
||||
double volNorm;
|
||||
long N0, N1, N2, Ntot, Ntot_k, N_k;
|
||||
long startN0, localN0, localNtot, localNtot_k;
|
||||
double L0, L1, L2, volume;
|
||||
ArrayType *tmp_m_field, *x_field, *s_field;
|
||||
bool constrainedGeneration;
|
||||
MPI_Communication *comm;
|
||||
FCalls::real_type *tmp_real_field;
|
||||
FFTMgr *mgr;
|
||||
public:
|
||||
MessengerSignalSampler(MPI_Communication* comm);
|
||||
virtual ~MessengerSignalSampler();
|
||||
|
||||
virtual void restore(MarkovState& state);
|
||||
virtual void initialize(MarkovState& state);
|
||||
virtual void sample(MarkovState& state);
|
||||
|
||||
void setMockGeneration(bool b) { constrainedGeneration = !b; }
|
||||
|
||||
};
|
||||
|
||||
class CatalogProjectorSampler: public MarkovSampler {
|
||||
protected:
|
||||
int Ncat;
|
||||
MPI_Communication *comm;
|
||||
bool mockGeneration;
|
||||
public:
|
||||
CatalogProjectorSampler(MPI_Communication *comm0): comm(comm0), mockGeneration(false) {}
|
||||
|
||||
virtual void restore(MarkovState& state);
|
||||
virtual void initialize(MarkovState& state);
|
||||
virtual void sample(MarkovState& state);
|
||||
|
||||
void setMockGeneration(bool b) { mockGeneration = b; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
using GibbsMessenger::details::MessengerSampler;
|
||||
using GibbsMessenger::details::MessengerSignalSampler;
|
||||
using GibbsMessenger::details::CatalogProjectorSampler;
|
||||
}
|
||||
|
||||
#endif
|
266
libLSS/samplers/ares/linbias_sampler.cpp
Normal file
266
libLSS/samplers/ares/linbias_sampler.cpp
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/linbias_sampler.cpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#include <boost/format.hpp>
|
||||
#include <functional>
|
||||
#include <cmath>
|
||||
#include <CosmoTool/algo.hpp>
|
||||
#include "libLSS/tools/errors.hpp"
|
||||
#include "libLSS/samplers/core/gig_sampler.hpp"
|
||||
#include "libLSS/samplers/ares/linbias_sampler.hpp"
|
||||
#include "libLSS/samplers/rgen/slice_sweep.hpp"
|
||||
#include "libLSS/samplers/ares/ares_bias.hpp"
|
||||
#include "libLSS/tools/array_tools.hpp"
|
||||
#include "boost/lambda/lambda.hpp"
|
||||
|
||||
using namespace LibLSS;
|
||||
using boost::format;
|
||||
using LibLSS::ARES::extract_bias;
|
||||
using LibLSS::ARES::ensure_bias_size;
|
||||
namespace ph = std::placeholders;
|
||||
|
||||
void LinearBiasSampler::initialize(MarkovState& state)
|
||||
{
|
||||
long N0, N1, N2;
|
||||
long localN0, startN0;
|
||||
|
||||
ConsoleContext<LOG_DEBUG> ctx("initialization of LinearBiasSampler");
|
||||
// This sampler depends heavily on the rest of the model.
|
||||
// First grab the number of catalogs available in the markov chain
|
||||
|
||||
Ncat = static_cast<SLong&>(state["NCAT"]);
|
||||
|
||||
N0 = static_cast<SLong&>(state["N0"]);
|
||||
localN0 = static_cast<SLong&>(state["localN0"]);
|
||||
startN0 = static_cast<SLong&>(state["startN0"]);
|
||||
N1 = static_cast<SLong&>(state["N1"]);
|
||||
N2 = static_cast<SLong&>(state["N2"]);
|
||||
|
||||
Ntot = N0*N1*N2;
|
||||
localNtot = localN0*N1*N2;
|
||||
// Ensure that the bias is at least size 1
|
||||
for (unsigned int c = 0; c < Ncat; c++)
|
||||
ensure_bias_size(state, c, boost::array<double,1>({1}));
|
||||
}
|
||||
|
||||
void LinearBiasSampler::restore(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_DEBUG> ctx("restoration of LinearBiasSampler");
|
||||
initialize(state);
|
||||
}
|
||||
|
||||
|
||||
static inline double logPosteriorBias(double b, double mean, double dev, double heat)
|
||||
{
|
||||
if (b < 0)
|
||||
return -std::numeric_limits<double>::infinity();
|
||||
|
||||
double delta = (b-mean)/dev;
|
||||
|
||||
return -0.5*delta*delta*heat;
|
||||
}
|
||||
|
||||
void LinearBiasSampler::sample(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_DEBUG> ctx("sampling of mean and bias");
|
||||
ArrayType& data_field = *state.get<ArrayType>("data_field");
|
||||
ArrayType& W = *state.get<ArrayType>("messenger_mask");
|
||||
double *G = state.get<ArrayType>("growth_factor")->array->data();
|
||||
double *s_field = state.get<ArrayType>("s_field")->array->data();
|
||||
RandomGen *rng = state.get<RandomGen>("random_generator");
|
||||
double heat = state.getScalar<double>("ares_heat");
|
||||
using boost::extents;
|
||||
using CosmoTool::square;
|
||||
|
||||
if (state.get<SBool>("bias_sampler_blocked")->value)
|
||||
return;
|
||||
|
||||
auto ext_Ncat = extents[Ncat];
|
||||
boost::multi_array<double, 1>
|
||||
alphas(ext_Ncat), betas(ext_Ncat),
|
||||
chis(ext_Ncat), psis(ext_Ncat), Npixs(ext_Ncat);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// Time consuming part, do data reduction per sub-catalog
|
||||
// We are only computing alphas and betas here.
|
||||
for (int c = 0; c < Ncat; c++) {
|
||||
SelArrayType& sel_field = *state.get<SelArrayType>(format("galaxy_synthetic_sel_window_%d") % c);
|
||||
double *g_field = state.get<ArrayType>(format("galaxy_data_%d") % c)->array->data();
|
||||
double& bias = extract_bias(state, c);
|
||||
SDouble *g_nmean = state.get<SDouble>(format("galaxy_nmean_%d") % c);
|
||||
double nmean = g_nmean->value;
|
||||
|
||||
const auto &sel_array = sel_field.array->data();
|
||||
double loc_alpha = 0, loc_beta = 0, loc_psi = 0, loc_chi = 0, loc_Npix = 0, alpha = 0, beta = 0;
|
||||
|
||||
#pragma omp parallel for schedule(dynamic, 1024) reduction(+:loc_alpha,loc_beta,loc_chi,loc_psi,loc_Npix)
|
||||
for (long i = 0; i < localNtot; i++) {
|
||||
double selection = sel_array[i];
|
||||
if (selection > 0) {
|
||||
double Nobs = g_field[i];
|
||||
double Dplus = G[i];
|
||||
double density = s_field[i];
|
||||
double aux_gamma = 1 + bias * Dplus * density;
|
||||
|
||||
loc_beta += selection * nmean * Dplus * Dplus * density * density;
|
||||
loc_alpha += (Nobs - selection*nmean) * Dplus * density;
|
||||
loc_chi += Nobs*Nobs/selection;
|
||||
loc_psi += selection * aux_gamma * aux_gamma;
|
||||
loc_Npix++;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the partial result and continue
|
||||
alphas[c] = loc_alpha;
|
||||
betas[c] = loc_beta;
|
||||
chis[c] = loc_chi;
|
||||
psis[c] = loc_psi;
|
||||
Npixs[c] = loc_Npix;
|
||||
}
|
||||
|
||||
// Final reduction
|
||||
ctx.print("Reducing result");
|
||||
comm->all_reduce_t(MPI_IN_PLACE, alphas.data(), Ncat, MPI_SUM);
|
||||
comm->all_reduce_t(MPI_IN_PLACE, betas.data(), Ncat, MPI_SUM);
|
||||
comm->all_reduce_t(MPI_IN_PLACE, chis.data(), Ncat, MPI_SUM);
|
||||
comm->all_reduce_t(MPI_IN_PLACE, psis.data(), Ncat, MPI_SUM);
|
||||
comm->all_reduce_t(MPI_IN_PLACE, Npixs.data(), Ncat, MPI_SUM);
|
||||
ctx.print("Done");
|
||||
|
||||
for (int c = 0; c < Ncat; c++) {
|
||||
double& bias = extract_bias(state, c);
|
||||
double& nmean = state.get<SDouble>(format("galaxy_nmean_%d") % c)->value;
|
||||
|
||||
double alpha = alphas[c], beta = betas[c];
|
||||
bool biasRef = state.get<SBool>(format("galaxy_bias_ref_%d") % c )->value;
|
||||
|
||||
if (comm->rank() == 0 ) {// || comm->size() == 1 ) { // Use another node */
|
||||
double lambda = 1 - 0.5*Npixs[c];
|
||||
|
||||
nmean = GIG_sampler_3params(heat*psis[c],heat*chis[c],lambda,
|
||||
rng->get());
|
||||
|
||||
ctx.print(format("Npix = %d, chi = %lg, psi = %lg") % Npixs[c] % chis[c] % psis[c]);
|
||||
ctx.print(format("Broadcast value -> nmean = %lg") % nmean);
|
||||
}
|
||||
|
||||
if (!biasRef && comm->rank() == 0) {
|
||||
double mean_bias = alpha/beta;
|
||||
double dev_bias = sqrt(1/beta);
|
||||
|
||||
Console::instance().c_assert(!std::isinf(mean_bias) && !std::isnan(mean_bias), "Mean is NaN or infinite");
|
||||
ctx.print(format("bias = %lg, mean_bias = %lg, dev_bias = %lg") % bias % mean_bias % dev_bias);
|
||||
bias = slice_sweep(rng->get(), std::bind(logPosteriorBias, ph::_1, mean_bias, dev_bias, heat), bias, dev_bias);
|
||||
|
||||
Console::instance().c_assert(bias > 0, "Negative bias (0). Ouch!");
|
||||
}
|
||||
|
||||
ctx.print("Sync bias");
|
||||
// Synchronize all nodes with the new bias value
|
||||
comm->broadcast_t(&bias, 1, 0);
|
||||
|
||||
ctx.print("Sync nmean");
|
||||
// Synchronize all nodes with the new mean value
|
||||
comm->broadcast_t(&nmean, 1, 0 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
///now improve sampling efficiency by performing a joint step in s,P(k) and biases
|
||||
///NOTE: the following algorithm MUST be executed in sequence
|
||||
///get RNG
|
||||
|
||||
//only update if power-spectrum is sampled
|
||||
if (state.getScalar<bool>("power_sampler_a_blocked") &&
|
||||
state.getScalar<bool>("power_sampler_b_blocked") &&
|
||||
state.getScalar<bool>("power_sampler_c_blocked"))
|
||||
return;
|
||||
|
||||
RandomGen *rgen = state.get<RandomGen>("random_generator");
|
||||
double factor = 1.;
|
||||
|
||||
if (comm->rank() == 0) {
|
||||
for (int c = 0; c < Ncat; c++) {
|
||||
bool biasRef = state.get<SBool>(format("galaxy_bias_ref_%d") % c )->value;
|
||||
|
||||
//Don't sample the reference bias
|
||||
if (biasRef)
|
||||
continue;
|
||||
|
||||
//1) draw random bias realization (b1) for the first catalog
|
||||
double mean_bias = alphas[c]/betas[c];
|
||||
double dev_bias = sqrt(1./betas[c]);
|
||||
double& b0 = extract_bias(state, c);
|
||||
double b1=b0;
|
||||
|
||||
ctx.print(boost::format("Slice sweeping[%d]: mean_bias = %lg, dev_bias = %lg") % c % mean_bias % dev_bias);
|
||||
b1 = slice_sweep(rng->get(), std::bind(logPosteriorBias, ph::_1, mean_bias, dev_bias, heat), b1, dev_bias);
|
||||
|
||||
double fact_virt = b0/b1;
|
||||
|
||||
//Now calculate hastings value for the all catalogs but the current one (this sum can be done in parallel)
|
||||
double dH=0.;
|
||||
for (int cc = 0; cc < Ncat; cc++) {
|
||||
|
||||
if(c!=cc) {
|
||||
double bb = extract_bias(state, cc);
|
||||
|
||||
//Note that we need to operate with the updated density field
|
||||
//we calculate the metropolis factor of remaining likelihoods with respect to jumps in bias and density field
|
||||
dH += 2 * (1-fact_virt) * alphas[cc] * factor * bb -
|
||||
(1-fact_virt*fact_virt) * betas[cc]*square(factor*bb);
|
||||
}
|
||||
}
|
||||
|
||||
dH *= 0.5*heat;
|
||||
|
||||
//now do Metropolis step
|
||||
double log_u = log(rgen->get().uniform());
|
||||
if (log_u <= -dH) {
|
||||
//update accepted bias
|
||||
b0 = b1;
|
||||
//also update the density factor
|
||||
//this accounts for updating the density and power-spectrum fields deterministically
|
||||
factor *= fact_virt;
|
||||
|
||||
// ctx.print(format("Sample accepted for catalog nr. %lg! New bias = %lg , New density factor = %lg") %c % b0 % factor);
|
||||
}
|
||||
//if sample is rejected then simply continue
|
||||
comm->broadcast_t(&b0, 1, 0);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// We are not root, just gather the biases as they are updated
|
||||
for (int c = 0; c < Ncat; c++) {
|
||||
bool biasRef = state.get<SBool>(format("galaxy_bias_ref_%d") % c )->value;
|
||||
|
||||
//Don't sample the reference bias
|
||||
if (!biasRef) {
|
||||
double& b0 = extract_bias(state, c);
|
||||
|
||||
// Update from Root rank the value of bias
|
||||
comm->broadcast_t(&b0, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Broadcast and gather the scaling factor
|
||||
comm->broadcast_t(&factor, 1, 0);
|
||||
|
||||
//Finally we just need to rescale the density and power-spectrum fields by "factor"
|
||||
|
||||
//1) scale density field in real and Fourier space
|
||||
array::scaleArray3d(*state.get<ArrayType>("s_field")->array, factor);
|
||||
|
||||
//2) scale power-spectrum
|
||||
ArrayType1d::ArrayType& P_info = *state.get<ArrayType1d>("powerspectrum")->array;
|
||||
LibLSS::copy_array(P_info, b_fused<double>(P_info, (factor*factor)*boost::lambda::_1));
|
||||
}
|
36
libLSS/samplers/ares/linbias_sampler.hpp
Normal file
36
libLSS/samplers/ares/linbias_sampler.hpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/linbias_sampler.hpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#ifndef __LIBLSS_LINEAR_BIAS_SAMPLER_HPP
|
||||
#define __LIBLSS_LINEAR_BIAS_SAMPLER_HPP
|
||||
|
||||
#include <boost/multi_array.hpp>
|
||||
#include "libLSS/samplers/core/markov.hpp"
|
||||
#include "libLSS/samplers/core/types_samplers.hpp"
|
||||
|
||||
namespace LibLSS {
|
||||
|
||||
class LinearBiasSampler: public MarkovSampler {
|
||||
protected:
|
||||
int Ncat;
|
||||
long Ntot, localNtot;
|
||||
boost::multi_array<SDouble *, 1> biases;
|
||||
MPI_Communication *comm;
|
||||
public:
|
||||
LinearBiasSampler(MPI_Communication *comm0) : comm(comm0) {}
|
||||
virtual ~LinearBiasSampler() {}
|
||||
|
||||
virtual void initialize(MarkovState& state);
|
||||
virtual void restore(MarkovState& state);
|
||||
virtual void sample(MarkovState& state);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
142
libLSS/samplers/ares/powerspectrum_a_sampler.cpp
Normal file
142
libLSS/samplers/ares/powerspectrum_a_sampler.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/powerspectrum_a_sampler.cpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#include <cmath>
|
||||
#include "libLSS/tools/console.hpp"
|
||||
#include "libLSS/samplers/ares/powerspectrum_a_sampler.hpp"
|
||||
#include "libLSS/mcmc/state_element.hpp"
|
||||
#include "libLSS/samplers/core/powerspec_tools.hpp"
|
||||
#include "libLSS/tools/mpi_fftw_helper.hpp"
|
||||
|
||||
using namespace LibLSS;
|
||||
|
||||
void PowerSpectrumSampler_a::base_init()
|
||||
{
|
||||
ConsoleContext<LOG_DEBUG> ctx("base_init");
|
||||
|
||||
ctx.print(boost::format("Allocating Fourier buffer %dx%dx%d") % N0 % N1 % N2_HC);
|
||||
tmp_fourier = MFCalls::alloc_complex(fourierLocalSize);
|
||||
tmp_s = MFCalls::alloc_real(2*fourierLocalSize);
|
||||
assert(tmp_fourier != 0);
|
||||
|
||||
ctx.print(boost::format("Fourier buffer %p") % tmp_fourier);
|
||||
ctx.print(boost::format("Allocating plan %dx%dx%d") % N0 % N1 % N2);
|
||||
analysis_plan = MFCalls::plan_dft_r2c_3d(
|
||||
N0, N1, N2,
|
||||
tmp_s,
|
||||
(FCalls::complex_type *)tmp_fourier,
|
||||
#ifdef ARES_MPI_FFTW
|
||||
comm->comm(),
|
||||
#endif
|
||||
//FFTW_MPI_TRANSPOSED_OUT|
|
||||
FFTW_DESTROY_INPUT|FFTW_MEASURE);
|
||||
|
||||
flat_keys = new FlatIntType(keys->array->data(), boost::extents[keys->array->num_elements()] );
|
||||
}
|
||||
|
||||
void PowerSpectrumSampler_a::restore(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_INFO> ctx("restoration of power spectrum sampler (a)");
|
||||
|
||||
restore_base(state);
|
||||
|
||||
base_init();
|
||||
}
|
||||
|
||||
void PowerSpectrumSampler_a::initialize(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_INFO> ctx("initialization of power spectrum sampler (a)");
|
||||
|
||||
initialize_base(state);
|
||||
|
||||
base_init();
|
||||
}
|
||||
|
||||
PowerSpectrumSampler_a::PowerSpectrumSampler_a(MPI_Communication *comm0)
|
||||
: PowerSpectrumSampler_Base(comm0), tmp_fourier(0), flat_keys(0), tmp_s(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PowerSpectrumSampler_a::~PowerSpectrumSampler_a()
|
||||
{
|
||||
if (tmp_fourier) {
|
||||
Console::instance().print<LOG_INFO>("Cleaning up Powerspectrum sampler (a)");
|
||||
|
||||
MFCalls::free(tmp_fourier);
|
||||
MFCalls::destroy_plan(analysis_plan);
|
||||
delete flat_keys;
|
||||
}
|
||||
if (tmp_s)
|
||||
MFCalls::free(tmp_s);
|
||||
}
|
||||
|
||||
void PowerSpectrumSampler_a::sample(MarkovState& state)
|
||||
{
|
||||
// Grab the messenger field
|
||||
ConsoleContext<LOG_DEBUG> ctx("PowerSpectrumSampler_a::sample");
|
||||
Console& cons = Console::instance();
|
||||
ArrayType& s_field = static_cast<ArrayType&>(state["s_field"]);
|
||||
|
||||
//return;
|
||||
IArrayType1d::ArrayType& nmode_array = *nmode->array;
|
||||
ArrayType1d::ArrayType& P_array = *P->array;
|
||||
|
||||
|
||||
if (state.get<SBool>("power_sampler_a_blocked")->value)
|
||||
return;
|
||||
|
||||
copy_padded_data(*s_field.array, tmp_s);
|
||||
MFCalls::execute(analysis_plan);
|
||||
|
||||
ctx.print("Compute inverse-gamma parameter");
|
||||
|
||||
std::fill(P_array.begin(), P_array.end(), 0);
|
||||
|
||||
ctx.print(boost::format("N_fourier_elements = %d") % N_fourier_elements);
|
||||
int *adjust = adjustMul->array->data();
|
||||
//#pragma omp parallel for schedule(static)
|
||||
for (long i = 0; i < local_fourier_elements; i++) {
|
||||
FCalls::complex_type& m_hat = tmp_fourier[i];
|
||||
double Pelt = m_hat[0]*m_hat[0] + m_hat[1]*m_hat[1];
|
||||
|
||||
// adjust increase memory bandwidth consumption. Not great...
|
||||
// OTOH it is very convenient and this loop is not the most time consuming aspect
|
||||
P_array[ (*flat_keys)[i] ] += adjust[i] * Pelt;
|
||||
}
|
||||
P_sync.mpiAllSum(*comm);
|
||||
|
||||
ctx.print("Sample new power spectrum");
|
||||
|
||||
const int alpha=1; ///Jeffreys prior
|
||||
|
||||
// Only compute random numbers on rank==0, broadcast after
|
||||
if (comm->rank() == 0) {
|
||||
#pragma omp parallel for schedule(static)
|
||||
for(long l = 0; l < N_k; l++) {
|
||||
if(nmode_array[l] > 0) {
|
||||
int beta = (2*alpha-2) + nmode_array[l];
|
||||
|
||||
///generate CHi-SQUARE sample
|
||||
double z2 = 0.;
|
||||
for(int j = 0; j < beta; j++) {
|
||||
double aux=rgen->get().gaussian();
|
||||
|
||||
z2 += aux*aux;
|
||||
}
|
||||
///calculate power-spectrum sample
|
||||
P_array[l] = (P_array[l]/z2) * volNorm / Ntot;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
P_sync.mpiBroadcast(*comm);
|
||||
}
|
||||
|
41
libLSS/samplers/ares/powerspectrum_a_sampler.hpp
Normal file
41
libLSS/samplers/ares/powerspectrum_a_sampler.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/powerspectrum_a_sampler.hpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#ifndef __LIBLSS_POWERSPECTRUM_A_SAMPLER_HPP
|
||||
#define __LIBLSS_POWERSPECTRUM_A_SAMPLER_HPP
|
||||
|
||||
#include "libLSS/mpi/generic_mpi.hpp"
|
||||
#include "libLSS/samplers/core/markov.hpp"
|
||||
#include "libLSS/samplers/core/types_samplers.hpp"
|
||||
#include "libLSS/samplers/core/powerspec_tools.hpp"
|
||||
|
||||
namespace LibLSS {
|
||||
|
||||
class PowerSpectrumSampler_a: public PowerSpectrumSampler_Base {
|
||||
protected:
|
||||
typedef boost::multi_array_ref< IArrayType::ArrayType::element, 1> FlatIntType;
|
||||
|
||||
FCalls::complex_type *tmp_fourier;
|
||||
FCalls::plan_type analysis_plan;
|
||||
FlatIntType *flat_keys;
|
||||
MFCalls::real_type *tmp_s;
|
||||
|
||||
void base_init();
|
||||
public:
|
||||
PowerSpectrumSampler_a(MPI_Communication *comm);
|
||||
virtual ~PowerSpectrumSampler_a();
|
||||
|
||||
virtual void restore(MarkovState& state);
|
||||
virtual void initialize(MarkovState& state);
|
||||
virtual void sample(MarkovState& state);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
217
libLSS/samplers/ares/powerspectrum_b_sampler.cpp
Normal file
217
libLSS/samplers/ares/powerspectrum_b_sampler.cpp
Normal file
|
@ -0,0 +1,217 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/powerspectrum_b_sampler.cpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#include <CosmoTool/algo.hpp>
|
||||
#include <cmath>
|
||||
#include "libLSS/tools/console.hpp"
|
||||
#include "libLSS/mcmc/state_element.hpp"
|
||||
#include "libLSS/samplers/core/powerspec_tools.hpp"
|
||||
#include "libLSS/samplers/ares/powerspectrum_b_sampler.hpp"
|
||||
#include "libLSS/tools/mpi_fftw_helper.hpp"
|
||||
|
||||
using boost::format;
|
||||
using namespace LibLSS;
|
||||
|
||||
PowerSpectrumSampler_b::PowerSpectrumSampler_b(MPI_Communication *comm0)
|
||||
: PowerSpectrumSampler_Coloring(comm0),
|
||||
tmp_fourier(0), P0_array(boost::extents[0]), P1_array(boost::extents[0]),
|
||||
tmp_x(0), tmp_t(0), total_accepted(0), total_tried(0), flat_keys(0)
|
||||
{
|
||||
}
|
||||
|
||||
PowerSpectrumSampler_b::~PowerSpectrumSampler_b()
|
||||
{
|
||||
if (tmp_fourier) {
|
||||
Console::instance().print<LOG_INFO>("Cleaning up Powerspectrum sampler (b)");
|
||||
Console::instance().print<LOG_DEBUG>(format("tmp_fourier=%p tmp_fourier=%p") % tmp_fourier % tmp_fourier_t);
|
||||
|
||||
FCalls::free(tmp_fourier);
|
||||
FCalls::free(tmp_fourier_t);
|
||||
FCalls::destroy_plan(analysis_plan);
|
||||
}
|
||||
if (tmp_x)
|
||||
MFCalls::free(tmp_x);
|
||||
if (tmp_t)
|
||||
MFCalls::free(tmp_t);
|
||||
if (flat_keys)
|
||||
delete flat_keys;
|
||||
}
|
||||
|
||||
void PowerSpectrumSampler_b::base_init(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_DEBUG> ctx("base init");
|
||||
|
||||
ctx.print(boost::format("Allocating Fourier buffer %dx%dx%d (sz=%d)") % localN0 % N1 % N2_HC % fourierLocalSize);
|
||||
tmp_fourier = MFCalls::alloc_complex(fourierLocalSize);
|
||||
tmp_fourier_t = MFCalls::alloc_complex(fourierLocalSize);
|
||||
tmp_x = MFCalls::alloc_real(2*fourierLocalSize);
|
||||
tmp_t = MFCalls::alloc_real(2*fourierLocalSize);
|
||||
P0_array.resize(boost::extents[N_k]);
|
||||
P1_array.resize(boost::extents[N_k]);
|
||||
|
||||
ctx.print(boost::format("Fourier buffer %p") % tmp_fourier);
|
||||
ctx.print(boost::format("Allocating plan %dx%dx%d") % N0 % N1 % N2);
|
||||
analysis_plan = MFCalls::plan_dft_r2c_3d(
|
||||
N0, N1, N2,
|
||||
tmp_x,
|
||||
tmp_fourier,
|
||||
#ifdef ARES_MPI_FFTW
|
||||
comm->comm(),
|
||||
#endif
|
||||
//FFTW_MPI_TRANSPOSED_OUT|
|
||||
FFTW_DESTROY_INPUT|FFTW_MEASURE);
|
||||
|
||||
flat_keys = new FlatIntType(keys->array->data(), boost::extents[keys->array->num_elements()] );
|
||||
|
||||
state.newElement("sampler_b_accepted", new SLong());
|
||||
state.newElement("sampler_b_tried", new SLong());
|
||||
}
|
||||
|
||||
void PowerSpectrumSampler_b::restore(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_INFO> ctx("restoration of power spectrum sampler (b)");
|
||||
|
||||
ctx.print("Restoring power spectrum sampler (b)");
|
||||
|
||||
restore_base(state);
|
||||
restore_coloring(state);
|
||||
|
||||
base_init(state);
|
||||
|
||||
}
|
||||
|
||||
void PowerSpectrumSampler_b::initialize(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_INFO> ctx("initialization of power spectrum sampler (b)");
|
||||
Console& cons = Console::instance();
|
||||
|
||||
initialize_base(state);
|
||||
initialize_coloring(state);
|
||||
base_init(state);
|
||||
|
||||
state.get<SLong>("sampler_b_accepted")->value = 0;
|
||||
state.get<SLong>("sampler_b_tried")->value = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PowerSpectrumSampler_b::sample(MarkovState& state)
|
||||
{
|
||||
// Grab the messenger field
|
||||
ConsoleContext<LOG_DEBUG> ctx("sampling of power spectrum (b)");
|
||||
Console& cons = Console::instance();
|
||||
ArrayType& x_field = static_cast<ArrayType&>(state["x_field"]);
|
||||
ArrayType& t_field = static_cast<ArrayType&>(state["messenger_field"]);
|
||||
RandomGen *rng = state.get<RandomGen>("random_generator");
|
||||
IArrayType1d::ArrayType& nmode_array = *nmode->array;
|
||||
ArrayType1d::ArrayType& P_array = *P->array;
|
||||
SDouble *messenger_tau = state.get<SDouble>("messenger_tau");
|
||||
double tau = messenger_tau->value;
|
||||
long localNtot = localN0*N1*N2;
|
||||
|
||||
if (state.get<SBool>("power_sampler_b_blocked")->value)
|
||||
return;
|
||||
|
||||
#ifdef ARES_MPI_FFTW
|
||||
copy_padded_data(*x_field.array, tmp_x);
|
||||
copy_padded_data(*t_field.array, tmp_t);
|
||||
#else
|
||||
::memcpy(tmp_x, x_field.array->data(), Ntot * sizeof(MFCalls::real_type));
|
||||
::memcpy(tmp_t, t_field.array->data(), Ntot * sizeof(MFCalls::real_type));
|
||||
#endif
|
||||
|
||||
ctx.print("Fourier analysis (1)");
|
||||
MFCalls::execute(analysis_plan);
|
||||
ctx.print("Fourier analysis (2)");
|
||||
MFCalls::execute_r2c(analysis_plan, tmp_t, tmp_fourier_t);
|
||||
|
||||
ctx.print("Compute inverse-gamma parameter");
|
||||
|
||||
ctx.print(boost::format("local_fourier_elements = %d") % local_fourier_elements);
|
||||
int *adjust = adjustMul->array->data();
|
||||
|
||||
std::fill(P0_array.begin(), P0_array.end(), 0);
|
||||
std::fill(P1_array.begin(), P1_array.end(), 0);
|
||||
|
||||
//#pragma omp parallel for schedule(static)
|
||||
for (long i = 0; i < local_fourier_elements; i++) {
|
||||
FCalls::complex_type& x_hat = tmp_fourier[i];
|
||||
FCalls::complex_type& t_hat = tmp_fourier_t[i];
|
||||
double Pelt_cross = x_hat[0]*t_hat[0] + x_hat[1]*t_hat[1];
|
||||
double Pelt_auto = x_hat[0]*x_hat[0] + x_hat[1]*x_hat[1];
|
||||
|
||||
// adjust increase memory bandwidth consumption. Not great...
|
||||
// OTOH it is very convenient and this loop is not the most time consuming aspect
|
||||
P0_array[ (*flat_keys)[i] ] += adjust[i] * Pelt_cross;
|
||||
P1_array[ (*flat_keys)[i] ] += adjust[i] * Pelt_auto;
|
||||
}
|
||||
|
||||
// No helper function written here. Ask MPI to reduce the arrays in-place.
|
||||
comm->all_reduce_t(MPI_IN_PLACE, P0_array.data(), P0_array.num_elements(),
|
||||
MPI_SUM);
|
||||
comm->all_reduce_t(MPI_IN_PLACE, P1_array.data(), P1_array.num_elements(),
|
||||
MPI_SUM);
|
||||
|
||||
int accepted = 0, tried = 0;
|
||||
double normalization = tau * Ntot;
|
||||
|
||||
if (comm->rank() == 0) {
|
||||
ctx.print("Accumulated, now create plausible sample");
|
||||
#pragma omp parallel for schedule(static) reduction(+:accepted,tried)
|
||||
for (int i = 0; i < N_k; i++) {
|
||||
if (P1_array[i] > 0) {
|
||||
double s = 1/P1_array[i];
|
||||
P0_array[i] *= s;
|
||||
P1_array[i] = sqrt(s * normalization);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
double u0 = sqrt(P_array[i] * volume);
|
||||
double u1 = -1;
|
||||
double mean = P0_array[i];
|
||||
double sigma = P1_array[i];
|
||||
assert(!std::isnan(u0));
|
||||
assert(!std::isnan(mean));
|
||||
assert(!std::isnan(sigma));
|
||||
ctx.print(format(" k = %lg, mean = %lg, sigma = %lg") % (*k->array)[i]% mean % sigma);
|
||||
if (mean < 0) mean = 0;
|
||||
while(u1 < 0)
|
||||
u1 = mean + sigma*rng->get().gaussian(); ///NOTE: sample from truncated Gaussian
|
||||
|
||||
double PA = u1/u0;
|
||||
if(PA>1.)
|
||||
PA=1.;
|
||||
|
||||
double u = rng->get().uniform();
|
||||
if (u < PA) {
|
||||
P_array[i] = u1*u1 / volume;
|
||||
accepted++;
|
||||
}
|
||||
tried++;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.print("Broadcast data");
|
||||
P_sync.mpiBroadcast(*comm);
|
||||
|
||||
total_accepted += accepted;
|
||||
total_tried += tried;
|
||||
|
||||
// Force update s_field with the new P
|
||||
update_s_field_from_x(state);
|
||||
|
||||
state.get<SLong>("sampler_b_accepted")->value = total_accepted;
|
||||
state.get<SLong>("sampler_b_tried")->value = total_tried;
|
||||
|
||||
if (comm->rank() == 0)
|
||||
Console::instance().print<LOG_VERBOSE>(format("PSpec sampler (b) total acceptance ratio: %2.0f %%") % (double(total_accepted)*100/total_tried));
|
||||
}
|
||||
|
||||
|
44
libLSS/samplers/ares/powerspectrum_b_sampler.hpp
Normal file
44
libLSS/samplers/ares/powerspectrum_b_sampler.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/powerspectrum_b_sampler.hpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#ifndef __LIBLSS_POWERSPECTRUM_B_SAMPLER_HPP
|
||||
#define __LIBLSS_POWERSPECTRUM_B_SAMPLER_HPP
|
||||
|
||||
#include "libLSS/mpi/generic_mpi.hpp"
|
||||
#include "libLSS/samplers/core/markov.hpp"
|
||||
#include "libLSS/samplers/core/types_samplers.hpp"
|
||||
#include "libLSS/samplers/core/powerspec_tools.hpp"
|
||||
|
||||
namespace LibLSS {
|
||||
|
||||
class PowerSpectrumSampler_b: public PowerSpectrumSampler_Coloring {
|
||||
protected:
|
||||
typedef boost::multi_array_ref< IArrayType::ArrayType::element, 1> FlatIntType;
|
||||
|
||||
MFCalls::complex_type *tmp_fourier, *tmp_fourier_t;
|
||||
MFCalls::real_type *tmp_x, *tmp_t;
|
||||
MFCalls::plan_type analysis_plan;
|
||||
FlatIntType *flat_keys;
|
||||
int total_accepted, total_tried;
|
||||
|
||||
ArrayType1d::ArrayType P0_array, P1_array;
|
||||
|
||||
void base_init(MarkovState& state);
|
||||
public:
|
||||
PowerSpectrumSampler_b(MPI_Communication *comm);
|
||||
virtual ~PowerSpectrumSampler_b();
|
||||
|
||||
virtual void restore(MarkovState& state);
|
||||
virtual void initialize(MarkovState& state);
|
||||
virtual void sample(MarkovState& state);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
196
libLSS/samplers/ares/powerspectrum_c_sampler.cpp
Normal file
196
libLSS/samplers/ares/powerspectrum_c_sampler.cpp
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/powerspectrum_c_sampler.cpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <CosmoTool/algo.hpp>
|
||||
#include <functional>
|
||||
#include <cmath>
|
||||
#include "libLSS/tools/console.hpp"
|
||||
#include "libLSS/mcmc/state_element.hpp"
|
||||
#include "libLSS/samplers/core/powerspec_tools.hpp"
|
||||
#include "libLSS/samplers/ares/powerspectrum_c_sampler.hpp"
|
||||
#include "libLSS/tools/mpi_fftw_helper.hpp"
|
||||
#include "libLSS/samplers/rgen/slice_sweep.hpp"
|
||||
#include "libLSS/samplers/ares/ares_bias.hpp"
|
||||
|
||||
static const int ROOT = 0;
|
||||
static const size_t LARGE_SCALE_MODE_COUNT=14;
|
||||
|
||||
using boost::format;
|
||||
using namespace LibLSS;
|
||||
using LibLSS::ARES::extract_bias;
|
||||
namespace ph = std::placeholders;
|
||||
|
||||
PowerSpectrumSampler_c::PowerSpectrumSampler_c(MPI_Communication *comm0)
|
||||
: PowerSpectrumSampler_Coloring(comm0), counter_evaluations(0)
|
||||
{
|
||||
}
|
||||
|
||||
PowerSpectrumSampler_c::~PowerSpectrumSampler_c()
|
||||
{
|
||||
}
|
||||
|
||||
void PowerSpectrumSampler_c::base_init(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_DEBUG> ctx("base init");
|
||||
|
||||
Ncatalog = state.get<SLong>("NCAT")->value;
|
||||
localNtot = localN0 * N1 * N2;
|
||||
|
||||
// Create a counter reinitialized at each save that look at the number of posterior evaluation
|
||||
// required for each mode
|
||||
counter_evaluations = new IArrayType1d(boost::extents[P->array->num_elements()]);
|
||||
state.newElement("spectrum_c_eval_counter", counter_evaluations, true);
|
||||
counter_evaluations->setResetOnSave(0);
|
||||
counter_evaluations->fill(0);
|
||||
|
||||
sigma_init = new ArrayType1d(boost::extents[P->array->num_elements()]);
|
||||
state.newElement("spectrum_c_init_sigma", sigma_init);
|
||||
sigma_init->fill(0);
|
||||
}
|
||||
|
||||
void PowerSpectrumSampler_c::restore(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_INFO> ctx("restoration of power spectrum sampler (b)");
|
||||
|
||||
ctx.print("Restoring power spectrum sampler (b)");
|
||||
|
||||
restore_base(state);
|
||||
restore_coloring(state);
|
||||
|
||||
base_init(state);
|
||||
|
||||
init_sampler = false;
|
||||
}
|
||||
|
||||
void PowerSpectrumSampler_c::initialize(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_INFO> ctx("initialization of power spectrum sampler (c)");
|
||||
Console& cons = Console::instance();
|
||||
|
||||
initialize_base(state);
|
||||
initialize_coloring(state);
|
||||
base_init(state);
|
||||
|
||||
init_sampler = true;
|
||||
}
|
||||
|
||||
|
||||
double PowerSpectrumSampler_c::log_likelihood(MarkovState& state, int k, double P_trial)
|
||||
{
|
||||
// Reuse system power spectrum
|
||||
//
|
||||
if (P_trial < 0)
|
||||
return -std::numeric_limits<double>::infinity();
|
||||
|
||||
(*P->array)[k] = P_trial;
|
||||
update_s_field_from_x(state, (*P));
|
||||
|
||||
// Now compute full likelihood
|
||||
double *s = state.get<ArrayType>("s_field")->array->data();
|
||||
double heat = state.getScalar<double>("ares_heat");
|
||||
|
||||
double L = 0, loc_L = 0;
|
||||
for (int c = 0; c < Ncatalog; c++) {
|
||||
double Lc = 0;
|
||||
SelArrayType& sel_field = *state.get<SelArrayType>(format("galaxy_synthetic_sel_window_%d") % c);
|
||||
ArrayType& g_field = *state.get<ArrayType>(format("galaxy_data_%d") % c);
|
||||
double bias = extract_bias(state, c);
|
||||
double nmean = state.get<SDouble>(format("galaxy_nmean_%d") % c)->value;
|
||||
double *R = sel_field.array->data();
|
||||
double *gdata = g_field.array->data();
|
||||
|
||||
//#pragma omp simd aligned(s,R,gdata)
|
||||
#pragma omp parallel for schedule(static) reduction(+:Lc)
|
||||
for (long i = 0; i < localNtot; i++) {
|
||||
if (R[i] <= 0)
|
||||
continue;
|
||||
Lc += CosmoTool::square(gdata[i] - nmean * R[i] * (1 + bias * s[i])) / (R[i]*nmean);
|
||||
}
|
||||
|
||||
loc_L += Lc;
|
||||
}
|
||||
|
||||
comm->reduce_t(&loc_L, &L, 1, MPI_SUM, ROOT);
|
||||
// if (comm->rank() == 0)
|
||||
// Console::instance().print<LOG_INFO>(format("Likelihood(P=%lg) = %lg") % P_trial % L);
|
||||
|
||||
// o << format("%15.15lg %15.15lg")%P_trial %L<< std::endl;
|
||||
|
||||
(*counter_evaluations->array)[k]++;
|
||||
return -0.5*heat*L - std::log(P_trial);
|
||||
}
|
||||
|
||||
void PowerSpectrumSampler_c::sample(MarkovState& state)
|
||||
{
|
||||
// Grab the messenger field
|
||||
ConsoleContext<LOG_INFO_SINGLE> ctx("sampling of power spectrum (c)");
|
||||
Console& cons = Console::instance();
|
||||
ArrayType& x_field = static_cast<ArrayType&>(state["x_field"]);
|
||||
RandomGen *rng = state.get<RandomGen>("random_generator");
|
||||
IArrayType1d::ArrayType& nmode_array = *nmode->array;
|
||||
ArrayType1d::ArrayType& P_array = *P->array;
|
||||
long localNtot = localN0*N1*N2;
|
||||
long step = state.get<SLong>("MCMC_STEP")->value;
|
||||
|
||||
if (state.get<SBool>("power_sampler_c_blocked")->value)
|
||||
return;
|
||||
if ((step % 10) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.print("Fourier analysis (1)");
|
||||
copy_padded_data(*x_field.array, tmp_real);
|
||||
|
||||
MFCalls::execute_r2c(analysis_plan, tmp_real, tmp_fourier);
|
||||
|
||||
int *counts = key_counts->array->data();
|
||||
|
||||
ArrayType1d::ArrayType& sigma_init_array = *sigma_init->array;
|
||||
if (init_sampler) {
|
||||
ctx.print("initial guess for the step for slice sampler...");
|
||||
for (long i = 0 ; i < P_array.size() ; i++) {
|
||||
if (counts[i] == 0)
|
||||
sigma_init_array[i] = 0;
|
||||
else
|
||||
sigma_init_array[i] = (P_array[i]) / std::sqrt(double(counts[i]));
|
||||
}
|
||||
init_sampler = false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < std::min(LARGE_SCALE_MODE_COUNT, P_array.size()); i++) {
|
||||
// std::string fname = str(format("P_k_%d.txt") % i);
|
||||
// std::ofstream f(fname.c_str());
|
||||
// Skip zero mode
|
||||
if (counts[i] == 0)
|
||||
continue;
|
||||
|
||||
double cosmic_var = sigma_init_array[i];
|
||||
ctx.print(format("Finding P_array(k=%d / %d) cvar=%g") % i % P_array.size() % cosmic_var);
|
||||
|
||||
auto posterior_fun =
|
||||
std::bind(&PowerSpectrumSampler_c::log_likelihood,
|
||||
this, boost::ref(state), i, ph::_1);
|
||||
|
||||
// We need the slice_sweep_double algo here. Cosmic var tends to quite underestimate
|
||||
// the width of the posterior
|
||||
if (cosmic_var >0)
|
||||
P_array[i] =
|
||||
slice_sweep_double(comm, rng->get(),
|
||||
posterior_fun,
|
||||
P_array[i], cosmic_var);
|
||||
|
||||
comm->broadcast_t(&P_array[i], 1, ROOT);
|
||||
}
|
||||
|
||||
update_s_field_from_x(state);
|
||||
|
||||
}
|
47
libLSS/samplers/ares/powerspectrum_c_sampler.hpp
Normal file
47
libLSS/samplers/ares/powerspectrum_c_sampler.hpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/powerspectrum_c_sampler.hpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#ifndef __LIBLSS_POWERSPECTRUM_C_SAMPLER_HPP
|
||||
#define __LIBLSS_POWERSPECTRUM_C_SAMPLER_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include "libLSS/mpi/generic_mpi.hpp"
|
||||
#include "libLSS/samplers/core/markov.hpp"
|
||||
#include "libLSS/samplers/core/types_samplers.hpp"
|
||||
#include "libLSS/samplers/core/powerspec_tools.hpp"
|
||||
|
||||
namespace LibLSS {
|
||||
|
||||
class PowerSpectrumSampler_c: public PowerSpectrumSampler_Coloring {
|
||||
protected:
|
||||
typedef boost::multi_array_ref< IArrayType::ArrayType::element, 1> FlatIntType;
|
||||
|
||||
long localNtot;
|
||||
int total_accepted, total_tried;
|
||||
|
||||
bool init_sampler;
|
||||
IArrayType1d *counter_evaluations;
|
||||
ArrayType1d *sigma_init;
|
||||
|
||||
void base_init(MarkovState& state);
|
||||
|
||||
double log_likelihood(MarkovState& state, int k, double P_trial);
|
||||
|
||||
public:
|
||||
PowerSpectrumSampler_c(MPI_Communication *comm);
|
||||
virtual ~PowerSpectrumSampler_c();
|
||||
|
||||
virtual void restore(MarkovState& state);
|
||||
virtual void initialize(MarkovState& state);
|
||||
virtual void sample(MarkovState& state);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
102
libLSS/samplers/ares/synthetic_selection.cpp
Normal file
102
libLSS/samplers/ares/synthetic_selection.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/synthetic_selection.cpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#include <boost/format.hpp>
|
||||
#include "libLSS/tools/errors.hpp"
|
||||
#include "libLSS/samplers/core/gig_sampler.hpp"
|
||||
#include "libLSS/samplers/ares/synthetic_selection.hpp"
|
||||
#include "libLSS/tools/fused_array.hpp"
|
||||
#include "libLSS/tools/fused_assign.hpp"
|
||||
|
||||
using namespace LibLSS;
|
||||
using boost::format;
|
||||
|
||||
using boost::extents;
|
||||
|
||||
typedef boost::multi_array_types::extent_range range;
|
||||
|
||||
|
||||
void SyntheticSelectionUpdater::initialize(MarkovState& state)
|
||||
{
|
||||
long N0, N1, N2;
|
||||
long localN0, startN0;
|
||||
long localNdata[6], Ndata[3];
|
||||
|
||||
ConsoleContext<LOG_DEBUG> ctx("initialization of Selection updater");
|
||||
|
||||
Ncat = static_cast<SLong&>(state["NCAT"]);
|
||||
|
||||
N0 = static_cast<SLong&>(state["N0"]);
|
||||
localN0 = static_cast<SLong&>(state["localN0"]);
|
||||
startN0 = static_cast<SLong&>(state["startN0"]);
|
||||
N1 = static_cast<SLong&>(state["N1"]);
|
||||
N2 = static_cast<SLong&>(state["N2"]);
|
||||
state.getScalarArray<long,3>("Ndata", Ndata);
|
||||
state.getScalarArray<long,6>("localNdata", localNdata);
|
||||
|
||||
Ntot = N0*N1*N2;
|
||||
localNtot = localN0*N1*N2;
|
||||
|
||||
for (int c = 0; c < Ncat; c++) {
|
||||
SelArrayType *sel_window;
|
||||
state.newElement(format("galaxy_synthetic_sel_window_%d") % c,
|
||||
sel_window = new SelArrayType(extents[range(localNdata[0],localNdata[1])][range(localNdata[2],localNdata[3])][range(localNdata[4],localNdata[5])]));
|
||||
|
||||
sel_window->setRealDims(ArrayDimension(Ndata[0], Ndata[1], Ndata[2]));
|
||||
}
|
||||
}
|
||||
|
||||
void SyntheticSelectionUpdater::restore(MarkovState& state)
|
||||
{
|
||||
initialize(state);
|
||||
}
|
||||
|
||||
void SyntheticSelectionUpdater::sample(MarkovState& state)
|
||||
{
|
||||
ConsoleContext<LOG_VERBOSE> ctx("processing of 3d selection (including foregrounds)");
|
||||
|
||||
for (int c = 0; c < Ncat; c++) {
|
||||
SelArrayType *original_selection_grid = state.get<SelArrayType>(format("galaxy_sel_window_%d") % c);
|
||||
SelArrayType *sel_grid = state.get<SelArrayType>(format("galaxy_synthetic_sel_window_%d") % c);
|
||||
IArrayType1d *fgmap = state.get<IArrayType1d>(format("catalog_foreground_maps_%d") % c);
|
||||
ArrayType1d *fgvals = state.get<ArrayType1d>(format("catalog_foreground_coefficient_%d") % c);
|
||||
int NcatForegrounds = fgmap->array->num_elements();
|
||||
|
||||
ctx.format("Copy initial selection for catalog %d", c);
|
||||
sel_grid->eigen() = original_selection_grid->eigen();
|
||||
|
||||
for (int f = 0; f < NcatForegrounds; f++) {
|
||||
int c = (*fgmap->array)[f];
|
||||
double val = (*fgvals->array)[f];
|
||||
|
||||
ctx.print(format("Applying foreground %d (value %lg) to selection of catalog %d") % f % val % c);
|
||||
|
||||
ArrayType *fgField = state.get<ArrayType>(format("foreground_3d_%d") % (c));
|
||||
|
||||
auto mergingFunction = [val](double s,double f) { return s*(1 - f * val); };
|
||||
|
||||
// copy_array is parallelized, hopefully later vectorized
|
||||
if (f == 0) {
|
||||
LibLSS::copy_array(*sel_grid->array,
|
||||
b_fused<double>(*original_selection_grid->array,
|
||||
*fgField->array,
|
||||
mergingFunction
|
||||
)
|
||||
);
|
||||
} else {
|
||||
LibLSS::copy_array(*sel_grid->array,
|
||||
b_fused<double>(*sel_grid->array,
|
||||
*fgField->array,
|
||||
mergingFunction
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
33
libLSS/samplers/ares/synthetic_selection.hpp
Normal file
33
libLSS/samplers/ares/synthetic_selection.hpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*+
|
||||
ARES/HADES/BORG Package -- ./libLSS/samplers/ares/synthetic_selection.hpp
|
||||
Copyright (C) 2014-2020 Guilhem Lavaux <guilhem.lavaux@iap.fr>
|
||||
Copyright (C) 2009-2020 Jens Jasche <jens.jasche@fysik.su.se>
|
||||
|
||||
Additional contributions from:
|
||||
Guilhem Lavaux <guilhem.lavaux@iap.fr> (2023)
|
||||
|
||||
+*/
|
||||
#ifndef __LIBLSS_SYNTHETIC_SELECTION_UPDATER_HPP
|
||||
#define __LIBLSS_SYNTHETIC_SELECTION_UPDATER_HPP
|
||||
|
||||
#include <boost/multi_array.hpp>
|
||||
#include "libLSS/samplers/core/markov.hpp"
|
||||
#include "libLSS/samplers/core/types_samplers.hpp"
|
||||
|
||||
namespace LibLSS {
|
||||
|
||||
class SyntheticSelectionUpdater: public MarkovSampler {
|
||||
protected:
|
||||
int Ncat;
|
||||
long Ntot, localNtot;
|
||||
public:
|
||||
|
||||
virtual void initialize(MarkovState& state);
|
||||
virtual void restore(MarkovState& state);
|
||||
virtual void sample(MarkovState& state);
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue