2 #include "purify/config.h"
11 t_real alpha = 2.34 * J;
19 if (2 * x > J)
return 0;
21 return boost::math::cyl_bessel_i(0, std::real(alpha * std::sqrt(1 - a * a))) /
22 boost::math::cyl_bessel_i(0, alpha);
30 t_complex eta = std::sqrt(
32 const t_real normalisation = J / boost::math::cyl_bessel_i(0, alpha);
34 return std::real(std::sin(eta) / eta) *
45 t_real alpha = 2.34 * J;
49 t_real
gaussian(
const t_real x,
const t_real J) {
56 t_real sigma = 0.31 * std::pow(J, 0.52);
67 t_real sigma = 0.31 * std::pow(J, 0.52);
71 t_real
calc_for_pswf(
const t_real eta0,
const t_real J,
const t_real alpha) {
73 const std::array<t_real, 6> p1 = {
74 {8.203343e-2, -3.644705e-1, 6.278660e-1, -5.335581e-1, 2.312756e-1, 2 * 0.0}};
75 const std::array<t_real, 6> p2 = {
76 {4.028559e-3, -3.697768e-2, 1.021332e-1, -1.201436e-1, 6.412774e-2, 2 * 0.0}};
77 const std::array<t_real, 3> q1 = {{1., 8.212018e-1, 2.078043e-1}};
78 const std::array<t_real, 3> q2 = {{1., 9.599102e-1, 2.918724e-1}};
80 if (J != 6 or alpha != 1) {
86 auto fraction = [](t_real eta, std::array<t_real, 6>
const &p, std::array<t_real, 3>
const &q) {
87 auto const p_size =
sizeof(p) /
sizeof(p[0]) - 1;
88 auto const q_size =
sizeof(q) /
sizeof(q[0]) - 1;
90 auto numerator = p[p_size];
91 for (
auto i = decltype(p_size){1}; i <= p_size; ++i)
92 numerator = eta * numerator + p[p_size - i];
94 auto denominator = q[q_size];
95 for (
auto i = decltype(q_size){1}; i <= q_size; ++i)
96 denominator = eta * denominator + q[q_size - i];
98 return numerator / denominator;
100 if (0 <= std::abs(eta0) and std::abs(eta0) <= 0.75)
101 return fraction(eta0 * eta0 - 0.75 * 0.75, p1, q1);
102 if (0.75 < std::abs(eta0) and std::abs(eta0) <= 1)
return fraction(eta0 * eta0 - 1 * 1, p2, q2);
107 t_real
pswf(
const t_real x,
const t_real J) {
119 const t_real eta0 = 2 * x / J;
120 const t_real alpha = 1;
121 return calc_for_pswf(eta0, J, alpha) * std::pow(1 - eta0 * eta0, alpha);
124 t_real
ft_pswf(
const t_real x,
const t_real J) {
138 const t_real alpha = 1;
139 const t_real eta0 = 2 * x;
145 const std::function<t_real(t_real)> kernelu) {
150 std::vector<t_real> samples(total_samples);
151 for (Vector<t_real>::Index i = 0; i < static_cast<t_int>(total_samples); ++i) {
152 samples[i] = kernelu(
static_cast<t_real
>(i) / total_samples);
161 const t_int total_samples = samples.size();
163 const t_real i_effective = 2 * std::abs(x) * total_samples / J;
165 const t_real i_0 = std::floor(i_effective);
166 if (i_0 < 0 or i_0 >= total_samples)
return 0.;
168 return samples[
static_cast<t_int
>(i_0)];
176 t_int total_samples = samples.size();
178 t_real i_effective = (x + J / 2) * total_samples / J;
180 t_int i_0 = floor(i_effective);
181 t_int i_1 = ceil(i_effective);
183 if (std::abs(i_0 - i_1) == 0) {
189 if (i_0 < 0 or i_0 >= total_samples) {
194 if (i_1 < 0 or i_1 >= total_samples) {
199 t_real output = y_0 + (y_1 - y_0) / (i_1 - i_0) * (i_effective - i_0);
209 return 1. /
static_cast<t_real
>(J);
229 t_real a = x / sigma;
230 return std::exp(-a * a * 0.5) / (sigma * std::sqrt(2 *
constant::pi));
242 t_real a = x * sigma;
243 return std::exp(a * a * 2);
247 std::tuple<std::function<t_real(t_real)>, std::function<t_real(t_real)>,
248 std::function<t_real(t_real)>, std::function<t_real(t_real)>>
250 const t_real imsizey_,
const t_real imsizex_,
const t_real oversample_ratio) {
253 const t_uint ftsizev_ = std::floor(imsizey_ * oversample_ratio);
254 const t_uint ftsizeu_ = std::floor(imsizex_ * oversample_ratio);
256 PURIFY_ERROR(
"Error: Only a support of 6 is implemented for PSWFs.");
257 throw std::runtime_error(
"Incorrect input: PSWF requires a support of 6");
259 switch (kernel_name_) {
265 return std::make_tuple(kbu, kbv, ftkbu, ftkbv);
270 throw std::runtime_error(
"Ju and Jv must be the same support size for presampling kernels.");
277 return std::make_tuple(kbu, kbv, ftkbu, ftkbv);
281 const t_real kb_interp_alpha_Ju =
282 constant::pi * std::sqrt(Ju_ * Ju_ / (oversample_ratio * oversample_ratio) *
283 (oversample_ratio - 0.5) * (oversample_ratio - 0.5) -
285 const t_real kb_interp_alpha_Jv =
286 constant::pi * std::sqrt(Jv_ * Jv_ / (oversample_ratio * oversample_ratio) *
287 (oversample_ratio - 0.5) * (oversample_ratio - 0.5) -
289 auto kbu = [=](
const t_real x) {
292 auto kbv = [=](
const t_real x) {
295 auto ftkbu = [=](
const t_real x) {
298 auto ftkbv = [=](
const t_real x) {
301 return std::make_tuple(kbu, kbv, ftkbu, ftkbv);
305 auto pswfu = [=](
const t_real x) {
return kernels::pswf(x, Ju_); };
306 auto pswfv = [=](
const t_real x) {
return kernels::pswf(x, Jv_); };
307 auto ftpswfu = [=](
const t_real x) {
return kernels::ft_pswf(x / ftsizeu_ - 0.5, Ju_); };
308 auto ftpswfv = [=](
const t_real x) {
return kernels::ft_pswf(x / ftsizev_ - 0.5, Jv_); };
309 return std::make_tuple(pswfu, pswfv, ftpswfu, ftpswfv);
317 return std::make_tuple(gaussu, gaussv, ftgaussu, ftgaussv);
325 return std::make_tuple(boxu, boxv, ftboxu, ftboxv);
329 const t_real sigma = 1;
333 auto ftgaussu = [=](
const t_real x) {
336 auto ftgaussv = [=](
const t_real x) {
339 return std::make_tuple(gaussu, gaussv, ftgaussu, ftgaussv);
343 throw std::runtime_error(
"Did not choose valid kernel.");
348 const kernels::kernel kernel_name_,
const t_uint Ju_,
const t_real oversample_ratio) {
352 PURIFY_ERROR(
"Error: Only a support of 6 is implemented for PSWFs.");
353 throw std::runtime_error(
"Incorrect input: PSWF requires a support of 6");
355 switch (kernel_name_) {
357 return std::make_tuple(
363 const t_real kb_interp_alpha_Ju =
364 constant::pi * std::sqrt(Ju_ * Ju_ / (oversample_ratio * oversample_ratio) *
365 (oversample_ratio - 0.5) * (oversample_ratio - 0.5) -
367 auto kbuv = [=](
const t_real x) {
370 auto ftkbuv = [=](
const t_real x) {
373 return std::make_tuple(ftkbuv, kbuv);
377 return std::make_tuple(
378 [=](
const t_real x) {
return kernels::ft_pswf(x,
static_cast<t_real
>(Ju_)); },
383 return std::make_tuple(
389 return std::make_tuple(
395 throw std::runtime_error(
"Did not choose valid radial kernel.");
#define PURIFY_ERROR(...)
\macro Something is definitely wrong, algorithm exits
#define PURIFY_MEDIUM_LOG(...)
Medium priority message.
const t_real pi
mathematical constant
t_real ft_kaiser_bessel(const t_real x, const t_real J)
Fourier transform of kaiser bessel kernel.
t_real ft_gaussian_general(const t_real x, const t_real J, const t_real sigma)
Fourier transform of general Gaussian kernel.
std::vector< t_real > kernel_samples(const t_int total_samples, const std::function< t_real(t_real)> kernelu)
Calculates samples of a kernel.
t_real kaiser_bessel(const t_real x, const t_real J)
Kaiser-Bessel kernel.
t_real kernel_zero_interp(const std::vector< t_real > &samples, const t_real x, const t_real J)
zeroth order interpolates from samples of kernel
t_real pill_box(const t_real x, const t_real J)
Box car function for kernel.
t_real ft_pswf(const t_real x, const t_real J)
Fourier transform of PSWF kernel.
t_real gaussian_general(const t_real x, const t_real J, const t_real sigma)
Fourier transform of general Gaussian kernel.
t_real kaiser_bessel_general(const t_real x, const t_real J, const t_real alpha)
More general Kaiser-Bessel kernel.
t_real calc_for_pswf(const t_real eta0, const t_real J, const t_real alpha)
Calculates Horner's Rule the standard PSWF for radio astronomy, with a support of J = 6 and alpha = 1...
t_real ft_pill_box(const t_real x, const t_real J)
Fourier transform of box car function, a Sinc function.
t_real gaussian(const t_real x, const t_real J)
Gaussian kernel.
t_real kernel_linear_interp(const Vector< t_real > &samples, const t_real x, const t_real J)
linearly interpolates from samples of kernel
t_real pswf(const t_real x, const t_real J)
PSWF kernel.
t_real ft_gaussian(const t_real x, const t_real J)
Fourier transform of Gaussian kernel.
t_real ft_kaiser_bessel_general(const t_real x, const t_real J, const t_real alpha)
Fourier transform of more general Kaiser-Bessel kernel.
std::tuple< std::function< t_real(t_real)>, std::function< t_real(t_real)> > create_radial_ftkernel(const kernels::kernel kernel_name_, const t_uint Ju_, const t_real oversample_ratio)
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)