Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FFT.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #include "FFT.hh"
27 
28 #include <Base/Debug/Error.hh>
29 
30 #include <complex>
31 #include <iomanip>
32 
33 using namespace BIAS;
34 using namespace std;
35 
37 {
38  _Size=0;
39  _in=NULL;
40  _out=NULL;
41  _p=NULL;
42 }
43 
45 {
46  Release();
47 }
48 
49 void FFT::Init(int size)
50 {
51 #ifdef BIAS_DEBUG
52  if (_Size!=0 || _InputSize!=0 || _OutNum!=0 || _out || _in || _p){
53  BIASERR ("FFT: call Release() before calling Init() a second time");
54  BIASEXIT(EXIT_FAILURE, "call Release() before calling Init() a second time");
55  }
56 #endif
57  _Size=size;
58  _InputSize=_Size*sizeof(double);
59  _OutNum=(_Size>>1)+1;
60  _out =(fftw_complex*)fftw_malloc(sizeof(fftw_complex) * _OutNum);
61  _in = (double*)fftw_malloc(sizeof(double) * _Size);
62  // this is slow a few seconds
63  _p = fftw_plan_dft_r2c_1d(_Size, _in, _out, FFTW_MEASURE);
64 }
65 
67 {
68  if (_p) fftw_destroy_plan(_p);
69  if (_in) fftw_free(_in);
70  if (_out) fftw_free(_out);
71  _in=NULL;
72  _out=NULL;
73  _p=NULL;
74  _Size=_InputSize=_OutNum=0;
75 }
76 
77 void FFT::Compute(double *in)
78 {
79  memcpy((void *)_in, (void *)in, _InputSize);
80  fftw_execute(_p);
81 }
82 
84 {
85 #ifdef BIAS_DEBUG
86  if ((int)in.Size()!=_Size){
87  BIASERR ("called FFT::Compute() with vector of wrong size "<<in.Size());
88  BIASEXIT(EXIT_FAILURE, "called FFT::Compute() with vector of wrong size "<<in.Size());
89  }
90 #endif
91  Compute(in.GetData());
92 }
93 
94 void FFT::GetPhase(double *phase)
95 {
96  complex<double> *p=reinterpret_cast<complex<double> *>(_out), *e=p+_OutNum;
97  double *m=phase;
98  while (p<e) {
99  *m=arg(*p);
100  m++;
101  p++;
102  }
103 }
104 
105 void FFT::GetMagnitude(double *mag)
106 {
107  complex<double> *p=reinterpret_cast<complex<double> *>(_out), *e=p+_OutNum;
108  double *m=mag;
109  while (p<e) {
110  *m=abs(*p);
111  m++;
112  p++;
113  }
114 }
115 
117 {
118  if ((int)phase.Size()!=_OutNum){
119  phase.newsize(_OutNum);
120  }
121  complex<double> *p=reinterpret_cast<complex<double> *>(_out);
122  for (int i=0; i<_OutNum; i++){
123  phase[i]=arg(p[i]);
124  }
125 }
126 
128 {
129  if ((int)mag.Size()!=_OutNum){
130  mag.newsize(_OutNum);
131  }
132  complex<double> *p=reinterpret_cast<complex<double> *>(_out);
133  for (int i=0; i<_OutNum; i++){
134  mag[i]=abs(p[i]);
135  }
136 }
137 
138 void FFT::DumpResult(std::ostream& os)
139 {
140  Vector<double> mag, phase;
141  GetMagnitude(mag);
142  GetPhase(phase);
143  os << "#result of fft: "<<endl;
144  os <<setw(4)<<"#num"<<setw(15)<<"freq"<<setw(15)<<"mag"<<setw(15)
145  <<"phase"<<endl;
146  for (int i=0; i<_OutNum; i++){
147  os <<setw(4)<<i
148  <<setw(15)<<(double)i/(double)_Size
149  <<setw(15)<<mag[i]
150  <<setw(15)<<phase[i]<<"\n";
151  }
152 
153 // os << "# pipe outputt into file: my_program_with_FFT > tmp.dat"<<endl
154 // << "# and view with gnuplot : echo \"plot \\\"tmp.dat\\\" u 2:3 t \\\"magnitude\\\" w l, \\\"tmp.dat\\\" u 2:4 t \\\"phase\\\" w l; pause 99999;\" |gnuplot"<<endl;
155 
156 }
void GetMagnitude(double *mag)
returns the resulting magnitude, mag must be of length size/2+1 (rounded downwards) ...
Definition: FFT.cpp:105
void Release()
cal this before a second call to Init()
Definition: FFT.cpp:66
FFT()
Definition: FFT.cpp:36
unsigned int Size() const
length of the vector
Definition: Vector.hh:143
Vector< T > & newsize(Subscript N)
Definition: vec.h:220
void Init(int size)
initializes the internal variables.
Definition: FFT.cpp:49
T * GetData() const
get the pointer to the data array of the vector (for faster direct memory access) ...
Definition: Vector.hh:219
void DumpResult(std::ostream &os=std::cout)
Definition: FFT.cpp:138
void Compute()
input must be filled before with GetInput
Definition: FFT.hh:82
void GetPhase(double *phase)
returns the resulting phase, phase must be of length size/2+1 (rounded downwards) ...
Definition: FFT.cpp:94
~FFT()
Definition: FFT.cpp:44