⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tfft.cpp

📁 信号处理的时頻富立叶变换
💻 CPP
字号:
/**************************************************************
* Program to demonstrate the Fast Fourier Transform Procedure *
*      (frequency analysis of a discreet signal F(t))         *
*                                                             *
*                         C++ version by J-P Moreau, Paris    *
*                                                             *
*     To be used with basi_r.cpp and wmblock.cpp found in     *
*     MATRICES directory.                                     *
* ----------------------------------------------------------- *
* SAMPLE RUN:                                                 *
*                                                             *
* Input data file (tfft.dat):                                 *
*                                                             *
* (The test signal contains 3 frequencies: 50, 250, 500 hz)   *
*                                                             * 
* 1024                                                        *
* 0.00000000000000E+0000   0.00000000000000E+0000             *
* 1.95503421309917E-0004   3.53914399999776E+0001             *
* 3.91006842619834E-0004   5.95684899999760E+0001             *
* 5.86510263929974E-0004   6.54621699999552E+0001             *
* 7.82013685239669E-0004   5.24038399999845E+0001             *
* ...                      ...                                *
* 1.98826979472187E-0001   2.77372500000183E-0001             *
* 1.99022482893497E-0001  -2.43361500000174E+0000             *
* 1.99217986314807E-0001  -4.84236799999780E+0000             *
* 1.99413489736116E-0001  -6.02247899999929E+0000             *
* 1.99608993157426E-0001  -5.45615399999951E+0000             *
* 1.99804496578736E-0001  -3.22824200000105E+0000             *
* 2.00000000000045E-0001  -2.96010699999982E-0003             *
*                                                             *
* Output file (tfft.lst):                                     *
*                                                             *
*   Frequency     Value                                       *
* ------------------------                                    *
*      0.00      0.271690                                     *
*      5.00      0.546336                                     *
*      9.99      0.555560                                     *
*     14.99      0.572242                                     *
*     19.98      0.598828                                     *
*     24.98      0.640061                                     *
*   ...          ...                                          *
*   2522.53      0.020520                                     *
*   2527.53      0.020518                                     *
*   2532.52      0.020516                                     *
*   2537.52      0.020513                                     *
*   2542.51      0.020512                                     *
*   2547.51      0.020511                                     *
*   2552.50      0.020511                                     *
*                                                             *
* ----------------------------------------------------------- *
* To link with files basis_r.cpp and vmblock.cpp (see direc-  *
* tory: C++/Matrices).                                        *                                         
**************************************************************/
#include <stdio.h>
#include <math.h>
#include <basis.h>     // ABS, MACH_EPS, REAL, WriteEnd(), WriteHead()   
#include <vmblock.h>   // dynamic allocations


FILE  *f_in,*f_out;
int   i,ip,n1,ndata;
REAL  df,dt,f,temp,tbegin,tend,y;
REAL  *signal;         // pointer to real vector
REAL  **A;             // pointer to matrix (complex vector)  
void  *vmblock;

 //complex numbers utility functions

 //returns real part of a complex number z
 double Re(double z[2])
 {
   return z[0];
 }

 //returns imaginary part of a complex number z
 double Im(double z[2])
 {
   return z[1];
 }

 //adds up to complex numbers (z1+z2)
 void Sum(double z1[2],double z2[2],double z1_plus_z2[2])
 {
   z1_plus_z2[0]=z1[0]+z2[0];
   z1_plus_z2[1]=z1[1]+z2[1];
 }

 //z1-z2
 void InvSum(double z1[2],double z2[2],double z1_z2[2])
 {
   z1_z2[0]=z1[0]-z2[0];
   z1_z2[1]=z1[1]-z2[1];
 }

 //z1*z2
 void Prod(double z1[2],double z2[2],double z1xz2[2])
 {
   double a1,a2,b1,b2;
   a1= Re(z1);
   b1= Im(z1);
   a2= Re(z2);
   b2= Im(z2);
   z1xz2[0]=a1*a2-b1*b2;
   z1xz2[1]=a1*b2+a2*b1;
 }

 /**************************************************************
 *             FAST FOURIER TRANSFORM PROCEDURE                *
 * ----------------------------------------------------------- *
 * This procedure calculates the fast Fourier transform of a   *
 * real function sampled in N points 0,1,....,N-1. N must be a *
 * power of two (2 power M).                                   *
 *  T being the sampling duration, the maximum frequency in    *
 * the signal can't be greater than fc = 1/(2T). The resulting *
 * specter H(k) is discreet and contains the frequencies:      *
 *         fn = k/(NT) with k = -N/2,.. -1,0,1,2,..,N/2.       *
 *         H(0) corresponds to null fr閝uency.                 *
 *         H(N/2) corresponds to fc frequency.                 * 
 * ----------------------------------------------------------- *
 * INPUTS:                                                     *
 *                                                             *
 *     A[i][2]  complex vector of size N, the real part of     *
 *              which contains the N sampled points of real    *
 *              signal to analyse (time spacing is constant).  *
 *                                                             *
 *          M   integer such as N=2^M                          *
 *                                                             *
 * OUTPUTS:                                                    *
 *                                                             *
 *     A[i][2]  complex vector of size N, the vector modulus   *
 *              contain the frequencies of input signal, the   *
 *              vector angles contain the corresponding phases *
 *              (not used here).                               *
 *                                                             *
 *                                     J-P Moreau/J-P Dumont   *
 **************************************************************/
void FFT(REAL **A, int M)  {
    
    const double pi=3.1415926535;
    double U[2],W[2],T[2];            //complex numbers
    int N,NV2,NM1,J,I,IP,K,L,LE,LE1;
    double Phi;

    N=(2 << (M-1));
    NV2=(N >> 1);
    NM1=N-1;
    J=1;
    for (I=1;I<=NM1;I++) {
      if (I<J) {
	    T[0]=A[J-1][0]; 
	    T[1]=A[J-1][1];
	    A[J-1][0]=A[I-1][0]; 
	    A[J-1][1]=A[I-1][1];
	    A[I-1][0]=T[0]; 
	    A[I-1][1]=T[1];
      }
      K=NV2;
      while (K<J) {
	    J=J-K;
	    K=(K >> 1);
      }
      J=J+K;
    }

    LE=1;
    for (L=1;L<=M;L++) {
      LE1=LE;
      LE=(LE << 1);
      U[0]=1.0;
      U[1]=0.0;
      Phi= pi/LE1;
      W[0] = cos(Phi);
      W[1] = sin(Phi);

      for (J=1;J<=LE1;J++)  {
	    I=J-LE;
	    while (I< N-LE) {
	      I=I+LE;
	      IP=I+LE1;
	      Prod(A[IP-1],U,T);
	      InvSum(A[I-1],T,A[IP-1]);
	      Sum(A[I-1],T,A[I-1]);
	    }
	    Prod(U,W,U);
      }
    }
    for (I=0;I<N;I++)  {
      A[I][0]=A[I][0]/N;
      A[I][1]=A[I][1]/N;
    }

} //FFT()


void main()  {
  // open input and output file
  f_in=fopen("tfft.dat","r");
  f_out=fopen("tfft.lst","w");
  //read number of input signal points in input file
  fscanf(f_in,"%d",&ndata);
  //take nearest power of two
  if (ndata > 2048) {ndata=2048; ip=11;}
  if (ndata < 2048 && ndata>1023) {ndata=1024; ip=10;}
  if (ndata < 1024 && ndata>511) {ndata=512; ip=9;}
  if (ndata <  512 && ndata>255) {ndata=256; ip=8;}
  if (ndata <  256 && ndata>127) {ndata=128; ip=7;}
  if (ndata <  128 && ndata> 63) {ndata=64; ip=6;}
  if (ndata <   64 && ndata> 31) {ndata=32; ip=5;}
  if (ndata <   32) {
    fprintf(f_out," Error: number of points too small (<32) !\n");
    fclose(f_out);
    printf(" Results in file tfft.lst (error).\n");
  }
  //Allocate memory space for A[ndata][2] and signal[ndata]
  vmblock = vminit();
  A      = (REAL **)vmalloc(vmblock, MATRIX, ndata, 2);
  signal = (REAL *) vmalloc(vmblock, VEKTOR, ndata, 0);
  if (! vmcomplete(vmblock)) {
    LogError ("Memory full!", 0, __FILE__, __LINE__);
    return;
  }	  
  
  //read ndata couples T(i), Y(i) in input data file
  for (i=0; i<ndata; i++) {
    fscanf(f_in,"%lf %lf",&temp,&y);
    signal[i] = y;
    if (i==0)  tbegin=temp;
    if (i==ndata-1)  tend=temp;
  }
  // Put input signal in real part of complex vector A
  for (i=0; i<ndata; i++) {
    A[i][0]=signal[i];
    A[i][1]=0.0;
  }
  // call FFT procedure
  FFT(A,ip);
  // get frequencies in signal real vector
  n1=ndata/2;
  for (i=0; i<n1; i++) {
    temp= sqrt(A[i][0]*A[i][0]+A[i][1]*A[i][1]);
    if (i>0)  temp=2*temp;
    signal[i]=temp;
  }

  // calculate sampling time range dt
  dt=(tend-tbegin)/(ndata-1);
  // calculate frequency step df
  df= 1.0/(ndata*dt);
  // print frequency specter to output file
  f=0.0;
  fprintf(f_out,"   Frequency     Value   \n");
  fprintf(f_out," ------------------------\n");
  for (i=0; i<n1; i++) {
    fprintf(f_out,"  %8.2f  %12.6f\n",f,signal[i]);
    f+=df;
  }
  fclose(f_out);
  free(vmblock);
  printf("\n Results in file tfft.lst.\n");

}

// End of file tfft.cpp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -