home *** CD-ROM | disk | FTP | other *** search
- /*
- % vfft_2p -- virtual-very fast fourier transform by size power of 2.
- %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- This software is copyright (C) by the Lawrence Berkeley Laboratory.
- Permission is granted to reproduce this software for non-commercial
- purposes provided that this notice is left intact.
-
- It is acknowledged that the U.S. Government has rights to this software
- under Contract DE-AC03-765F00098 between the U.S. Department of Energy
- and the University of California.
-
- This software is provided as a professional and academic contribution
- for joint exchange. Thus, it is experimental, and is provided ``as is'',
- with no warranties of any kind whatsoever, no support, no promise of
- updates, or printed documentation. By using this software, you
- acknowledge that the Lawrence Berkeley Laboratory and Regents of the
- University of California shall have no liability with respect to the
- infringement of other copyrights by any part of this software.
-
- For further information about this notice, contact William Johnston,
- Bld. 50B, Rm. 2239, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
- (wejohnston@lbl.gov)
-
- For further information about this software, contact:
- Jin Guojun
- Bld. 50B, Rm. 2275, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
- g_jin@lbl.gov
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % Note: No division by total_size is performed and no multiply 2 used so that
- % this median transform is no a standard transform. It is only used for
- % applying filter on frequency domain and transfer back to spatial
- % domain (this is done by performing conjugate on filtered transform,
- % and applying vfft again and dividing by N = size to get final result.
- % The DCVTOB can convert vfft to regular fft format in 2D transform.
- %
- % Timing Consuming:
- %
- % 256 x 256 : 5 - 7 sec (on Sun4 SLC local file server <LFS>)
- % 6 sec (Sun4 sparc 2)
- % 10 sec (Sun4 SLC) - 7 sec [7.0u 0.5s]
- % 15 sec (Sun4 280) - 11 sec [14.0u 0.6s] <LFS>
- % 256 x 256 x 5: 74 sec (Sun4 280) - 54 sec [51.0u 2.4s] <LFS>
- % 48 sec (sparc 2) - 30 sec [29.7u 0.7s]
- % 256 x 256 x 8: 105 sec (Sun4 280)- 97 sec [93.7u 3.8s] <LFS>
- % 63 sec (sparc 2) - 34 sec [32.7u 1.0s]
- % 35 sec (sparc 2) - 33 sec [32.6u 0.8s] <LFS>
- %
- %
- % Routines:
- %
- % FType *re_plane, *im_plane;
- % int loglen, skip;
- %
- % vfft_3d(re_plane, im_plane, logfrms, logrows, logcols)
- % performs a 3-dimensional vfft
- %
- % vfft_2d(re_plane, im_plane, logrows, logcols)
- % performs a 2-dimensional vfft where logrows is the log of the number of
- % rows, and logcols is the log of the number of columns
- %
- % vfftn(re_plane, im_plane, loglen, skip)
- % performs a 1-dimensional vfft on every skip-th entry
- %
- %
- % for double format, put letter 'd' before routine name.
- % example:
- % dfft_2d(...)
- %
- % AUTHOR: Jin Guojun - Lawrence Berkelry Laboratory 5/1/91
- */
-
- #include <math.h>
- #include "imagedef.h"
-
-
- float *w_re,*w_im;
-
- w_init(half)
- MType half;
- {
- w_re = (float*)nzalloc(half, (MType)sizeof(*w_re), "wc");
- w_im = (float*)nzalloc(half, (MType)sizeof(*w_im), "wi");
- }
-
- w_load(n)
- {
- int nv2 = n>>1;
- register float wr, wi;
- register int i;
- static int constsize=0;
- if (constsize != nv2) {
- constsize = nv2;
- wr = cos(2*M_PI/n);
- wi = -sin(2*M_PI/n);
- w_re[0] = 1.;
- w_im[0] = 0.;
- for (i=1; i<nv2; i++) {
- w_re[i] = wr*w_re[i-1] - wi*w_im[i-1];
- w_im[i] = wr*w_im[i-1] + wi*w_re[i-1];
- }
- }
- }
-
-
- vfft(re_plane, im_plane, loglen)
- float *re_plane, *im_plane;
- int loglen;
- {
- w_load(1<<loglen);
- vfftn(re_plane, im_plane, loglen, 1);
- }
-
- vfft_2d(re_plane, im_plane, logrows, logcols)
- float *re_plane, *im_plane;
- int logrows, logcols;
- {
- register int i;
- int rows = 1<<logrows,
- cols = 1<<logcols,
- size = rows * cols;
-
- w_load(cols);
- for (i=0; i<size; i+=cols)
- vfftn(re_plane+i, im_plane+i, logcols, 1);
- w_load(rows);
- for (i=(cols>>1)+1; i--;)
- vfftn(re_plane+i, im_plane+i, logrows, cols);
- }
-
- vrft_2d(re_plane, im_plane, logrows, logcols)
- float *re_plane, *im_plane;
- int logrows, logcols;
- {
- register int i;
- int rows = 1<<logrows,
- cols = 1<<logcols,
- size = rows * cols;
-
- w_load(rows);
- for (i=(cols>>1)+1; i--;)
- vfftn(re_plane+i, im_plane+i, logrows, cols);
- if (cols > 1)
- for (i=0; i<rows; i++){
- register int j;
- register float *re1 = re_plane + i*cols,
- *im1 = im_plane + i*cols;
- for (j=cols>>1; --j;){
- re1[cols-j] = re1[j];
- im1[cols-j] = -im1[j];
- }
- }
- w_load(cols);
- for (i=0; i<size; i+=cols)
- vfftn(re_plane+i, im_plane+i, logcols, 1);
- }
-
- vfftn(re_plane, im_plane, loglen, nskip)
- float *re_plane, *im_plane;
- int loglen;
- register int nskip;
- {
- register int i;
- int n, nv2, nm1, j, k, l, le, le1, c, nle;
- float tr, ti;
- register float *re_x, *re_y, *im_x, *im_y;
-
-
- if(loglen==0) return;
- n=1<<loglen;
- nv2=n >> 1; nm1=n-1; j=0;
-
- for (i=0; i<nm1; i++) {
- register float tmp;
- if(i < j) { /* do swapping */
- re_x=re_plane+i*nskip; re_y=re_plane+j*nskip;
- tmp=(*re_y); *re_y=(*re_x); *re_x=tmp;
- im_x=im_plane+i*nskip; im_y=im_plane+j*nskip;
- tmp=(*im_y); *im_y=(*im_x); *im_x=tmp;
- }
- k = nv2;
- while (k <= j) {
- j -= k; k >>= 1;
- }
- j += k;
- }
-
- le = 1;
- for (l=0; l<loglen; l++) {
- le1 = le;
- le += le;
- nle = n/le;
- for (c=j=0; j<le1; j++) {
- for (i=j; i<n; i+=le) {
- if(i+le1 >= n)
- syserr("fftn: strange index=%d",i+le1);
- re_x=re_plane+i*nskip; re_y=re_plane+(i+le1)*nskip;
- im_x=im_plane+i*nskip; im_y=im_plane+(i+le1)*nskip;
-
- if (c==0) {
- tr = *re_y;
- ti = *im_y;
- }
- else {
- tr = *re_y*w_re[c] - *im_y*w_im[c];
- ti = *re_y*w_im[c] + *im_y*w_re[c];
- }
- *re_y = *re_x - tr;
- *im_y = *im_x - ti;
-
- *re_x += tr;
- *im_x += ti;
- }
- c += nle;
- }
- }
- }
-
- /*=======================================================================
- % below is same routines bu for double (8 bytes) processing %
- =======================================================================*/
-
- double *dw_re,*dw_im;
-
- dw_init(half)
- MType half;
- {
- dw_re = (double*)nzalloc(half, (MType)sizeof(*dw_re), "dwc");
- dw_im = (double*)nzalloc(half, (MType)sizeof(*dw_im), "dwi");
- }
-
- dw_load(n)
- {
- int nv2 = n >> 1;
- register double dwr, dwi;
- register int i;
- static int constsize=0;
- if (constsize != nv2) {
- constsize = nv2;
- dwr = cos(2*M_PI/n);
- dwi = -sin(2*M_PI/n);
- dw_re[0] = 1.;
- dw_im[0] = 0.;
- for (i=1; i<nv2; i++) {
- dw_re[i] = dwr*dw_re[i-1] - dwi*dw_im[i-1];
- dw_im[i] = dwr*dw_im[i-1] + dwi*dw_re[i-1];
- }
- }
- }
-
- dvfft(re_plane, im_plane, loglen)
- double *re_plane, *im_plane;
- int loglen;
- {
- dw_load(1<<loglen);
- vfftn(re_plane, im_plane, loglen, 1);
- }
-
- dvfft_2d(re_plane, im_plane, logrows, logcols)
- double *re_plane, *im_plane;
- int logrows, logcols;
- {
- register int i;
- int rows = 1<<logrows,
- cols = 1<<logcols,
- size = rows * cols;
-
- dw_load(cols);
- for (i=0; i<size; i+=cols)
- vfftn(re_plane+i, im_plane+i, logcols, 1);
- dw_load(rows);
- for (i=(cols>>1)+1; i--;)
- vfftn(re_plane+i, im_plane+i, logrows, cols);
- }
-
- dvrft_2d(re_plane, im_plane, logrows, logcols)
- double *re_plane, *im_plane;
- int logrows, logcols;
- {
- register int i;
- int rows = 1<<logrows,
- cols = 1<<logcols,
- size = rows * cols;
-
- dw_load(rows);
- for (i=(cols>>1)+1; i--;)
- vfftn(re_plane+i, im_plane+i, logrows, cols);
- if (cols > 1)
- for (i=0; i<rows; i++){
- register int j;
- register double *re1 = re_plane + i*cols,
- *im1 = im_plane + i*cols;
- for (j=cols>>1; --j;){
- re1[cols-j] = re1[j];
- im1[cols-j] = -im1[j];
- }
- }
- dw_load(cols);
- for (i=0; i<size; i+=cols)
- vfftn(re_plane+i, im_plane+i, logcols, 1);
- }
-
- dvfftn(re_plane, im_plane, loglen, nskip)
- double *re_plane, *im_plane;
- int loglen;
- register int nskip;
- {
- register int i;
- int n, nv2, nm1, j, k, l, le, le1, c, nle;
- double tr, ti;
- register double *re_x, *re_y, *im_x, *im_y;
-
-
- if(loglen==0) return;
- n=1<<loglen;
- nv2=n >> 1; nm1=n-1; j=0;
-
- for (i=0; i<nm1; i++) {
- register double tmp;
- if(i < j) { /* do swapping */
- re_x=re_plane+i*nskip; re_y=re_plane+j*nskip;
- tmp=(*re_y); *re_y=(*re_x); *re_x=tmp;
- im_x=im_plane+i*nskip; im_y=im_plane+j*nskip;
- tmp=(*im_y); *im_y=(*im_x); *im_x=tmp;
- }
- k = nv2;
- while (k <= j) {
- j -= k; k >>= 1;
- }
- j += k;
- }
-
- le = 1;
- for (l=0; l<loglen; l++) {
- le1 = le;
- le += le;
- nle = n/le;
- for (c=j=0; j<le1; j++) {
- for (i=j; i<n; i+=le) {
- if(i+le1 >= n)
- syserr("fftn: strange index=%d",i+le1);
- re_x=re_plane+i*nskip; re_y=re_plane+(i+le1)*nskip;
- im_x=im_plane+i*nskip; im_y=im_plane+(i+le1)*nskip;
-
- if (c==0) {
- tr = *re_y;
- ti = *im_y;
- }
- else {
- tr = *re_y*dw_re[c] - *im_y*dw_im[c];
- ti = *re_y*dw_im[c] + *im_y*dw_re[c];
- }
- *re_y = *re_x - tr;
- *im_y = *im_x - ti;
-
- *re_x += tr;
- *im_x += ti;
- }
- c += nle;
- }
- }
- }
-