PURIFY
Next-generation radio interferometric imaging
Enumerations | Functions
purify::distribute Namespace Reference

Enumerations

enum class  plan { none , equal , radial , w_term }
 

Functions

std::vector< t_int > distribute_measurements (Vector< t_real > const &u, Vector< t_real > const &v, Vector< t_real > const &w, t_int const number_of_nodes, distribute::plan const distribution_plan=plan::equal, t_int const &grid_size=128)
 Distribute visiblities into groups. More...
 
Vector< t_int > w_distribution (Vector< t_real > const &u, const Vector< t_real > &v, const Vector< t_real > &w)
 Distribute visibilities into nodes in order of w terms (useful for w-stacking) More...
 
Vector< t_int > w_distribution (Vector< t_real > const &w)
 
Vector< t_int > distance_distribution (Vector< t_real > const &u, Vector< t_real > const &v)
 Distribute visiblities into nodes in order of distance from the centre. More...
 
Vector< t_int > equal_distribution (Vector< t_real > const &u, Vector< t_real > const &v, t_int const &grid_size)
 Distribute the visiblities into nodes in order of density. More...
 
std::tuple< std::vector< t_int >, std::vector< t_real > > kmeans_algo (const Vector< t_real > &w, const t_int number_of_nodes, const t_int iters, const std::function< t_real(t_real)> &cost=[](t_real x) { return x *x;}, const t_real rel_diff=1e-3)
 patition w terms using k-means More...
 

Enumeration Type Documentation

◆ plan

Enumerator
none 
equal 
radial 
w_term 

Definition at line 16 of file distribute.h.

Function Documentation

◆ distance_distribution()

Vector< t_int > purify::distribute::distance_distribution ( Vector< t_real > const &  u,
Vector< t_real > const &  v 
)

Distribute visiblities into nodes in order of distance from the centre.

Definition at line 69 of file distribute.cc.

69  {
70  // sort visibilities by distance from centre
71  Vector<t_int> index = Vector<t_int>::LinSpaced(u.size(), 0, u.size());
72  std::sort(index.data(), index.data() + index.size(), [&u, &v](int a, int b) {
73  return std::sqrt(u(a) * u(a) + v(a) * v(a)) < std::sqrt(u(b) * u(b) + v(b) * v(b));
74  });
75  return index;
76 }
const std::vector< t_real > u
data for u coordinate
Definition: operators.cc:18
const std::vector< t_real > v
data for v coordinate
Definition: operators.cc:20

References operators_test::u, and operators_test::v.

Referenced by distribute_measurements().

◆ distribute_measurements()

std::vector< t_int > purify::distribute::distribute_measurements ( Vector< t_real > const &  u,
Vector< t_real > const &  v,
Vector< t_real > const &  w,
t_int const  number_of_nodes,
distribute::plan const  distribution_plan,
t_int const &  grid_size 
)

Distribute visiblities into groups.

Definition at line 6 of file distribute.cc.

9  {
10  // distrubte visibilities from a measurement
11  Vector<t_int> index = Vector<t_int>::LinSpaced(u.size(), 0, u.size());
12  t_int const partition_size =
13  std::ceil(static_cast<t_real>(u.size()) / static_cast<t_real>(number_of_nodes));
14  // return a vector of vectors of indicies for each node
15  std::string plan_name = "";
16  switch (distribution_plan) {
17  case plan::none: {
18  plan_name = "none";
19  break;
20  }
21  case plan::equal: {
22  index = equal_distribution(u, v, grid_size);
23  plan_name = "equal";
24  break;
25  }
26  case plan::radial: {
27  index = distance_distribution(u, v);
28  plan_name = "radial";
29  break;
30  }
31  case plan::w_term: {
32  index = w_distribution(w);
33  plan_name = "w_term";
34  break;
35  }
36  default: {
37  throw std::runtime_error("Distribution plan not recognised or implimented.");
38  break;
39  }
40  }
42  "Using {} to make {} partitions from {} visibilities, with {} visibilities per a node.",
43  plan_name, number_of_nodes, index.size(), partition_size);
44  std::vector<t_int> partitions(u.size());
45  if (std::floor(static_cast<t_real>(index.size() - 1) / static_cast<t_real>(partition_size)) >
46  number_of_nodes - 1) {
47  PURIFY_ERROR("Error: Probably a bug in distribution plan.");
48  throw std::runtime_error("Distributing data into too many nodes");
49  }
50  // creating partitions
51  for (t_int i = 0; i < index.size(); ++i) {
52  partitions[index(i)] = std::floor(static_cast<t_real>(i) / static_cast<t_real>(partition_size));
53  }
54  return partitions;
55 }
#define PURIFY_ERROR(...)
\macro Something is definitely wrong, algorithm exits
Definition: logging.h:190
#define PURIFY_DEBUG(...)
\macro Output some debugging
Definition: logging.h:197
Vector< t_int > equal_distribution(Vector< t_real > const &u, Vector< t_real > const &v, t_int const &grid_size)
Distribute the visiblities into nodes in order of density.
Definition: distribute.cc:78
Vector< t_int > w_distribution(Vector< t_real > const &w)
Definition: distribute.cc:62
Vector< t_int > distance_distribution(Vector< t_real > const &u, Vector< t_real > const &v)
Distribute visiblities into nodes in order of distance from the centre.
Definition: distribute.cc:69

References distance_distribution(), equal, equal_distribution(), none, PURIFY_DEBUG, PURIFY_ERROR, radial, operators_test::u, operators_test::v, w_distribution(), and w_term.

Referenced by dirty_visibilities(), purify::utilities::distribute_params(), and TEST_CASE().

◆ equal_distribution()

Vector< t_int > purify::distribute::equal_distribution ( Vector< t_real > const &  u,
Vector< t_real > const &  v,
t_int const &  grid_size 
)

Distribute the visiblities into nodes in order of density.

Definition at line 78 of file distribute.cc.

79  {
80  // distribute visibilities by density calculated from histogram
81  t_real const max_u = u.array().maxCoeff();
82  t_real const max_v = v.array().maxCoeff();
83  t_real const min_u = u.array().minCoeff();
84  t_real const min_v = v.array().minCoeff();
85  // scaling for histogram grid
86  Vector<t_real> const scaled_u = (u.array() - min_u) * (grid_size - 1) / (max_u - min_u);
87  Vector<t_real> const scaled_v = (v.array() - min_v) * (grid_size - 1) / (max_v - min_v);
88  Image<t_int> histogram = Image<t_int>::Zero(grid_size, grid_size);
89  Vector<t_int> index = Vector<t_int>::LinSpaced(u.size(), 0, u.size());
90  // creating histogram grid
91  for (t_int i = 0; i < index.size(); i++) {
92  histogram((t_int)std::floor(scaled_u(i)), (t_int)std::floor(scaled_v(i))) += 1;
93  }
94  // sorting indicies
95  std::sort(index.data(), index.data() + index.size(),
96  [&histogram, &scaled_u, &scaled_v](int a, int b) {
97  return (histogram((t_int)std::floor(scaled_u(a)), (t_int)std::floor(scaled_v(a))) <
98  histogram((t_int)std::floor(scaled_u(b)), (t_int)std::floor(scaled_v(b))));
99  });
100  return index;
101 }

References operators_test::u, and operators_test::v.

Referenced by distribute_measurements().

◆ kmeans_algo()

std::tuple< std::vector< t_int >, std::vector< t_real > > purify::distribute::kmeans_algo ( const Vector< t_real > &  w,
const t_int  number_of_nodes,
const t_int  iters,
const std::function< t_real(t_real)> &  cost,
const t_real  rel_diff 
)

patition w terms using k-means

Definition at line 103 of file distribute.cc.

105  {
106  std::vector<t_int> w_node(w.size(), 0);
107  std::vector<t_real> w_centre(number_of_nodes, 0);
108  std::vector<t_real> w_sum(number_of_nodes, 0);
109  std::vector<t_real> w_count(number_of_nodes, 0);
110  t_real diff = 1;
111  t_real const wmin = w.minCoeff();
112  t_real const wmax = w.maxCoeff();
113  PURIFY_DEBUG("Min w = {}", wmin);
114  PURIFY_DEBUG("Max w = {}", wmax);
115  for (int i = 0; i < w_centre.size(); i++)
116  w_centre[i] = (i * (wmax - wmin) / number_of_nodes + wmin);
117  // lopp through even nodes to reduces w-term
118  for (int n = 0; n < iters; n++) {
119  PURIFY_DEBUG("clustering iteration {}", n);
120  for (int i = 0; i < w.size(); i++) {
121  t_real min = 2 * cost(wmax - wmin);
122  for (int node = 0; node < number_of_nodes; node++) {
123  const t_real cost_val = cost(w(i) - w_centre.at(node));
124  if (cost_val < min) {
125  min = cost_val;
126  w_node[i] = node;
127  }
128  }
129  w_sum[w_node.at(i)] += w(i);
130  w_count[w_node.at(i)]++;
131  }
132  for (int j = 0; j < number_of_nodes; j++) {
133  diff += std::abs(((w_count.at(j) > 0) ? w_sum.at(j) / w_count.at(j) : 0) - w_centre.at(j)) /
134  std::abs(w_centre.at(j) * number_of_nodes);
135  w_centre[j] = (w_count.at(j) > 0) ? w_sum.at(j) / w_count.at(j) : 0;
136  PURIFY_DEBUG("Node {} has {} visibilities, using w-stack w = {}.", j, w_count.at(j),
137  w_centre.at(j));
138  w_sum[j] = 0;
139  w_count[j] = 0;
140  }
141  if (diff < rel_diff) {
142  PURIFY_DEBUG("Converged!");
143  break;
144  } else {
145  PURIFY_DEBUG("relative_diff = {}", diff);
146  diff = 0;
147  }
148  }
149 
150  return std::make_tuple(w_node, w_centre);
151 }

References PURIFY_DEBUG.

Referenced by TEST_CASE(), purify::utilities::w_stacking(), and purify::utilities::w_stacking_with_all_to_all().

◆ w_distribution() [1/2]

Vector< t_int > purify::distribute::w_distribution ( const Vector< t_real > &  u,
const Vector< t_real > &  v,
Vector< t_real > const &  w 
)

Distribute visibilities into nodes in order of w terms (useful for w-stacking)

Definition at line 57 of file distribute.cc.

58  {
59  return w_distribution(w);
60 }

Referenced by distribute_measurements().

◆ w_distribution() [2/2]

Vector< t_int > purify::distribute::w_distribution ( Vector< t_real > const &  w)

Definition at line 62 of file distribute.cc.

62  {
63  // sort visibilities by w from w_max to w_min
64  Vector<t_int> index = Vector<t_int>::LinSpaced(w.size(), 0, w.size());
65  std::sort(index.data(), index.data() + index.size(), [&w](int a, int b) { return w(a) < w(b); });
66  return index;
67 }