Update copyright date; remove old CVS keyword
[ctsim.git] / include / fourier.h
1 /*****************************************************************************
2 ** FILE IDENTIFICATION
3 **
4 **   Name:          fourier.h
5 **   Purpose:       Header for Fourier transform functions
6 **   Programmer:    Kevin Rosenberg
7 **   Date Started:  Dec 2000
8 **
9 **  This is part of the CTSim program
10 **  Copyright (c) 1983-2009 Kevin Rosenberg
11 **
12 **  This program is free software; you can redistribute it and/or modify
13 **  it under the terms of the GNU General Public License (version 2) as
14 **  published by the Free Software Foundation.
15 **
16 **  This program is distributed in the hope that it will be useful,
17 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 **  GNU General Public License for more details.
20 **
21 **  You should have received a copy of the GNU General Public License
22 **  along with this program; if not, write to the Free Software
23 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 ******************************************************************************/
25
26 #include <complex>
27 #ifdef HAVE_FFTW
28 #include <fftw3.h>
29 #endif
30
31 class ImageFile;
32
33 class Fourier {
34 public:
35     static void shuffleFourierToNaturalOrder (ImageFile& im);
36     static void shuffleNaturalToFourierOrder (ImageFile& im);
37
38 #ifdef HAVE_FFTW
39     static void shuffleFourierToNaturalOrder (fftw_complex* pc, const int n);
40     static void shuffleNaturalToFourierOrder (fftw_complex* pc, const int n);
41 #endif
42
43 // Odd Number of Points
44 //   Natural Frequency Order: -(n-1)/2...-1,0,1...(n-1)/2
45 //   Fourier Frequency Order: 0, 1..(n-1)/2,-(n-1)/2...-1
46 // Even Number of Points
47 //   Natural Frequency Order: -n/2...-1,0,1...((n/2)-1)
48 //   Fourier Frequency Order: 0,1...((n/2)-1),-n/2...-1
49     template<class T>
50     static void shuffleNaturalToFourierOrder (T* pVector, const int n)
51     {
52       T* pTemp = new T [n];
53       int i;
54       if (isOdd(n)) { // Odd
55         int iHalfN = (n - 1) / 2;
56
57         pTemp[0] = pVector[iHalfN];
58         for (i = 0; i < iHalfN; i++)
59           pTemp[i + 1] = pVector[i + 1 + iHalfN];
60         for (i = 0; i < iHalfN; i++)
61           pTemp[i + iHalfN + 1] = pVector[i];
62       } else {     // Even
63         int iHalfN = n / 2;
64         pTemp[0] = pVector[iHalfN];
65         for (i = 0; i < iHalfN - 1; i++)
66         pTemp[i + 1] = pVector[i + iHalfN + 1];
67         for (i = 0; i < iHalfN; i++)
68           pTemp[i + iHalfN] = pVector[i];
69       }
70
71     for (i = 0; i < n; i++)
72       pVector[i] = pTemp[i];
73     delete pTemp;
74   }
75
76   template<class T>
77   static void shuffleFourierToNaturalOrder (T* pVector, const int n)
78   {
79     T* pTemp = new T [n];
80     int i;
81     if (isOdd(n)) { // Odd
82       int iHalfN = (n - 1) / 2;
83
84       pTemp[iHalfN] = pVector[0];
85       for (i = 0; i < iHalfN; i++)
86         pTemp[i + 1 + iHalfN] = pVector[i + 1];
87       for (i = 0; i < iHalfN; i++)
88         pTemp[i] = pVector[i + iHalfN + 1];
89     } else {     // Even
90       int iHalfN = n / 2;
91       pTemp[iHalfN] = pVector[0];
92       for (i = 0; i < iHalfN; i++)
93         pTemp[i] = pVector[i + iHalfN];
94       for (i = 0; i < iHalfN - 1; i++)
95         pTemp[i + iHalfN + 1] = pVector[i+1];
96     }
97
98     for (i = 0; i < n; i++)
99       pVector[i] = pTemp[i];
100     delete pTemp;
101   }
102 #if 0
103     static void shuffleNaturalToFourierOrder (float* pdVector, const int n);
104     static void shuffleNaturalToFourierOrder (double* pdVector, const int n);
105     static void shuffleNaturalToFourierOrder (std::complex<double>* pdVector, const int n);
106     static void shuffleFourierToNaturalOrder (float* pdVector, const int n);
107     static void shuffleFourierToNaturalOrder (double* pdVector, const int n);
108     static void shuffleFourierToNaturalOrder (std::complex<double>* pdVector, const int n);
109 #endif
110 };
111
112