PURIFY
Next-generation radio interferometric imaging
Namespaces | Functions
purify::wproj_utilities Namespace Reference

Namespaces

 expansions
 

Functions

std::vector< t_uint > w_rows (const Sparse< t_complex > &w_degrider)
 
std::tuple< t_real, t_real > fov_cosines (t_real const &cell_x, t_real const &cell_y, t_uint const &x_size, t_uint const &y_size)
 Work out max L and M directional cosines from image parameters. More...
 
Matrix< t_complex > generate_dde (const std::function< t_complex(t_real, t_real)> &dde, const t_real &cell_x, const t_real &cell_y, const t_uint &x_size, const t_uint &y_size)
 Generate image of DDE for A or W projection. More...
 
Matrix< t_complex > generate_chirp (const std::function< t_complex(t_real, t_real)> &dde, const t_real &w_rate, const t_real &cell_x, const t_real &cell_y, const t_uint &x_size, const t_uint &y_size)
 
Matrix< t_complex > generate_chirp (const t_real &w_rate, const t_real &cell_x, const t_real &cell_y, const t_uint &x_size, const t_uint &y_size)
 Generates image of chirp. More...
 
Sparse< t_complex > create_chirp_row (const t_real &w_rate, const t_real &cell_x, const t_real &cell_y, const t_uint &ftsizev, const t_uint &ftsizeu, const t_real &energy_fraction, const sopt::OperatorFunction< Vector< t_complex >> &fftop)
 Generates row of chirp matrix from image of chirp. More...
 
Sparse< t_complex > create_chirp_row (const Vector< t_complex > &chirp_image, const t_real &energy_fraction, const sopt::OperatorFunction< Vector< t_complex >> &fftop)
 
Sparse< t_complex > wprojection_matrix (const Sparse< t_complex > &G, const t_uint &x_size, const t_uint &y_size, const Vector< t_real > &w_components, const t_real &cell_x, const t_real &cell_y, const t_real &energy_fraction_chirp, const t_real &energy_fraction_wproj, const expansions::series series=expansions::series::none, const t_uint order=1, const t_real &interpolation_error=1e-2)
 Produce Gridding matrix convovled with chirp matrix for wprojection. More...
 
t_real snr_metric (const Image< t_real > &model, const Image< t_real > &solution)
 SNR calculation. More...
 
t_real mr_metric (const Image< t_real > &model, const Image< t_real > &solution)
 MR calculation. More...
 
Sparse< t_complex > generate_vect (const t_uint &x_size, const t_uint &y_size, const t_real &sigma, const t_real &mean)
 Genereates an image of a Gaussian as a sparse matrice. More...
 
template<typename T >
Sparse< t_complex > convert_sparse (const Eigen::MatrixBase< T > &M, const t_real &threshold=0.)
 Convert from dense to sparse. More...
 
template<typename T >
t_real sparsify_row_thres (const Eigen::SparseMatrixBase< T > &row, const t_real &energy)
 Returns threshold to keep a fraction of energy in the sparse row. More...
 
template<typename T >
t_real sparsify_row_dense_thres (const Eigen::MatrixBase< T > &row, const t_real &energy)
 Returns threshold to keep a fraction of energy in the dense row. More...
 
template<class T >
Sparse< t_complex > row_wise_convolution (const Sparse< t_complex > &Grid_, const Sparse< T > &chirp_, const t_uint &x_size, const t_uint &y_size)
 Perform convolution with gridding matrix row and chirp matrix row. More...
 
t_real sparsity_sp (const Sparse< t_complex > &Gmat)
 return fraction of non zero values from sparse matrix More...
 
t_real sparsity_im (const Image< t_complex > &Cmat)
 return faction of non zero values from matrix More...
 
t_real upsample_ratio_sim (const utilities::vis_params &uv_vis, const t_real &L, const t_real &M, const t_int &x_size, const t_int &y_size, const t_int &multipleOf)
 Calculate upsample ratio from bandwidth (only needed for simulations) More...
 
template<class T >
Sparse< t_complex > row_wise_sparse_convolution (const Sparse< t_complex > &Grid_, const Sparse< T > &chirp_, const t_uint &x_size, const t_uint &y_size)
 

Function Documentation

◆ convert_sparse()

template<typename T >
Sparse< t_complex > purify::wproj_utilities::convert_sparse ( const Eigen::MatrixBase< T > &  M,
const t_real &  threshold = 0. 
)

Convert from dense to sparse.

Definition at line 90 of file wproj_utilities.h.

90  {
91  const Sparse<t_complex> M_sparse =
92  M.sparseView(std::max(M.cwiseAbs().maxCoeff() * 1e-10, threshold), 1);
93  Sparse<t_complex> out(M.rows(), M.cols());
94  out.reserve(M_sparse.nonZeros());
95  for (t_int k = 0; k < M_sparse.outerSize(); ++k)
96  for (Sparse<t_complex>::InnerIterator it(M_sparse, k); it; ++it) {
97  out.coeffRef(it.row(), it.col()) = it.value();
98  }
99  return out;
100 }

Referenced by create_chirp_row(), and row_wise_convolution().

◆ create_chirp_row() [1/2]

Sparse< t_complex > purify::wproj_utilities::create_chirp_row ( const t_real &  w_rate,
const t_real &  cell_x,
const t_real &  cell_y,
const t_uint &  ftsizev,
const t_uint &  ftsizeu,
const t_real &  energy_fraction,
const sopt::OperatorFunction< Vector< t_complex >> &  fftop 
)

Generates row of chirp matrix from image of chirp.

Definition at line 110 of file wproj_utilities.cc.

113  {
114  const Matrix<t_complex> chirp =
115  wproj_utilities::generate_chirp(w_rate, cell_x, cell_y, ftsizeu, ftsizev);
116  return create_chirp_row(Vector<t_complex>::Map(chirp.data(), chirp.size()), energy_fraction,
117  fftop);
118 }
Matrix< t_complex > generate_chirp(const t_real &w_rate, const t_real &cell_x, const t_real &cell_y, const t_uint &x_size, const t_uint &y_size)
Generates image of chirp.
Sparse< t_complex > create_chirp_row(const Vector< t_complex > &chirp_image, const t_real &energy_fraction, const sopt::OperatorFunction< Vector< t_complex >> &fftop)

References generate_chirp().

Referenced by wprojection_matrix().

◆ create_chirp_row() [2/2]

Sparse< t_complex > purify::wproj_utilities::create_chirp_row ( const Vector< t_complex > &  chirp_image,
const t_real &  energy_fraction,
const sopt::OperatorFunction< Vector< t_complex >> &  fftop 
)

Definition at line 119 of file wproj_utilities.cc.

121  {
122  Vector<t_complex> chirp;
123 #pragma omp critical(fft)
124  fftop(chirp, chirp_image);
125  chirp *= std::sqrt(chirp.size());
126  const t_real thres = wproj_utilities::sparsify_row_dense_thres(chirp, energy_fraction);
127  assert(chirp.norm() > 0);
128  const t_real row_max = chirp.cwiseAbs().maxCoeff();
129  return convert_sparse(chirp, thres).transpose();
130 }
t_real sparsify_row_dense_thres(const Eigen::MatrixBase< T > &row, const t_real &energy)
Returns threshold to keep a fraction of energy in the dense row.
Sparse< t_complex > convert_sparse(const Eigen::MatrixBase< T > &M, const t_real &threshold=0.)
Convert from dense to sparse.

References convert_sparse(), and sparsify_row_dense_thres().

◆ fov_cosines()

std::tuple< t_real, t_real > purify::wproj_utilities::fov_cosines ( t_real const &  cell_x,
t_real const &  cell_y,
t_uint const &  x_size,
t_uint const &  y_size 
)

Work out max L and M directional cosines from image parameters.

Definition at line 37 of file wproj_utilities.cc.

38  {
39  // celly:: size of y pixel in arcseconds
40  // cellx:: size of x pixel in arcseconds
41  // x_size:: number of pixels along x-axis
42  // y_size:: number of pixels along y-axis
43  const t_real pi = constant::pi;
44  const t_real theta_FoV_L = cell_x * x_size;
45  const t_real theta_FoV_M = cell_y * y_size;
46  const t_real L = 2 * std::sin(pi / 180. * theta_FoV_L / (60. * 60.) * 0.5);
47  const t_real M = 2 * std::sin(pi / 180. * theta_FoV_M / (60. * 60.) * 0.5);
48  return std::make_tuple(L, M);
49 }
const t_real pi
mathematical constant
Definition: types.h:70

References purify::constant::pi.

Referenced by generate_dde().

◆ generate_chirp() [1/2]

Matrix< t_complex > purify::wproj_utilities::generate_chirp ( const std::function< t_complex(t_real, t_real)> &  dde,
const t_real &  w_rate,
const t_real &  cell_x,
const t_real &  cell_y,
const t_uint &  x_size,
const t_uint &  y_size 
)

Definition at line 76 of file wproj_utilities.cc.

78  {
79  // return chirp image fourier transform for w component
80  // w:: w-term in units of lambda
81  // celly:: size of y pixel in arcseconds
82  // cellx:: size of x pixel in arcseconds
83  // x_size:: number of pixels along x-axis
84  // y_size:: number of pixels along y-axis
85  const t_real nz = y_size * x_size;
86  const t_complex I(0, 1);
87  const t_real pi = constant::pi;
88  const auto chirp = [=](const t_real &y, const t_real &x) {
89  return dde(y, x) * (std::exp(-2 * pi * I * w_rate * (std::sqrt(1 - x * x - y * y) - 1))) / nz;
90  };
91  auto primary_beam = [=](const t_real &x, const t_real &y) {
92  return 1. / std::sqrt(1 - x * x - y * y);
93  };
94  const auto chirp_approx = [=](const t_real &y, const t_real &x) {
95  return dde(y, x) * (std::exp(2 * pi * I * w_rate * (x * x + y * y))) / nz;
96  };
97  return generate_dde(chirp, cell_x, cell_y, x_size, y_size);
98 }
Matrix< t_complex > generate_dde(const std::function< t_complex(t_real, t_real)> &dde, const t_real &cell_x, const t_real &cell_y, const t_uint &x_size, const t_uint &y_size)
Generate image of DDE for A or W projection.

References generate_dde(), purify::I, and purify::constant::pi.

Referenced by create_chirp_row(), and generate_chirp().

◆ generate_chirp() [2/2]

Matrix< t_complex > purify::wproj_utilities::generate_chirp ( const t_real &  w_rate,
const t_real &  cell_x,
const t_real &  cell_y,
const t_uint &  x_size,
const t_uint &  y_size 
)

Generates image of chirp.

Definition at line 99 of file wproj_utilities.cc.

100  {
101  // return chirp image fourier transform for w component
102  // w:: w-term in units of lambda
103  // celly:: size of y pixel in arcseconds
104  // cellx:: size of x pixel in arcseconds
105  // x_size:: number of pixels along x-axis
106  // y_size:: number of pixels along y-axis
107  return generate_chirp([](const t_real &, const t_real &) { return 1.; }, w_rate, cell_x, cell_y,
108  x_size, y_size);
109 }

References generate_chirp().

◆ generate_dde()

Matrix< t_complex > purify::wproj_utilities::generate_dde ( const std::function< t_complex(t_real, t_real)> &  dde,
const t_real &  cell_x,
const t_real &  cell_y,
const t_uint &  x_size,
const t_uint &  y_size 
)

Generate image of DDE for A or W projection.

Definition at line 51 of file wproj_utilities.cc.

53  {
54  // celly:: size of y pixel in arcseconds
55  // cellx:: size of x pixel in arcseconds
56  // x_size:: number of pixels along x-axis
57  // y_size:: number of pixels along y-axis
58  auto const LM = fov_cosines(cell_x, cell_y, x_size, y_size);
59 
60  const t_real L = std::get<0>(LM);
61  const t_real M = std::get<1>(LM);
62 
63  const t_real delt_x = L / x_size;
64  const t_real delt_y = M / y_size;
65  Image<t_complex> chirp(y_size, x_size);
66 
67  for (t_int l = 0; l < x_size; ++l)
68  for (t_int m = 0; m < y_size; ++m) {
69  const t_real x = (l + 0.5 - x_size * 0.5) * delt_x;
70  const t_real y = (m + 0.5 - y_size * 0.5) * delt_y;
71  chirp(l, m) = dde(y, x);
72  }
73 
74  return chirp;
75 }
std::tuple< t_real, t_real > fov_cosines(t_real const &cell_x, t_real const &cell_y, t_uint const &x_size, t_uint const &y_size)
Work out max L and M directional cosines from image parameters.

References fov_cosines().

Referenced by generate_chirp().

◆ generate_vect()

Sparse< t_complex > purify::wproj_utilities::generate_vect ( const t_uint &  x_size,
const t_uint &  y_size,
const t_real &  sigma,
const t_real &  mean 
)

Genereates an image of a Gaussian as a sparse matrice.

Definition at line 213 of file wproj_utilities.cc.

214  {
215  // t_real sigma = 3;
216  // const t_real pi = constant::pi;
217  t_int W = x_size;
218  Matrix<t_complex> chirp = Image<t_complex>::Zero(y_size, x_size);
219  // t_real mean = 0;
220  t_complex I(0, 1);
221  t_real step = W / 2;
222 
223  // t_complex sum = 0.0; // For accumulating the kernel values
224  for (int x = 0; x < W; ++x) {
225  for (int y = 0; y < W; ++y) {
226  t_int xx = x - step;
227  xx = xx * xx;
228  t_int yy = y - step;
229  yy = yy * yy;
230  t_complex val =
231  exp(-0.5 * (xx / (sigma * sigma) +
232  yy / (sigma * sigma))); //* std::exp(- 2 * pi * I * (x * 0.5 + y * 0.5));
233  if (std::abs(val) > 1e-5)
234  chirp(x, y) = val;
235  else
236  chirp(x, y) = 0.0;
237  }
238  }
239 
240  chirp.resize(x_size * y_size, 1);
241  Sparse<t_complex> chirp_ = chirp.sparseView(1e-5, 1);
242  return chirp_;
243 }

References purify::I.

◆ mr_metric()

t_real purify::wproj_utilities::mr_metric ( const Image< t_real > &  model,
const Image< t_real > &  solution 
)

MR calculation.

Definition at line 199 of file wproj_utilities.cc.

199  {
200  /*
201  Returns SNR of the estimated model image
202  */
203  t_int Npix = model.rows() * model.cols();
204  Image<t_real> model_ = model.array() + 1e-10;
205  Image<t_real> solution_ = solution.array() + 1e-10;
206  Image<t_real> model_sol = model_.matrix().cwiseQuotient(solution_.matrix());
207  Image<t_real> sol_model = solution_.matrix().cwiseQuotient(model_.matrix());
208  Image<t_real> min_ratio = sol_model.matrix().cwiseMin(model_sol.matrix());
209  t_real val = min_ratio.array().sum() / Npix;
210  return val;
211 }

◆ row_wise_convolution()

template<class T >
Sparse< t_complex > purify::wproj_utilities::row_wise_convolution ( const Sparse< t_complex > &  Grid_,
const Sparse< T > &  chirp_,
const t_uint &  x_size,
const t_uint &  y_size 
)

Perform convolution with gridding matrix row and chirp matrix row.

Definition at line 187 of file wproj_utilities.h.

188  {
189  assert((Grid_.nonZeros() > 0) and (chirp_.nonZeros() > 0));
190  Matrix<t_complex> output_row = Matrix<t_complex>::Zero(1, x_size * y_size);
191  const t_int x_sizec = std::floor(x_size * 0.5);
192  const t_int y_sizec = std::floor(y_size * 0.5);
193  for (t_int k = 0; k < output_row.size(); k++) {
194  // shifting indicies to workout linear convolution
195  t_int i_shift_W = 0;
196  t_int j_shift_W = 0;
197  std::tie(j_shift_W, i_shift_W) = utilities::ind2sub(k, y_size, x_size);
198  const t_int i_W = utilities::mod(i_shift_W + x_sizec, x_size);
199  const t_int j_W = utilities::mod(j_shift_W + y_sizec, y_size);
200  for (Sparse<t_complex>::InnerIterator it(Grid_, 0); it; ++it) {
201  t_int i_shift_G = 0;
202  t_int j_shift_G = 0;
203  std::tie(j_shift_G, i_shift_G) = utilities::ind2sub(it.index(), y_size, x_size);
204  const t_int i_G = utilities::mod(i_shift_G + x_sizec, x_size);
205  const t_int j_G = utilities::mod(j_shift_G + y_sizec, y_size);
206  const t_int i_C = i_W - i_G;
207  const t_int j_C = j_W - j_G;
208  // Checking that convolution result is going to be within bounds
209  if (-x_sizec <= i_C and i_C < std::ceil(x_size * 0.5) and -y_sizec <= j_C and
210  j_C < std::ceil(y_size * 0.5)) {
211  // FFTshift of result to go into gridding matrix
212  const t_int i_shift_C = utilities::mod(i_C, x_size);
213  const t_int j_shift_C = utilities::mod(j_C, y_size);
214  const t_int pos = utilities::sub2ind(j_shift_C, i_shift_C, y_size, x_size);
215  assert(0 <= pos and pos < x_size * y_size);
216  output_row(0, k) += it.value() * chirp_.coeff(0, pos);
217  }
218  }
219  }
220  return convert_sparse(output_row);
221 }
t_int sub2ind(const t_int &row, const t_int &col, const t_int &rows, const t_int &cols)
Converts from subscript to index for matrix.
Definition: utilities.cc:12
t_real mod(const t_real &x, const t_real &y)
Mod function modified to wrap circularly for negative numbers.
Definition: utilities.cc:41
std::tuple< t_int, t_int > ind2sub(const t_int &sub, const t_int &cols, const t_int &rows)
Converts from index to subscript for matrix.
Definition: utilities.cc:26

References convert_sparse(), purify::utilities::ind2sub(), purify::utilities::mod(), and purify::utilities::sub2ind().

◆ row_wise_sparse_convolution()

template<class T >
Sparse<t_complex> purify::wproj_utilities::row_wise_sparse_convolution ( const Sparse< t_complex > &  Grid_,
const Sparse< T > &  chirp_,
const t_uint &  x_size,
const t_uint &  y_size 
)

Definition at line 223 of file wproj_utilities.h.

225  {
226  assert((Grid_.nonZeros() > 0) and (chirp_.nonZeros() > 0));
227  const t_int x_sizec = std::floor(x_size * 0.5);
228  const t_int y_sizec = std::floor(y_size * 0.5);
229  std::set<t_int> non_zero_W;
230  for (Sparse<t_complex>::InnerIterator jt(chirp_, 0); jt; ++jt) {
231  // shifting indicies to workout linear convolution
232  t_int i_shift_C = 0;
233  t_int j_shift_C = 0;
234  std::tie(j_shift_C, i_shift_C) = utilities::ind2sub(jt.index(), y_size, x_size);
235  const t_int i_C = utilities::mod(i_shift_C + x_sizec, x_size) - x_sizec;
236  const t_int j_C = utilities::mod(j_shift_C + y_sizec, y_size) - y_sizec;
237  for (Sparse<t_complex>::InnerIterator it(Grid_, 0); it; ++it) {
238  t_int i_shift_G = 0;
239  t_int j_shift_G = 0;
240  std::tie(j_shift_G, i_shift_G) = utilities::ind2sub(it.index(), y_size, x_size);
241  const t_int i_G = utilities::mod(i_shift_G + x_sizec, x_size) - x_sizec;
242  const t_int j_G = utilities::mod(j_shift_G + y_sizec, y_size) - y_sizec;
243  const t_int i_W = i_G + i_C;
244  const t_int j_W = j_G + j_C;
245  if (-x_sizec <= i_W and i_W < std::ceil(x_size * 0.5) and -y_sizec <= j_W and
246  j_W < std::ceil(y_size * 0.5)) {
247  const t_int i_shift_W = utilities::mod(i_W, x_size);
248  const t_int j_shift_W = utilities::mod(j_W, y_size);
249  const t_real pos = utilities::sub2ind(j_shift_W, i_shift_W, y_size, x_size);
250  non_zero_W.insert(pos);
251  }
252  }
253  }
254  if (non_zero_W.size() < std::min(Grid_.nonZeros(), chirp_.nonZeros()))
255  throw std::runtime_error("Gridding kernel or chirp kernel is zero.");
256  Sparse<t_complex> output_row(1, x_size * y_size);
257  output_row.reserve(non_zero_W.size());
258 
259  for (t_int k = 0; k < output_row.size(); k++) {
260  // shifting indicies to workout linear convolution
261  t_int i_shift_W = 0;
262  t_int j_shift_W = 0;
263  std::tie(j_shift_W, i_shift_W) = utilities::ind2sub(k, y_size, x_size);
264  const t_int i_W = utilities::mod(i_shift_W + x_sizec, x_size);
265  const t_int j_W = utilities::mod(j_shift_W + y_sizec, y_size);
266  for (Sparse<t_complex>::InnerIterator it(Grid_, 0); it; ++it) {
267  t_int i_shift_G = 0;
268  t_int j_shift_G = 0;
269  std::tie(j_shift_G, i_shift_G) = utilities::ind2sub(it.index(), y_size, x_size);
270  const t_int i_G = utilities::mod(i_shift_G + x_sizec, x_size);
271  const t_int j_G = utilities::mod(j_shift_G + y_sizec, y_size);
272  const t_int i_C = i_W - i_G;
273  const t_int j_C = j_W - j_G;
274  // Checking that convolution result is going to be within bounds
275  if (-x_sizec <= i_C and i_C < std::ceil(x_size * 0.5) and -y_sizec <= j_C and
276  j_C < std::ceil(y_size * 0.5)) {
277  // FFTshift of result to go into gridding matrix
278  const t_int i_shift_C = utilities::mod(i_C, x_size);
279  const t_int j_shift_C = utilities::mod(j_C, y_size);
280  const t_int pos = utilities::sub2ind(j_shift_C, i_shift_C, y_size, x_size);
281  assert(0 <= pos and pos < x_size * y_size);
282  output_row.coeffRef(0, k) += it.value() * chirp_.coeff(0, pos);
283  }
284  }
285  }
286  return output_row;
287 }

References purify::utilities::ind2sub(), purify::utilities::mod(), and purify::utilities::sub2ind().

Referenced by wprojection_matrix().

◆ snr_metric()

t_real purify::wproj_utilities::snr_metric ( const Image< t_real > &  model,
const Image< t_real > &  solution 
)

SNR calculation.

Definition at line 190 of file wproj_utilities.cc.

190  {
191  /*
192  Returns SNR of the estimated model image
193  */
194  t_real nm = model.matrix().norm();
195  t_real ndiff = (model - solution).matrix().norm();
196  t_real val = 20 * std::log10(nm / ndiff);
197  return val;
198 }

◆ sparsify_row_dense_thres()

template<typename T >
t_real purify::wproj_utilities::sparsify_row_dense_thres ( const Eigen::MatrixBase< T > &  row,
const t_real &  energy 
)

Returns threshold to keep a fraction of energy in the dense row.

Definition at line 147 of file wproj_utilities.h.

147  {
148  /*
149  Takes in a row of G and returns indexes of coeff to keep in the row sparse version
150  energy:: how much energy - in l2 sens - to keep after hard-thresholding
151  */
152 
153  if (energy >= 1) return 0;
154 
155  const Vector<t_real> row_abs = row.cwiseAbs();
156  const t_real abs_row_max = row.cwiseAbs().maxCoeff();
157  const t_real row_total_energy = row_abs.cwiseProduct(row_abs).sum();
158  const t_real target_threshold_energy_sum = row_total_energy * energy;
159  const t_int niters = 200;
160  t_real lower = 0;
161  t_real upper = abs_row_max;
162  t_real current_threshold = upper * 0.5;
163  t_real old_threshold = upper;
164  bool converged = false;
165  for (t_int i = 0; i < niters; i++) {
166  t_real threshold_energy_sum = 0;
167  for (t_int j = 0; j < row_abs.size(); j++) {
168  if (row_abs(j) > current_threshold) threshold_energy_sum += row_abs(j) * row_abs(j);
169  }
170  if ((std::abs(current_threshold - old_threshold) / std::abs(old_threshold) < 1e-3) and
171  ((threshold_energy_sum >= target_threshold_energy_sum) and
172  (((threshold_energy_sum / target_threshold_energy_sum) - 1) < 0.01))) {
173  converged = true;
174  break;
175  }
176  if (threshold_energy_sum < target_threshold_energy_sum)
177  upper = current_threshold;
178  else
179  lower = current_threshold;
180  old_threshold = current_threshold;
181  current_threshold = (lower + upper) * 0.5;
182  }
183  if (!converged) current_threshold = lower;
184  return current_threshold;
185 }

Referenced by create_chirp_row().

◆ sparsify_row_thres()

template<typename T >
t_real purify::wproj_utilities::sparsify_row_thres ( const Eigen::SparseMatrixBase< T > &  row,
const t_real &  energy 
)

Returns threshold to keep a fraction of energy in the sparse row.

Definition at line 102 of file wproj_utilities.h.

102  {
103  /*
104  Takes in a row of G and returns indexes of coeff to keep in the row sparse version
105  energy:: how much energy - in l2 sens - to keep after hard-thresholding
106  */
107 
108  if (energy >= 1) return 0;
109 
110  const Sparse<t_real> row_abs = row.cwiseAbs();
111 
112  t_real abs_row_max = 0;
113  for (t_uint i = 0; i < row_abs.nonZeros(); i++) {
114  if (*(row_abs.valuePtr() + i) > abs_row_max) abs_row_max = *(row_abs.valuePtr() + i);
115  }
116  const t_real row_total_energy = row_abs.cwiseProduct(row_abs).sum();
117  const t_real target_threshold_energy_sum = row_total_energy * energy;
118  const t_int niters = 200;
119  t_real lower = 0;
120  t_real upper = abs_row_max;
121  t_real current_threshold = upper * 0.5;
122  t_real old_threshold = upper;
123  bool converged = false;
124  for (t_int i = 0; i < niters; i++) {
125  t_real threshold_energy_sum = 0;
126  for (t_int j = 0; j < row_abs.nonZeros(); j++) {
127  if (*(row_abs.valuePtr() + j) > current_threshold)
128  threshold_energy_sum += *(row_abs.valuePtr() + j) * *(row_abs.valuePtr() + j);
129  }
130  if ((std::abs(current_threshold - old_threshold) / std::abs(old_threshold) < 1e-3) and
131  ((threshold_energy_sum >= target_threshold_energy_sum) and
132  (((threshold_energy_sum / target_threshold_energy_sum) - 1) < 0.01))) {
133  converged = true;
134  break;
135  }
136  if (threshold_energy_sum < target_threshold_energy_sum)
137  upper = current_threshold;
138  else
139  lower = current_threshold;
140  old_threshold = current_threshold;
141  current_threshold = (lower + upper) * 0.5;
142  }
143  if (!converged) current_threshold = lower;
144  return current_threshold;
145 }

Referenced by wprojection_matrix().

◆ sparsity_im()

t_real purify::wproj_utilities::sparsity_im ( const Image< t_complex > &  Cmat)

return faction of non zero values from matrix

◆ sparsity_sp()

t_real purify::wproj_utilities::sparsity_sp ( const Sparse< t_complex > &  Gmat)

return fraction of non zero values from sparse matrix

◆ upsample_ratio_sim()

t_real purify::wproj_utilities::upsample_ratio_sim ( const utilities::vis_params uv_vis,
const t_real &  L,
const t_real &  M,
const t_int &  x_size,
const t_int &  y_size,
const t_int &  multipleOf 
)

Calculate upsample ratio from bandwidth (only needed for simulations)

◆ w_rows()

std::vector<t_uint> purify::wproj_utilities::w_rows ( const Sparse< t_complex > &  w_degrider)

Definition at line 22 of file wproj_utilities.cc.

22  {
23  std::set<t_uint> w_rows_set;
24  for (t_int k = 0; k < w_degrider.outerSize(); ++k) {
25  t_uint index = 0;
26  for (Sparse<t_complex>::InnerIterator it(w_degrider, k); it; ++it) {
27  index++;
28  if (index > 0) {
29  w_rows_set.insert(it.col());
30  }
31  }
32  }
33  std::vector<t_uint> w_rows(w_rows_set.begin(), w_rows_set.end());
34  std::sort(w_rows.begin(), w_rows.end());
35  return w_rows;
36 }
std::vector< t_uint > w_rows(const Sparse< t_complex > &w_degrider)

◆ wprojection_matrix()

Sparse< t_complex > purify::wproj_utilities::wprojection_matrix ( const Sparse< t_complex > &  G,
const t_uint &  x_size,
const t_uint &  y_size,
const Vector< t_real > &  w_components,
const t_real &  cell_x,
const t_real &  cell_y,
const t_real &  energy_fraction_chirp,
const t_real &  energy_fraction_wproj,
const expansions::series  series,
const t_uint  order,
const t_real &  interpolation_error 
)

Produce Gridding matrix convovled with chirp matrix for wprojection.

Definition at line 132 of file wproj_utilities.cc.

138  {
139  const t_uint Npix = x_size * y_size;
140  const t_uint Nvis = w_components.size();
141 
142  PURIFY_HIGH_LOG("Spread of w components {} ",
143  std::sqrt(std::pow(w_components.norm(), 2) / Nvis -
144  std::pow(w_components.array().mean(), 2)));
145  PURIFY_HIGH_LOG("Mean of w components {} ", w_components.array().mean());
146  PURIFY_HIGH_LOG("Hard-thresholding of the chirp kernels: energy [{}] ", energy_fraction_chirp);
147  PURIFY_HIGH_LOG("Hard-thresholding of the rows of G: energy [{}] ", energy_fraction_wproj);
148 
149  const auto ft_plan = operators::fftw_plan::measure;
150  const auto fftop_ = operators::init_FFT_2d<Vector<t_complex>>(y_size, x_size, 1., ft_plan);
151  Sparse<t_complex> GW(Nvis, Npix);
152 
153  t_uint counts = 0;
154  t_uint total_non_zero = 0;
155  GW.reserve(G.nonZeros() * 1e3);
156 #pragma omp parallel for
157  for (t_int m = 0; m < G.rows(); m++) {
158  const Sparse<t_complex> chirp =
159  create_chirp_row(w_components(m), cell_x, cell_y, x_size, y_size, energy_fraction_chirp,
160  std::get<0>(fftop_));
161 
162  Sparse<t_complex> kernel = row_wise_sparse_convolution(G.row(m), chirp, x_size, y_size);
163  const t_real thres = sparsify_row_thres(kernel, energy_fraction_wproj);
164  kernel.prune([&](const t_uint &i, const t_uint &j, const t_complex &value) {
165  return std::abs(value) > thres;
166  });
167  assert(kernel.cols() > 0);
168  assert(kernel.rows() == 1);
169 #pragma omp critical
170  GW.row(m) = kernel;
171 #pragma omp critical
172  counts++;
173 #pragma omp critical
174  total_non_zero += kernel.nonZeros();
175 #pragma omp critical
176  // if(counts % 100 == 0) {
177  PURIFY_DEBUG("Row {} of {}", counts, GW.rows());
178  PURIFY_DEBUG("With {} entries non zero, which is {} entries per a row.", total_non_zero,
179  static_cast<t_real>(total_non_zero) / counts);
180  //}
181  }
182  assert(GW.nonZeros() > 0);
183  PURIFY_DEBUG("\nBuilding the rows of GW.. DONE!\n");
184  PURIFY_DEBUG("DONE - With {} entries non zero, which is {} entries per a row.", GW.nonZeros(),
185  static_cast<t_real>(GW.nonZeros()) / GW.rows());
186  GW.makeCompressed();
187  return GW;
188 }
#define PURIFY_HIGH_LOG(...)
High priority message.
Definition: logging.h:203
#define PURIFY_DEBUG(...)
\macro Output some debugging
Definition: logging.h:197
t_real sparsify_row_thres(const Eigen::SparseMatrixBase< T > &row, const t_real &energy)
Returns threshold to keep a fraction of energy in the sparse row.
Sparse< t_complex > row_wise_sparse_convolution(const Sparse< t_complex > &Grid_, const Sparse< T > &chirp_, const t_uint &x_size, const t_uint &y_size)

References create_chirp_row(), purify::operators::measure, PURIFY_DEBUG, PURIFY_HIGH_LOG, row_wise_sparse_convolution(), and sparsify_row_thres().