19   const t_uint M = 1000;
 
   20   const t_real oversample_ratio = 2;
 
   21   const t_uint imsizex = 128;
 
   22   const t_uint imsizey = 128;
 
   23   const t_uint N = imsizex * imsizey;
 
   24   const t_uint ftsizev = std::floor(imsizey * oversample_ratio);
 
   25   const t_uint ftsizeu = std::floor(imsizex * oversample_ratio);
 
   28   const t_uint power_iters = 100;
 
   29   const t_real power_tol = 1e-9;
 
   31   const std::string& weighting_type = 
"natural";
 
   33   auto u = Vector<t_real>::Random(M);
 
   34   auto v = Vector<t_real>::Random(M);
 
   39   uv_vis.
weights = Vector<t_complex>::Random(M);
 
   40   uv_vis.
vis = Vector<t_complex>::Random(M);
 
   41   uv_vis.
units = utilities::vis_units::pixels;
 
   42   std::function<t_real(t_real)> kbu, kbv, ftkbu, ftkbv;
 
   43   std::tie(kbu, kbv, ftkbu, ftkbv) =
 
   46     const Vector<t_complex> input = Vector<t_complex>::Random(ftsizev * ftsizeu);
 
   47     Vector<t_complex> output;
 
   48     Vector<t_complex> new_input;
 
   49     sopt::OperatorFunction<af::array> direct_gpu_fft, indirect_gpu_fft;
 
   50     std::tie(direct_gpu_fft, indirect_gpu_fft) =
 
   51         gpu::operators::init_af_FFT_2d(imsizey, imsizex, oversample_ratio);
 
   52     sopt::OperatorFunction<Vector<t_complex>> fft =
 
   53         gpu::host_wrapper(direct_gpu_fft, input.size(), input.size());
 
   54     sopt::OperatorFunction<Vector<t_complex>> ifft =
 
   55         gpu::host_wrapper(indirect_gpu_fft, input.size(), input.size());
 
   57     ifft(new_input, output);
 
   58     CAPTURE(input.transpose().array() / new_input.transpose().array());
 
   59     CHECK(input.isApprox(new_input, 1e-6));
 
   60     sopt::OperatorFunction<Vector<t_complex>> direct_fft, indirect_fft;
 
   61     std::tie(direct_fft, indirect_fft) =
 
   62         operators::init_FFT_2d<Vector<t_complex>>(imsizey, imsizex, oversample_ratio);
 
   63     const Vector<t_complex> 
direct_input = Vector<t_complex>::Random(ftsizev * ftsizeu);
 
   64     const Vector<t_complex> 
indirect_input = Vector<t_complex>::Random(ftsizev * ftsizeu);
 
   65     Vector<t_complex> output_new;
 
   66     Vector<t_complex> output_old;
 
   69     CHECK(output_old.isApprox(output_new, 1e-6));
 
   72     CHECK(output_old.isApprox(output_new, 1e-6));
 
   75     sopt::OperatorFunction<af::array> direct_gpu_G, indirect_gpu_G;
 
   76     std::tie(direct_gpu_G, indirect_gpu_G) = gpu::operators::init_af_gridding_matrix_2d(
 
   77         uv_vis.
u, uv_vis.
v, Vector<t_complex>::Constant(M, 1.), imsizey, imsizex, oversample_ratio,
 
   79     const sopt::OperatorFunction<Vector<t_complex>> gpu_direct_G =
 
   80         gpu::host_wrapper(direct_gpu_G, ftsizeu * ftsizev, M);
 
   81     const sopt::OperatorFunction<Vector<t_complex>> gpu_indirect_G =
 
   82         gpu::host_wrapper(indirect_gpu_G, M, ftsizeu * ftsizev);
 
   83     sopt::OperatorFunction<Vector<t_complex>> direct_G, indirect_G;
 
   84     std::tie(direct_G, indirect_G) = operators::init_gridding_matrix_2d<Vector<t_complex>>(
 
   85         uv_vis.
u, uv_vis.
v, Vector<t_complex>::Constant(M, 1.), imsizey, imsizex, oversample_ratio,
 
   87     const Vector<t_complex> 
direct_input = Vector<t_complex>::Random(ftsizev * ftsizeu);
 
   88     const Vector<t_complex> 
indirect_input = Vector<t_complex>::Random(M);
 
   89     Vector<t_complex> output_new;
 
   90     Vector<t_complex> output_old;
 
   93     CHECK(output_new.isApprox(output_old, 1e-6));
 
   96     CHECK(output_new.isApprox(output_old, 1e-6));
 
   98   SECTION(
"Zero Padding") {
 
   99     const Image<t_complex> S =
 
  101     CHECK(imsizex == S.cols());
 
  102     CHECK(imsizey == S.rows());
 
  103     sopt::OperatorFunction<Vector<t_complex>> directZ, indirectZ;
 
  104     std::tie(directZ, indirectZ) =
 
  105         operators::init_zero_padding_2d<Vector<t_complex>>(S, oversample_ratio);
 
  106     sopt::OperatorFunction<af::array> directZgpu, indirectZgpu;
 
  107     std::tie(directZgpu, indirectZgpu) =
 
  108         gpu::operators::init_af_zero_padding_2d(S.cast<
t_complexf>(), oversample_ratio);
 
  109     sopt::OperatorFunction<Vector<t_complex>> directZ_gpu =
 
  110         gpu::host_wrapper(directZgpu, imsizex * imsizey, ftsizeu * ftsizev);
 
  111     sopt::OperatorFunction<Vector<t_complex>> indirectZ_gpu =
 
  112         gpu::host_wrapper(indirectZgpu, ftsizeu * ftsizev, imsizex * imsizey);
 
  113     const Vector<t_complex> 
direct_input = Vector<t_complex>::Random(imsizex * imsizey);
 
  114     Vector<t_complex> direct_output_old;
 
  115     Vector<t_complex> direct_output_new;
 
  118     CHECK(direct_output_new.size() == ftsizeu * ftsizev);
 
  119     CHECK(direct_output_old.isApprox(direct_output_new, 1e-6));
 
  120     const Vector<t_complex> 
indirect_input = Vector<t_complex>::Random(ftsizeu * ftsizev);
 
  121     Vector<t_complex> indirect_output_old;
 
  122     Vector<t_complex> indirect_output_new;
 
  125     CHECK(indirect_output_new.size() == imsizex * imsizey);
 
  126     CHECK(indirect_output_old.isApprox(indirect_output_new, 1e-6));
 
  128   SECTION(
"Serial Operator") {
 
  129     const auto measure_op = std::get<2>(sopt::algorithm::normalise_operator<Vector<t_complex>>(
 
  131             uv_vis.
u, uv_vis.
v, uv_vis.
w, uv_vis.
weights, imsizey, imsizex, oversample_ratio,
 
  133         power_iters, power_tol, Vector<t_complex>::Random(imsizex * imsizey)));
 
  135     const auto measure_op_gpu = std::get<2>(sopt::algorithm::normalise_operator<Vector<t_complex>>(
 
  137                                                           uv_vis.
weights, imsizey, imsizex,
 
  138                                                           oversample_ratio, 
kernel, Ju, Jv),
 
  139         power_iters, power_tol, Vector<t_complex>::Random(imsizex * imsizey)));
 
  140     const Vector<t_complex> 
direct_input = Vector<t_complex>::Random(imsizex * imsizey);
 
  141     const Vector<t_complex> direct_output = *measure_op_gpu * 
direct_input;
 
  142     CHECK(direct_output.size() == M);
 
  143     const Vector<t_complex> 
indirect_input = Vector<t_complex>::Random(M);
 
  144     const Vector<t_complex> indirect_output = measure_op_gpu->adjoint() * 
indirect_input;
 
  145     CHECK(indirect_output.size() == imsizex * imsizey);
 
  146     SECTION(
"Power Method") {
 
  147       auto op_norm = std::get<0>(sopt::algorithm::power_method<Vector<t_complex>>(
 
  148           *measure_op, power_iters, power_tol, Vector<t_complex>::Random(imsizex * imsizey)));
 
  149       CHECK(std::abs(op_norm - 1.) < power_tol);
 
  152       const Vector<t_complex> input = Vector<t_complex>::Random(imsizex * imsizey);
 
  153       const Vector<t_complex> expected_output = *measure_op * input;
 
  154       const Vector<t_complex> actual_output = *measure_op_gpu * input;
 
  155       CHECK(expected_output.size() == actual_output.size());
 
  156       CHECK(actual_output.isApprox(expected_output, 1e-4));
 
  159       const Vector<t_complex> input = Vector<t_complex>::Random(M);
 
  160       const Vector<t_complex> expected_output = measure_op->adjoint() * input;
 
  161       const Vector<t_complex> actual_output = measure_op_gpu->adjoint() * input;
 
  162       CHECK(expected_output.size() == actual_output.size());
 
  163       CHECK(actual_output.isApprox(expected_output, 1e-4));
 
#define CHECK(CONDITION, ERROR)
 
const std::vector< t_complex > indirect_input
data for gridding input
 
const std::vector< t_real > u
data for u coordinate
 
const std::vector< t_real > v
data for v coordinate
 
const std::vector< t_complex > direct_input
data for degridding input
 
Image< t_complex > init_correction2d(const t_real &oversample_ratio, const t_uint &imsizey_, const t_uint &imsizex_, const std::function< t_real(t_real)> ftkernelu, const std::function< t_real(t_real)> ftkernelv, const t_real &w_mean, const t_real &cellx, const t_real &celly)
 
std::shared_ptr< sopt::LinearTransform< T > > init_degrid_operator_2d(const Vector< t_real > &u, const Vector< t_real > &v, const Vector< t_real > &w, const Vector< t_complex > &weights, const t_uint &imsizey, const t_uint &imsizex, const t_real &oversample_ratio=2, const kernels::kernel kernel=kernels::kernel::kb, const t_uint Ju=4, const t_uint Jv=4, const bool w_stacking=false, const t_real &cellx=1, const t_real &celly=1)
Returns linear transform that is the standard degridding operator.
 
std::complex< float > t_complexf
 
std::tuple< std::function< t_real(t_real)>, std::function< t_real(t_real)>, std::function< t_real(t_real)>, std::function< t_real(t_real)> > create_kernels(const kernels::kernel kernel_name_, const t_uint Ju_, const t_uint Jv_, const t_real imsizey_, const t_real imsizex_, const t_real oversample_ratio)
 
Vector< t_complex > weights