This file is indexed.

/usr/share/yorick/i0/yeti_fftw.i is in yorick-yeti-fftw 6.3.1-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/*
 * yeti_fftw.i --
 *
 *	Implement support for FFTW, the "fastest Fourier transform in the
 *	West", in Yorick.
 *
 *-----------------------------------------------------------------------------
 *
 *	Copyright (C) 2003-2006 Eric Thi��baut.
 *
 *	This file is part of Yeti.
 *
 *	Yeti is  free software;  you can redistribute  it and/or  modify it
 *	under  the terms of  the GNU  General Public  License version  2 as
 *	published by the Free Software Foundation.
 *
 *	Yeti is distributed in the hope that it will be useful, but WITHOUT
 *	ANY WARRANTY; without even  the implied warranty of MERCHANTABILITY
 *	or FITNESS  FOR A PARTICULAR  PURPOSE.  See the GNU  General Public
 *	License for more details.
 *
 *	You should have  received a copy of the  GNU General Public License
 *	along with  Yeti (file "COPYING"  in the top source  directory); if
 *	not, write to  the Free Software Foundation, Inc.,  51 Franklin St,
 *	Fifth Floor, Boston, MA 02110-1301 USA
 *
 *-----------------------------------------------------------------------------
 *
 * History:
 *	$Id: yeti_fftw.i,v 1.6 2007/04/30 14:27:07 eric Exp $
 *	$Log: yeti_fftw.i,v $
 *	Revision 1.6  2007/04/30 14:27:07  eric
 *	 - Fixed typo in documentation.
 *
 *	Revision 1.5  2006/07/19 15:13:56  eric
 *	 - Copyright notice updated.
 *
 *	Revision 1.4  2005/05/24 13:40:00  eric
 *	 - Make it as a Yorick package: "yeti_fftw".
 *
 *	Revision 1.3  2005/05/24 13:17:23  eric
 *	 - fixed typo in doc
 *	 - fixed fftw_dist
 *	 - make code loadable as a plugin
 *
 *	Revision 1.2  2003/04/25 23:44:34  eric
 *	 - New functions: fftw_indgen, fftw_dist, and fftw_smooth.
 *	 - Change keyword names in fftw_convolve according to fftw_smooth.
 *
 *	Revision 1.1  2003/04/25 10:20:47  eric
 *	Initial revision
 */

/* load dynamic code */
if (is_func(plug_in)) plug_in, "yeti_fftw";

extern fftw_plan;
/* DOCUMENT fftw_plan(dimlist, dir)
     Creates a  plan for fast Fourier  transforming by fftw  (which see) of
     arrays of dimension  list DIMLIST.  DIR=+/-1 and has  the same meaning
     as in fft (which see):

        DIR  meaning                1-D discrete Fourier transform
        ---  ---------------------  ------------------------------
         +1  "forward" transform    sum_k x(k)*exp(-i*2*PI*k*l/N)
         -1  "backward" transform   sum_k x(k)*exp(+i*2*PI*k*l/N)

     where i=sqrt(-1).   Except when keyword  REAL is true (se  below), the
     name "forward"  or "backward" is  only a question of  convention, only
     the sign of the complex exponent really matters.

     If keyword  REAL is  true, then  the result is  a plan  for a  real to
     complex  transform if  DIR=+1 ("forward")  or  for a  complex to  real
     transform if  DIR=-1 ("backward").   The result of  a real  to complex
     transform contains only half of  the complex DFT amplitudes (since the
     negative-frequency amplitudes for real  data are the complex conjugate
     of  the   positive-frequency  amplitudes).   If  the   real  array  is
     N1xN2x...xNn then the result is  a complex (N1/2 + 1)xN2x...xNn array.
     Reciprocally,  the   complex  to  real  transform  takes   a  (N1/2  +
     1)xN2x...xNn complex input array to compute a N1xN2x...xNn real array.
     When  the plan is  created with  REAL set  to true,  DIMS must  be the
     dimension list of the real array  and DIR must be +1 ("forward") for a
     real to  complex transform and -1  ("backward") for a  complex to real
     transform.

     If keyword  MEASURE is  true, then FFTW  attempts to find  the optimal
     plan by actually computing several FFT's and measuring their execution
     time.  The  default is to not  run any FFT and  provide a "reasonable"
     plan  (for  a  RISC  processor  with many  registers).   Computing  an
     efficient plan for FFTW (with keyword MEASURE set to true) may be very
     expensive.  FFTW  is therefore mostly advantageous  when several FFT's
     of arrays with  same dimension lists are to be  computed; in this case
     the user should save the plan in a variable, e.g.:

         plan_for_x_and_dir = fftw_plan(dimsof(x), dir, measure=1);
         for (...) {
           ...;
           fft_of_x = fftw(x, plan_for_x_and_dir);
           ...;
         }

     instead of:

         for (...) {
           ...;
           fft_of_x = fftw(x, fftw_plan(dimsof(x), dir, measure=1));
           ...;
         }

     However note that it is relatively inexpensive to compute a plan for
     the default strategy; therefore:

         for (...) {
           ...;
           fft_of_x = fftw(x, fftw_plan(dimsof(x), dir));
           ...;
         }

     is not too inefficient (this is what does cfftw).


  SEE ALSO fftw, fft, fft_setup. */

extern fftw;
func cfftw(x, dir) { return fftw(x, fftw_plan(dimsof(x), dir)); }
/* DOCUMENT  fftw(x, plan)
       -or- cfftw(x, dir)
     Computes the  fast Fourier  transform of X  with the  "fastest Fourier
     transform in the West".

     The fftw function makes use of PLAN that has been created by fftw_plan
     (which  see)  and  computes a  real  to  complex  or complex  to  real
     transform,  if  PLAN  was  created  with keyword  REAL  set  to  true;
     otherwise, fftw computes a complex transform.

     The cfftw function  always computes a complex transform  and creates a
     temporary plan for  the dimensions of X and  FFT direction DIR (+/-1).
     If  you  want to  compute  seral  FFT's  of identical  dimensions  and
     directions, or if  you want to compute real to  complex (or complex to
     real)  transforms, or if  you want  to use  the "measure"  strategy in
     defining FFTW plan, you should rather use fftw_plan and fftw.

   SEE ALSO fftw_plan. */

func fftw_indgen(dim) { return (u= indgen(0:dim-1)) - dim*(u > dim/2); }
/* DOCUMENT fftw_indgen(len)
     Return FFT frequencies along a dimension of length LEN.
   SEE ALSO: indgen, span, fftw_dist. */

func fftw_dist(.., nyquist=, square=, half=)
/* DOCUMENT fftw_dist(dimlist);
     Returns Euclidian lenght of spatial frequencies in frequel units for a
     FFT of dimensions DIMLIST.

     If keyword  NYQUIST is true,  the frequel coordinates get  rescaled so
     that the Nyquist frequency is  equal to NYQUIST along every dimension.
     This is obtained by using coordinates:
        (2.0*NYQUIST/DIM(i))*fft_indgen(DIM(i))
     along i-th dimension of lenght DIM(i).

     If  keyword  SQUARE is  true,  the square  of  the  Euclidian norm  is
     returned instead.

     If keyword HALF  is true, the length is only computed  for half of the
     spatial frequencies so that it can be used with a real to complex FFTW
     forward transform (the first dimension becomes DIM(1)/2 + 1).

   SEE ALSO: fftw, fftw_indgen. */
{
  /* Build dimension list. */
  local arg, dims;
  while (more_args()) {
    eq_nocopy, arg, next_arg();
    if ((s = structof(arg)) == long || s == int || s == short || s == char) {
      /* got an integer array */
      if (! (n = dimsof(arg)(1))) {
        /* got a scalar */
        grow, dims, arg;
      } else if (n == 1 && (n = numberof(arg) - 1) == arg(1)) {
        /* got a vector which is a valid dimension list */
        if (n) grow, dims, arg(2:);
      } else {
        error, "bad dimension list";
      }
    } else if (! is_void(arg)) {
      error, "unexpected data type in dimension list";
    }
  }
  if (! (n = numberof(dims))) return 0.0; /* scalar array */
  if (min(dims) <= 0) error, "negative value in dimension list";

  /* Build square radius array one dimension at a time, starting with the
     last dimension. */
  local r2;
  if (is_void(nyquist)) {
    for (k=n ; k>=1 ; --k) {
      u = double((k==1 && half ? indgen(0:dims(k)/2) : fftw_indgen(dims(k))));
      r2 = (k<n ? r2(-,..) + u*u : u*u);
    }
  } else {
    s = 2.0*nyquist;
    for (k=n ; k>=1 ; --k) {
      dim = dims(k);
      u = (s/dim)*(k==1 && half ? indgen(0:dim/2) : fftw_indgen(dim));
      r2 = (k<n ? r2(-,..) + u*u : u*u);
    }
  }
  return (square ? r2 : sqrt(r2));
}

func fftw_smooth(a, fwhm, fp=, bp=)
/* DOCUMENT fftw_smooth(a, fwhm)
     Returns  array A  smoothed  along  all its  dimensions  by a  discrete
     convolution by  a gaussian with full  width at half  maximum equals to
     FWHM (in "pixel" units).

     Keywords FP and  BP may be used to specify FFTW  plans for the forward
     and/or backward transforms respectively  (which must have been created
     with REAL set to true if and only if A is a real array).

   SEE ALSO: fftw, fftw_plan. */
{
  /*
   * The FFT of a Gaussian of given FWHM is:
   *    exp(-pi^2*fwhm^2*(k/dim)^2/log(16))
   *  where K is the FFT index; hence:
   *    Nyquist = sqrt(pi^2*fwhm^2*(dim/2/dim)^2/4/log(2))
   *            = pi*fwhm/4/sqrt(log(2))
   *            ~ 0.9433593338763967992*fwhm
   */
  dims = dimsof(a);
  real = (structof(a) != complex);
  u = fftw_dist(dims, square=1, nyquist=0.9433593338763967992*fwhm, half=real);
  return fftw((1.0/numberof(a))*exp(-u)
              *fftw(a, (is_void(fp) ? fftw_plan(dims, 1, real=real) : fp)),
              (is_void(bp) ? fftw_plan(dims, -1, real=real) : bp));
}

func fftw_convolve(orig, psf, do_not_roll, fp=, bp=)
/* DOCUMENT fftw_convolve(orig, psf);
       -or- fftw_convolve(orig, psf, do_not_roll);
     Return discrete convolution (computed by  FFTW) of array ORIG by point
     spread  function PSF  (ORIG and  PSF must  have same  dimension list).
     Unless argument  DO_NOT_ROLL is true, PSF is  rolled before.

     Keywords FP and  BP may be used to specify FFTW  plans for the forward
     and/or backward transforms respectively  (which must have been created
     with REAL  set to true  if and  only if _both_  ORIG and PSF  are real
     arrays).

   SEE ALSO: fftw, fftw_plan, roll. */
{
  dims = dimsof(orig);
  real = (structof(orig) != complex && structof(psf) != complex);
  if (is_void(fp)) fp = fftw_plan(dims, +1, real=real);
  p = fftw(fftw(orig, fp)*fftw((do_not_roll?psf:roll(psf)), fp),
           (is_void(bp) ? fftw_plan(dims, -1, real=real) : bp));
  return (1.0/numberof(p))*p;
}

/*---------------------------------------------------------------------------*
 * Local Variables:                                                          *
 * mode: Yorick                                                              *
 * tab-width: 8                                                              *
 * fill-column: 75                                                           *
 * coding: latin-1                                                           *
 * End:                                                                      *
 *---------------------------------------------------------------------------*/