3 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #include <gsl/gsl_errno.h>
25 #include <gsl/gsl_math.h>
26 #include <gsl/gsl_sf_bessel.h>
27 #include <gsl/gsl_dht.h>
31 gsl_dht_alloc (size_t size)
36 GSL_ERROR_VAL("size == 0", GSL_EDOM, 0);
39 t = (gsl_dht *)malloc(sizeof(gsl_dht));
42 GSL_ERROR_VAL("out of memory", GSL_ENOMEM, 0);
47 t->xmax = -1.0; /* Make it clear that this needs to be calculated. */
50 t->j = (double *)malloc((size+2)*sizeof(double));
54 GSL_ERROR_VAL("could not allocate memory for j", GSL_ENOMEM, 0);
57 t->Jjj = (double *)malloc(size*(size+1)/2 * sizeof(double));
62 GSL_ERROR_VAL("could not allocate memory for Jjj", GSL_ENOMEM, 0);
65 t->J2 = (double *)malloc((size+1)*sizeof(double));
71 GSL_ERROR_VAL("could not allocate memory for J2", GSL_ENOMEM, 0);
77 /* Handle internal calculation of Bessel zeros. */
79 dht_bessel_zeros(gsl_dht * t)
85 for(s=1; s < t->size + 2; s++) {
86 stat_z += gsl_sf_bessel_zero_Jnu_e(t->nu, s, &z);
90 GSL_ERROR("could not compute bessel zeroes", GSL_EFAILED);
98 gsl_dht_new (size_t size, double nu, double xmax)
102 gsl_dht * dht = gsl_dht_alloc (size);
107 status = gsl_dht_init(dht, nu, xmax);
116 gsl_dht_init(gsl_dht * t, double nu, double xmax)
119 GSL_ERROR ("xmax is not positive", GSL_EDOM);
120 } else if(nu < 0.0) {
121 GSL_ERROR ("nu is negative", GSL_EDOM);
125 int stat_bz = GSL_SUCCESS;
130 /* Recalculate Bessel zeros if necessary. */
132 stat_bz = dht_bessel_zeros(t);
135 jN = t->j[t->size+1];
141 for(m=1; m<t->size+1; m++) {
143 stat_J += gsl_sf_bessel_Jnu_e(nu + 1.0, t->j[m], &J);
144 t->J2[m] = J.val * J.val;
147 /* J_nu(j[n] j[m] / j[N]) = Jjj[n(n-1)/2 + m - 1], 1 <= n,m <= size
149 for(n=1; n<t->size+1; n++) {
150 for(m=1; m<=n; m++) {
151 double arg = t->j[n] * t->j[m] / jN;
153 stat_J += gsl_sf_bessel_Jnu_e(nu, arg, &J);
154 t->Jjj[n*(n-1)/2 + m - 1] = J.val;
159 GSL_ERROR("error computing bessel function", GSL_EFAILED);
168 double gsl_dht_x_sample(const gsl_dht * t, int n)
170 return t->j[n+1]/t->j[t->size+1] * t->xmax;
174 double gsl_dht_k_sample(const gsl_dht * t, int n)
176 return t->j[n+1] / t->xmax;
180 void gsl_dht_free(gsl_dht * t)
190 gsl_dht_apply(const gsl_dht * t, double * f_in, double * f_out)
192 const double jN = t->j[t->size + 1];
193 const double r = t->xmax / jN;
197 for(m=0; m<t->size; m++) {
200 for(i=0; i<t->size; i++) {
201 /* Need to find max and min so that we
202 * address the symmetric Jjj matrix properly.
203 * FIXME: we can presumably optimize this
204 * by just running over the elements of Jjj
205 * in a deterministic manner.
217 Y = t->Jjj[n_local*(n_local+1)/2 + m_local] / t->J2[i+1];
220 f_out[m] = sum * 2.0 * r*r;