File: wkernel.cc

package info (click to toggle)
purify 5.0.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 186,836 kB
  • sloc: cpp: 17,731; python: 510; xml: 182; makefile: 7; sh: 6
file content (137 lines) | stat: -rw-r--r-- 6,355 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "purify/config.h"
#include "catch2/catch_all.hpp"
#include "purify/logging.h"

#include "purify/types.h"

#include "purify/directories.h"
#include "purify/kernels.h"
#include "purify/wide_field_utilities.h"
#include "purify/wkernel_integration.h"

using namespace purify;
using Catch::Approx;

TEST_CASE("test transform kernels") {
  SECTION("horizon bound check for 2d transform") {
    REQUIRE(projection_kernels::fourier_wproj_kernel(0, 0, 0, 0, 0, 1, 1).real() == Approx(1));
    REQUIRE(std::abs(projection_kernels::fourier_wproj_kernel(2, 2, 0, 0, 0, 1, 1)) == Approx(0));
    REQUIRE(std::abs(projection_kernels::fourier_wproj_kernel(0.4, 0, 0, 0, 0, 0.3, 0.3)) ==
            Approx(0));
  }
}
TEST_CASE("calculating zero") {
  const t_real cell = 30;
  const t_int imsize = 1024;
  const t_real absolute_error = 1e-9;
  t_uint const J = 4;
  const t_real oversample_ratio = 2;
  const t_real du = widefield::pixel_to_lambda(cell, imsize, oversample_ratio);
  auto const normu = [=](const t_real l) -> t_real { return kernels::ft_kaiser_bessel(l, J); };

  const t_uint max_evaluations = 1e9;
  const t_real relative_error = 0;
  t_uint e;
  const t_real norm2d = std::sqrt(std::abs(projection_kernels::exact_w_projection_integration(
      0, 0, 0, du, du, oversample_ratio, normu, normu, 1e9, 0, 1e-12, integration::method::h, e)));
  const t_real norm1d = std::abs(projection_kernels::exact_w_projection_integration_1d(
      0, 0, 0, du, oversample_ratio, normu, 1e9, 0, 1e-12, integration::method::h, e));
  auto const ftkernelu = [=](const t_real l) -> t_real {
    return kernels::ft_kaiser_bessel(l, J) / norm2d;
  };
  auto const ftkernelv = [=](const t_real l) -> t_real {
    return kernels::ft_kaiser_bessel(l, J) / norm1d;
  };
  t_uint total = 0;
  t_uint rtotal = 0;
  t_int const Ju = J;
  t_real const upsample = 2;
  const t_int Ju_max = std::floor(Ju * upsample * 0.5);
  SECTION("+u") {
    for (int j = 0; j < Ju_max; j++) {
      t_uint evaluations = 0;
      t_uint revaluations = 0;
      t_uint e;
      const t_real u = j / upsample;
      CAPTURE(u);
      const t_complex kernel2d = projection_kernels::exact_w_projection_integration(
          u, 0, 0, du, du, oversample_ratio, ftkernelu, ftkernelu, max_evaluations, absolute_error,
          absolute_error, integration::method::h, evaluations);
      const t_complex kernel1d = projection_kernels::exact_w_projection_integration_1d(
          u, 0, 0, du, oversample_ratio, ftkernelv, max_evaluations, absolute_error, absolute_error,
          integration::method::h, evaluations);
      CHECK(kernel2d.real() ==
            Approx(kernels::kaiser_bessel(0, J) * kernels::kaiser_bessel(u, J)).margin(1e-4));
      CHECK(kernel2d.imag() == Approx(0.).margin(1e-5));
      CHECK(kernel1d.imag() == Approx(0.).margin(1e-5));
    }
  }
  SECTION("-u") {
    for (int j = 0; j < Ju_max; j++) {
      t_uint evaluations = 0;
      t_uint revaluations = 0;
      t_uint e;
      const t_real u = j / upsample;
      CAPTURE(u);
      const t_complex kernel2d = projection_kernels::exact_w_projection_integration(
          -u, 0, 0, du, du, oversample_ratio, ftkernelu, ftkernelu, max_evaluations, absolute_error,
          absolute_error, integration::method::h, evaluations);
      CHECK(kernel2d.real() ==
            Approx(kernels::kaiser_bessel(0, J) * kernels::kaiser_bessel(-u, J)).margin(1e-4));
      CHECK(kernel2d.imag() == Approx(0.).margin(1e-5));
    }
  }
  SECTION("+/-w relation") {
    const t_real w = 100.;
    for (int j = 0; j < Ju_max; j++) {
      t_uint evaluations = 0;
      t_uint revaluations = 0;
      t_uint e;
      const t_real u = j / upsample;
      CAPTURE(u);
      const t_complex kernel2d = projection_kernels::exact_w_projection_integration(
          u, 0, w, du, du, oversample_ratio, ftkernelu, ftkernelu, max_evaluations, absolute_error,
          absolute_error, integration::method::h, evaluations);
      const t_complex kernel1d = projection_kernels::exact_w_projection_integration_1d(
          u, 0, w, du, oversample_ratio, ftkernelv, max_evaluations, absolute_error, absolute_error,
          integration::method::h, evaluations);
      const t_complex kernel2d_conj = projection_kernels::exact_w_projection_integration(
          u, 0, -w, du, du, oversample_ratio, ftkernelu, ftkernelu, max_evaluations, absolute_error,
          absolute_error, integration::method::h, evaluations);
      const t_complex kernel1d_conj = projection_kernels::exact_w_projection_integration_1d(
          u, 0, -w, du, oversample_ratio, ftkernelv, max_evaluations, absolute_error,
          absolute_error, integration::method::h, evaluations);
      CHECK(kernel2d.real() == Approx(kernel2d_conj.real()).margin(1e-4));
      CHECK(kernel2d.imag() == Approx(-kernel2d_conj.imag()).margin(1e-4));
      CHECK(kernel1d.real() == Approx(kernel1d_conj.real()).margin(1e-4));
      CHECK(kernel1d.imag() == Approx(-kernel1d_conj.imag()).margin(1e-4));
    }
  }
  SECTION("window function") {
    for (int j = 0; j < Ju_max; j++) {
      t_uint evaluations = 0;
      t_uint revaluations = 0;
      t_uint e;
      const t_real u = j / upsample;
      CAPTURE(u);
      const t_complex kernel2d = projection_kernels::exact_w_projection_integration(
          u, 0, 0, du, du, oversample_ratio, [](t_real) { return 1.; }, [](t_real) { return 1.; },
          max_evaluations, 1e-5, 1e-5, integration::method::h, evaluations);
      const t_complex kernel1d = projection_kernels::exact_w_projection_integration_1d(
          u + 1e-4, 0, 0, du, oversample_ratio, [](t_real) { return 1.; }, max_evaluations, 1e-5,
          1e-5, integration::method::h, evaluations);
      // analytical results from theory
      const t_real expected2d = boost::math::sinc_pi(2 * constant::pi * u * 2. / oversample_ratio);
      const t_real expected1d =
          boost::math::cyl_bessel_j(1, 2 * constant::pi * (u + 1e-4) * 2. / oversample_ratio) /
          ((u + 1e-4) * 2. / oversample_ratio);
      CAPTURE(du);
      CAPTURE(kernel2d / expected2d);
      CAPTURE(kernel1d / expected1d);
      CHECK(kernel2d.real() == Approx(expected2d).margin(1e-6));
      CHECK(kernel2d.imag() == Approx(0).margin(1e-6));
      CHECK(kernel1d.real() == Approx(expected1d).margin(1e-6));
      CHECK(kernel1d.imag() == Approx(0).margin(1e-6));
    }
  }
}