diff --git a/w-stacking.cu b/w-stacking.cu index 4fe36254789fff354e28fb887a5d4bb6c3b37704..d5e8e8ca5aa849f7601ae2566f0ec799b558c3da 100644 --- a/w-stacking.cu +++ b/w-stacking.cu @@ -14,12 +14,51 @@ double __device__ #else double #endif +// Gaussian Kernel gauss_kernel_norm(double norm, double std22, double u_dist, double v_dist) { double conv_weight; conv_weight = norm * exp(-((u_dist*u_dist)+(v_dist*v_dist))*std22); return conv_weight; } + +// Kaiser-Bessel Kernel: it is adapted from WSClean +double bessel0(double x, double precision) { + // Calculate I_0 = SUM of m 0 -> inf [ (x/2)^(2m) ] + // This is the unnormalized bessel function of order 0. + double d = 0.0, ds = 1.0, sum = 1.0; + do { + d += 2.0; + ds *= x * x / (d * d); + sum += ds; + } while (ds > sum * precision); + return sum; +} +void makeKaiserBesselKernel(double * kernel, + int KernelLen, + double alpha, + double overSamplingFactor, + int withSinc) { + int n = KernelLen, mid = n / 2; + double * sincKernel = malloc((mid + 1)*sizeof(*sincKernel)); + const double filterRatio = 1.0 / overSamplingFactor; + sincKernel[0] = filterRatio; + for (int i = 1; i != mid + 1; i++) { + double x = i; + sincKernel[i] = + withSinc ? (sin(PI * filterRatio * x) / (PI * x)) : filterRatio; + } + const double normFactor = overSamplingFactor / bessel0(alpha, 1e-8); + for (int i = 0; i != mid + 1; i++) { + double term = (double)i / mid; + kernel[mid + i] = sincKernel[i] * + bessel0(alpha * sqrt(1.0 - (term * term)), 1e-8) * + normFactor; + } + for (int i = 0; i != mid; i++) kernel[i] = kernel[n - 1 - i]; +} + + #ifdef ACCOMP #pragma omp end declare target #endif