48 m_cell_size = cell_size;
53 m_Lim.resize(m_nDim, vector<double> (2,0));
54 m_Delta.resize(m_nDim);
55 m_nCell.resize(m_nDim);
56 m_cell_to_index.resize(m_nDim);
75 vector<long> indx(m_nDim);
77 for (
long j=0; j<m_nDim; j++)
78 indx[j] = min(
long((center[j]-m_Lim[j][0])/m_cell_size), m_nCell[j]-1);
80 long indx_tot = indx[m_nDim-1];
82 for (
long j=m_nDim-2; j>-1; j--) {
84 for (
long k=j+1; k<m_nDim; k++) mult *= m_nCell[k];
85 indx_tot += mult*indx[j];
97 long indx_tot = indx[m_nDim-1];
99 for (
int j=m_nDim-2; j>-1; j--) {
101 for (
int k=j+1; k<m_nDim; k++) mult *= m_nCell[k];
102 indx_tot += mult*indx[j];
114 indx.resize(m_nDim, 0);
117 for (
int i=1; i<m_nDim; i++) mult *= nn[i];
118 indx[0] = floor((index-sum)/mult);
121 for (
int i=1; i<m_nDim; i++) {
123 for (
int k=i+1; k<m_nDim; k++) mult *= nn[k];
124 indx[i] = floor((index-sum)/mult);
140 long nObj = data[0].size();
141 m_List.erase(m_List.begin(), m_List.end()); m_List.resize(nObj, -1);
142 m_NonEmpty_Cells.erase(m_NonEmpty_Cells.begin(), m_NonEmpty_Cells.end());
144 m_nCell_tot = pow(nMAX,3)+1;
145 m_nCell_NonEmpty = 0;
146 m_multCell.erase(m_multCell.begin(), m_multCell.end()); m_multCell.resize(m_nDim, 1);
150 check_memory(3.0,
true,
"cbl::chainmesh::ChainMesh::create_chain_mesh of ChainMesh.cpp");
152 while (m_nCell_tot>pow(nMAX, 3) || m_nCell_tot<nMIN
153 || !
check_memory(3.0,
false,
"cbl::chainmesh::ChainMesh::create_chain_mesh of ChainMesh.cpp")) {
157 for (
int i=0; i<m_nDim; i++) {
158 m_Lim[i][0] =
Min(data[i])-1.05*rMAX;
159 m_Lim[i][1] =
Max(data[i])+1.05*rMAX;
160 m_Delta[i] = m_Lim[i][1]-m_Lim[i][0];
161 m_nCell[i] =
nint(m_Delta[i]/m_cell_size);
162 m_nCell_tot *= m_nCell[i];
163 m_cell_to_index[i] = m_Delta[i]/m_nCell[i];
165 for (
int i=1; i<m_nDim; i++)
166 m_multCell[m_nDim-1-i] = m_nCell[m_nDim-i]*m_multCell[i-1];
170 m_Label.erase(m_Label.begin(), m_Label.end());
174 m_Label.resize(m_nCell_tot, -1);
176 for (
long i=0; i<nObj; i++) {
177 vector<double> center(m_nDim);
178 for (
int j=0; j<m_nDim; j++)
179 center[j] = data[j][i];
180 long indx_tot = pos_to_index(center);
181 m_NonEmpty_Cells.push_back(indx_tot);
182 m_List[i] = m_Label[indx_tot];
183 m_Label[indx_tot] = i;
186 get_searching_region(rMAX, rMIN);
188 m_nCell_NonEmpty = (long)m_NonEmpty_Cells.size();
199 long nObj = data[0].size();
201 for (
int i=0; i<m_nDim; i++) {
202 m_Lim[i][0] =
Min(data[i]); m_Lim[i][1] =
Max(data[i]);
203 m_Delta[i] = m_Lim[i][1]-m_Lim[i][0];
204 m_nCell[i] =
nint(m_Delta[i]/m_cell_size);
205 m_nCell_tot *= m_nCell[i];
208 m_List_index.erase(m_List_index.begin(),m_List_index.end()); m_List_index.resize(m_nCell_tot);
209 m_NonEmpty_Cells.erase(m_NonEmpty_Cells.begin(), m_NonEmpty_Cells.end());
210 m_nCell_NonEmpty = 0;
212 for (
long i=0; i<nObj; i++) {
213 long indx_tot = pos_to_index(data[i]);
214 m_NonEmpty_Cells.push_back(indx_tot);
215 m_List_index[indx_tot].push_back(i);
219 m_nCell_NonEmpty = (long)m_NonEmpty_Cells.size();
229 int n_max =
nint(r_max/m_cell_size);
230 n_max = (n_max*m_cell_size<r_max) ? n_max+1 : n_max;
232 int n_min =
nint(r_min/m_cell_size)-2;
233 vector<long> n_incl(m_nDim);
235 for (
int i=0; i<m_nDim; i++)
236 n_incl[i] = 2*n_max+1;
238 long sz_region = pow(2*n_max+1, m_nDim);
240 m_search_region.erase(m_search_region.begin(),m_search_region.end());
241 m_search_region.resize(sz_region,0);
243 for (
long i=0; i<sz_region; i++) {
244 vector<long> indx(m_nDim);
245 index_to_inds(i,n_incl,indx);
246 for (
int i=0; i<m_nDim; i++) indx[i]-=n_max;
247 m_search_region[i] = inds_to_index(indx);
250 if (r_min>0 && n_min>0) {
251 vector<long> n_excl(m_nDim);
252 for (
int i=0; i<m_nDim; i++)
253 n_excl[i] = 2*n_min+1;
255 long sz_excl_region = pow(2*n_min+1,m_nDim);
257 for (
long i=0; i<sz_excl_region; i++) {
258 vector<long> indx(m_nDim);
259 index_to_inds(i, n_excl, indx);
260 for (
int i=0; i<m_nDim; i++) indx[i] -= n_min;
261 long veto = inds_to_index(indx);
262 m_search_region.erase(remove(m_search_region.begin(), m_search_region.end(), veto), m_search_region.end());
278 for (
size_t i=0; i<m_search_region.size(); i++) {
280 long k = min(max(m_search_region[i]+cell_index, (
long)0), m_nCell_tot-1);
302 if (
long(center.size())!=m_nDim)
ErrorCBL(
"point must have same dimensions of the chain-mesh",
"close_objects",
"ChainMesh.cpp");
304 long center_indx = pos_to_index(center);
306 for (
unsigned long i=0; i<m_search_region.size(); i++) {
308 long k = min(max(m_search_region[i]+center_indx, (
long)0), m_nCell_tot-1);
312 if (m_cell_size>=m_rMAX/m_nDim) {
313 vector<int> indx(m_nDim, 0);
315 for (
int ii=0; ii<m_nDim; ii++) {
316 indx[ii] = floor(k/m_multCell[ii]);
317 k -= m_multCell[ii]*indx[ii];
321 for (
int ii=0; ii<m_nDim; ii++)
322 dist += ((indx[ii]+0.5)*m_cell_size-center[ii]+m_Lim[ii][0])*((indx[ii]+0.5)*m_cell_size-center[ii]+m_Lim[ii][0]);
326 double half_diag = m_cell_size*0.5*sqrt(m_nDim);
327 double max_radius = m_rMAX+half_diag;
328 double min_radius = (m_rMIN>0.) ? m_rMIN-half_diag : 0.;
330 if (dist<max_radius && dist>min_radius)
331 while (j>-1 && j>ii) {
337 while (j>-1 && j>ii) {
351 if (points[0].size()!=values.size())
ErrorCBL(
"the size of points is different from the size of values",
"norm_grid",
"ChainMesh.cpp");
353 const int nparams = points.size();
358 std::vector<std::vector<double>> extremals(2, std::vector<double> (nparams, 0));
359 std::vector<double> delta (nparams, 0.);
361 for(
int N=0; N<nparams; N++) {
362 extremals[0][N] =
cbl::Max(points[N]);
363 extremals[1][N] =
cbl::Min(points[N]);
366 for(
int N=0; N<nparams; N++) {
367 delta[N] = extremals[0][N]-extremals[1][N];
368 if (delta[N]==0)
ErrorCBL(
"the grid cannot be normalised",
"norm_grid",
"ChainMesh.cpp");
369 for(
size_t ii=0; ii<points[0].size(); ii++){
370 points[N][ii] = 100. - (200./(delta[N]))*(extremals[0][N] - points[N][ii]);
376 m_extremals = extremals;
378 long nMAX = floor(200/m_cell_size)+10*rMAX;
380 create_chain_mesh(m_points, m_rMAX, -1., nMAX, 0);
389 if (m_points.size() != xi.size())
ErrorCBL(
"the dimension of points is different from the dimension of xi",
"interp_coord",
"ChainMesh.cpp");
390 if (m_delta.size()==0.)
ErrorCBL(
"the chain mesh grid is not normalised!",
"interp_coord",
"ChainMesh.cpp");
392 const int nparams = m_points.size();
395 for (
int N=0; N<nparams; N++)
396 xi[N] = 100. - (200./(m_delta[N]))*(m_extremals[0][N] - xi[N]);
398 double interp_value =
cbl::Min(m_values);
399 std::vector<long> close;
400 std::vector<double> distances;
401 std::vector<double> indices;
402 double dist, sum = 0.;
403 double sum_distances = 0.;
406 close = close_objects(xi);
408 if (close.size()>0) {
409 for (
auto&&k : close) {
411 for(
int N=0; N<nparams; N++)
412 dist += pow((xi[N]-m_points[N][k]), 2);
414 distances.push_back(dist);
415 indices.push_back(k);
420 for (
auto&&k : indices) {
421 if (distances[npoints]>0.) {
422 sum += m_values[k]/distances[npoints];
423 sum_distances += 1./distances[npoints];
426 if (npoints>distNum)
break;
429 interp_value = sum/sum_distances;
444 if (points.size() != xi.size())
ErrorCBL(
"the dimension of points is different from the dimension of xi",
"interpolate",
"ChainMesh.cpp");
445 if (points[0].size() != values.size())
ErrorCBL(
"the size of points is different from the size of values",
"interpolate",
"ChainMesh.cpp");
447 const int nparams = points.size();
448 const int points_values = points[0].size();
449 const int xi_values = xi[0].size();
450 std::vector<std::vector<double>> unique_vect(nparams, std::vector<double> (points_values+xi_values, 0));
452 std::vector<std::vector<double>> extremals(2, std::vector<double> (nparams, 0));
454 for (
int N=0; N<nparams; N++) {
459 for (
int N=0; N<nparams; N++){
460 delta = extremals[0][N]-extremals[1][N];
462 for (
int ii=0; ii<xi_values; ii++) {
463 xi[N][ii] = 100. - (200./(delta))*(extremals[0][N] - xi[N][ii]);
464 unique_vect[N][ii] = xi[N][ii];
467 for (
int ii=0; ii<points_values; ii++) {
468 points[N][ii] = 100. - (200./(delta))*(extremals[0][N] - points[N][ii]);
469 unique_vect[N][xi_values+ii] = points[N][ii];
474 long nMAX = floor(200/m_cell_size)+10*rMAX;
476 std::vector<double> interp_values(xi_values,
cbl::Min(values));
478 create_chain_mesh(unique_vect, rMAX, -1., nMAX, 0);
480 #pragma omp parallel num_threads(omp_get_max_threads())
482 std::vector<double> center(nparams);
483 std::vector<long> close;
484 std::vector<double> distances;
485 std::vector<double> indices;
486 double dist, sum_posterior = 0.;
489 #pragma omp for schedule(dynamic)
490 for (
int ii=0; ii<xi_values; ii++) {
493 for (
int N=0; N<nparams; N++) center[N] = xi[N][ii];
494 close = close_objects(center, xi_values);
495 if (close.size()>0) {
496 for (
auto&&k : close) {
498 for (
int N=0; N<nparams; N++) dist += pow((center[N]-unique_vect[N][k]), 2);
500 distances.push_back(dist);
501 indices.push_back(k-xi_values);
506 for (
auto&&k : indices) {
507 sum_posterior += values[k];
509 if (npoints>distNum)
break;
511 interp_values[ii] = sum_posterior/npoints;
519 return interp_values;
529 long j = m_Label[cell_index];
547 vector<vector<double>> data;
549 create_chain_mesh(data, rMAX, rMIN, nMAX, nMIN);
558 set_par(cell_size, xx, rMAX, rMIN, nMAX, nMIN);
565 void cbl::chainmesh::ChainMesh2D::set_par (
const double cell_size,
const std::vector<double> xx,
const std::vector<double> yy,
const double rMAX,
const double rMIN,
const long nMAX,
const long nMIN)
569 vector<vector<double>> data;
572 create_chain_mesh(data, rMAX, rMIN, nMAX, nMIN);
581 set_par(cell_size, xx, yy, rMAX, rMIN, nMAX, nMIN);
588 void cbl::chainmesh::ChainMesh3D::set_par (
const double cell_size,
const std::vector<double> xx,
const std::vector<double> yy,
const std::vector<double> zz,
const double rMAX,
const double rMIN,
const long nMAX,
const long nMIN)
591 vector<vector<double>> data;
595 create_chain_mesh(data, rMAX, rMIN, nMAX, nMIN);
604 set_par(cell_size, xx, yy, zz, rMAX, rMIN, nMAX, nMIN);
Implementation of the chain-mesh data structure.
ChainMesh1D()=default
default constructor
void set_par(const double cell_size, const std::vector< double > xx, const double rMAX, const double rMIN=-1., const long nMAX=300, const long nMIN=0)
function that set parameters for the chain-mesh
ChainMesh2D()=default
default constructor 1D
void set_par(const double cell_size, const std::vector< double > xx, const std::vector< double > yy, const double rMAX, const double rMIN=-1., const long nMAX=300, const long nMIN=0)
function that set parameters for the chain-mesh
ChainMesh3D()=default
default constructor
void set_par(const double cell_size, const std::vector< double > xx, const std::vector< double > yy, const std::vector< double > zz, const double rMAX, const double rMIN=-1., const long nMAX=300, const long nMIN=0)
function that set parameters for the chain-mesh
std::vector< long > close_objects(std::vector< double > center, long ii=-1) const
get the indeces of the objects close to an object
void create_chain_mesh(const std::vector< std::vector< double > > data, const double rMax, const double rMin=-1., const long nMAX=300, const long nMIN=10)
create the chain mesh
double interpolate(std::vector< double > xi, const int distNum)
N-dim interpolation of a set of N coordinates on a normalised grid (see normalize)
void set_par(const double cell_size, const long nDim)
function that set parameters for the chain-mesh
void create_chain_mesh_m2(const std::vector< std::vector< double > > data)
create the chain mesh
ChainMesh()=default
default constructor
void get_searching_region(const double r_max, const double r_min=-1.)
set the internal variable m_search_region, the list of cell around a generic center
long pos_to_index(const std::vector< double > center) const
get the index of the cell given the object coordinates
void normalize(std::vector< std::vector< double >> points, std::vector< double > values, const double rMAX)
function to set a normalized (square/cubic) grid from a sample of points, used for the N-dim interpol...
void index_to_inds(const long index, const std::vector< long > nn, std::vector< long > &indx) const
get the n indices given the unique index
std::vector< long > get_list(const long cell_index) const
get the index of the object inside a cell
std::vector< long > close_objects_cell(const int cell_index, long ii=-1) const
get the indeces of the objects close to a cell
long inds_to_index(const std::vector< long > indx) const
get the unique index of the cell given the n indices
static const char fDP2[]
conversion symbol for: double -> std::string
The global namespace of the CosmoBolognaLib
T Min(const std::vector< T > vect)
minimum element of a std::vector
std::string conv(const T val, const char *fact)
convert a number to a std::string
std::vector< T > different_elements(const std::vector< T > vect_input)
get the unique elements of a std::vector
int ErrorCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL, const cbl::glob::ExitCode exitCode=cbl::glob::ExitCode::_error_)
throw an exception: it is used for handling exceptions inside the CosmoBolognaLib
T Max(const std::vector< T > vect)
maximum element of a std::vector
int nint(const T val)
the nearest integer
void sort_2vectors(std::vector< double >::iterator p1, std::vector< double >::iterator p2, const int dim)
sort the elements of a std::vectors, and the elements of a second std::vector according to the first ...
int check_memory(const double frac, const bool exit=true, const std::string func="", const int type=1)
check if the memory used by current process is larger than a given fraction of the available memory