2018-01-18 13:22:27 +02:00
|
|
|
#include "bessels.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <math.h>
|
2018-01-18 14:55:15 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2018-01-18 13:22:27 +02:00
|
|
|
|
2018-01-23 07:38:02 +02:00
|
|
|
static const double ln2 = 0.693147180559945309417;
|
2018-01-18 13:22:27 +02:00
|
|
|
|
|
|
|
|
2018-01-18 14:55:15 +02:00
|
|
|
// general; gives an array of size xxx with TODODESC
|
2018-01-18 13:22:27 +02:00
|
|
|
complex double * hankelcoefftable_init(size_t maxn) {
|
|
|
|
complex double *hct = malloc((maxn+1)*(maxn+2)/2 * sizeof(complex double));
|
|
|
|
for(size_t n = 0; n <= maxn; ++n) {
|
|
|
|
complex double *hcs = hankelcoeffs_get(hct,n);
|
|
|
|
for (size_t k = 0; k <= n; ++k) {
|
|
|
|
double lcoeff = lgamma(n+k+1) - lgamma(n-k+1) - lgamma(k+1) - k*ln2;
|
|
|
|
// for some reason, casting k-n to double does not work,so
|
|
|
|
// cpow (I, k-n-1) cannot be used...
|
|
|
|
complex double ifactor;
|
|
|
|
switch ((n+1-k) % 4) {
|
|
|
|
case 0:
|
|
|
|
ifactor = 1;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
ifactor = -I;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
ifactor = -1;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
ifactor = I;
|
|
|
|
break;
|
2018-08-27 07:50:37 +03:00
|
|
|
default:
|
|
|
|
abort();
|
2018-01-18 13:22:27 +02:00
|
|
|
}
|
|
|
|
// the result should be integer, so round to remove inaccuracies
|
|
|
|
hcs[k] = round(exp(lcoeff)) * ifactor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return hct;
|
|
|
|
}
|
|
|
|
|
2018-01-18 14:55:15 +02:00
|
|
|
void hankelparts_fill(complex double *lrt, complex double *srt, size_t maxn,
|
2018-05-14 06:52:32 +03:00
|
|
|
size_t lrk_cutoff, complex double const * const hct,
|
2018-01-18 14:55:15 +02:00
|
|
|
unsigned kappa, double c, double x) {
|
2018-01-23 07:38:02 +02:00
|
|
|
if (lrt) memset(lrt, 0, (maxn+1)*sizeof(complex double));
|
2018-01-18 14:55:15 +02:00
|
|
|
memset(srt, 0, (maxn+1)*sizeof(complex double));
|
|
|
|
double regularisator = pow(1. - exp(-c * x), (double) kappa);
|
|
|
|
double antiregularisator = 1. - regularisator;
|
|
|
|
double xfrac = 1.; // x ** (-1-k)
|
|
|
|
for (size_t k = 0; k <= maxn; ++k) {
|
|
|
|
xfrac /= x;
|
2018-05-14 06:52:32 +03:00
|
|
|
for(size_t n = k; n <= maxn; ++n) // TODO Kahan sums here
|
2018-01-18 14:55:15 +02:00
|
|
|
srt[n] += ((k<lrk_cutoff) ? antiregularisator : 1)
|
|
|
|
* xfrac * hankelcoeffs_get(hct,n)[k];
|
2018-01-23 07:38:02 +02:00
|
|
|
if (lrt && k < lrk_cutoff) for (size_t n = k; n <= maxn; ++n)
|
2018-01-18 14:55:15 +02:00
|
|
|
lrt[n] += regularisator * xfrac * hankelcoeffs_get(hct,n)[k];
|
|
|
|
}
|
|
|
|
|
|
|
|
complex double expix = cexp(I * x);
|
2018-01-23 07:38:02 +02:00
|
|
|
for(size_t n = 0; n <= maxn; ++n)
|
|
|
|
srt[n] *= expix;
|
|
|
|
if (lrt) for(size_t n = 0; n <= maxn; ++n)
|
2018-01-18 14:55:15 +02:00
|
|
|
srt[n] *= expix;
|
|
|
|
}
|