divers.c
来自「Time-Frequency Toolbox,其中包含很常用的MATLAB程序」· C语言 代码 · 共 1,075 行 · 第 1/3 页
C
1,075 行
/*====================================================================*
* this file contains several programs used in a signal processing *
* context. The programs are : *
* - fft : Computes the fast Fourier transform of a complex *
* signal *
* - po2 : Computes the next higher power of two *
* - idx : In a matrix stored like a vector, computes the *
* vector index corresponding to given line and column *
* numbers in the matrix *
* - ifft : Computes the inverse fft *
* - sqr : square of a number *
* - powof : Computes x to the power of alpha *
* - Recover_Signal : In programs used inside the Matlab *
* environement, recovers a signal from a matlab *
* function *
* - gradient : Computes the bidimensional gradient of a surface *
* (called 'field of potential') *
*====================================================================*/
/*====================================================================*
* Name of the function : powof (double) *
* Author : Manuel DAVY - IRCYN *
* Date of creation : 02 - 02 - 1999 *
*--------------------------------------------------------------------*
* Action of the function *
* *
* Computes x^alpha and takes the case x=0 into account *
* !!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!! *
* x must be non-negative when alpha is not an interger *
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! *
*====================================================================*/
double
powof (double x, double alpha)
{
double resu;
if (x >= 0) /* in this case, no problem */
{
if (x == 0)
resu = 0.0;
else
resu = exp (alpha * log (x));
}
else /* there may be problems */
{
if (alpha == (int)(alpha)) /* if alpha is an integer */
{
/* then x^alpha is real-valued */
resu = powof ( -x, alpha);
/* and the sign of the results depends on
wether alpha is ODD or EVEN */
if (ISODD(alpha) == 1)
{
/* alpha is ODD */
resu = -resu;
}
}
else
{
printf ("Attempt to compute x^alpha with x<0 : complex valued result\n");
exit(0);
}
}
return resu;
}
/* *
*====================================================================*
* Name of the function : *
* Author : *
* Date of creation : *
*--------------------------------------------------------------------*
* THE ALGORITHM *
*
*
*====================================================================*
* INPUT VARIABLES *
* Name | type | role *
* | | kernel *
*--------------------------------------------------------------------*
* OUTPUT VARIABLES *
* Name | type | role *
* *
*--------------------------------------------------------------------*
* INTERNAL VARIABLES *
* Name | type | role *
* *
*====================================================================*
* SUBROUTINES USED HERE *
*--------------------------------------------------------------------*
* Name | *
* Action | *
* Place | *
*====================================================================*/
void
fft (int Signal_Length, int Nfft, double *sig_real, double *sig_imag)
{
/*------------------------------------------------------------------*/
/* when the signal length is a power of two */
/*------------------------------------------------------------------*/
if (Signal_Length == (int) powof (2.0, Nfft) + 1)
{
/* local variables */
int i, j, k, n, n2;
double c, s, e, a, t1, t2;
j = 0; /* bit-reverse */
n2 = Signal_Length / 2;
for (i = 1; i < Signal_Length - 1; i++)
{
n = n2;
while (j >= n)
{
j = j - n;
n = n / 2;
}
j = j + n;
if (i < j)
{
t1 = sig_real[i];
sig_real[i] = sig_real[j];
sig_real[j] = t1;
t1 = sig_imag[i];
sig_imag[i] = sig_imag[j];
sig_imag[j] = t1;
}
}
n = 0; /* FFT */
n2 = 1;
for (i = 0; i < Nfft; i++)
{
n = n2;
n2 = n2 + n2;
e = -6.283185307179586 / n2;
a = 0.0;
for (j = 0; j < n; j++)
{
c = cos (a);
s = sin (a);
a = a + e;
for (k = j; k < Signal_Length; k = k + n2)
{
t1 = c * sig_real[k + n] - s * sig_imag[k + n];
t2 = s * sig_real[k + n] + c * sig_imag[k + n];
sig_real[k + n] = sig_real[k] - t1;
sig_imag[k + n] = sig_imag[k] - t2;
sig_real[k] = sig_real[k] + t1;
sig_imag[k] = sig_imag[k] + t2;
}
}
}
}
/*------------------------------------------------------------------*/
/* when the signal length is NOT a power of two */
/* Calls the matlab subroutine fft */
/*------------------------------------------------------------------*/
else
{
int num_out, num_in, i;
mxArray *outputArray[1];
mxArray *inputArray[1];
mxArray *array_ptr;
num_out = 1;
num_in = 1;
/* recopy the real and imag parts of the signal in matrices */
array_ptr = mxCreateDoubleMatrix (1, Signal_Length, mxCOMPLEX);
memcpy (mxGetPr (array_ptr), sig_real, Signal_Length * sizeof (double));
memcpy (mxGetPi (array_ptr), sig_imag, Signal_Length * sizeof (double));
inputArray[0] = array_ptr;
/* calls the MATLAB function */
mexCallMATLAB (num_out, outputArray, num_in, inputArray, "fft");
memcpy (sig_real, mxGetPr (outputArray[0]), Signal_Length * sizeof (double));
if (mxIsComplex (outputArray[0]))
{
memcpy (sig_imag, mxGetPi (outputArray[0]), Signal_Length * sizeof (double));
}
else
{
for (i = 0; i < Signal_Length; i++)
sig_imag[i] = 0;
}
/* free memory */
mxDestroyArray (outputArray[0]);
mxDestroyArray (inputArray[0]);
}
return;
}
/*====================================================================*
* Name of the function : po2 (int) *
* Author : *
* Date of creation : *
*--------------------------------------------------------------------*
* Action of the function *
* Computes the next power of to of an integer n, i.e. *
* the smallest k such that m=2^k>=n *
*====================================================================*/
int
po2 (int n)
{
int nextpo2, m;
m = 1;
nextpo2 = 0;
while (m < n)
{
++nextpo2;
m = m + m;
}
return (nextpo2);
}
/*====================================================================*
* Name of the function : sinc (double) *
* Author : Emmanuel ROY *
* Date of creation : 22 - 06 - 1999 *
*--------------------------------------------------------------------*
* Action of the function *
* Computes the sinc function of a number, defined by : *
* *
* for any x in R, *
* *
* / *
* | 1 if x = 0 *
* | *
* sinc(x) = | sin (pi * x) *
* | ------------ if x != 0 *
* | pi * x *
* \ *
* *
*====================================================================*/
double sinc (double x)
{
double resu;
if (x == 0)
resu = 1.0;
else
resu = sin(pi*x)/(pi*x);
return resu;
}
/*====================================================================*
* Name of the function : irem (double x, double y) *
* Author : Emmanuel ROY *
* Date of creation : 22 - 06 -1999 *
*--------------------------------------------------------------------*
* Action of the function *
* *
* Computes the remainder after Euclidean division of two doubles *
* *
*====================================================================*/
int irem( double x, double y)
{
int result;
if (y != 0)
{
result = x-y* (int)(x/y);
}
else
{
result = 0;
printf("irem.c : attempt to divide by 0\n");
}
return result;
}
/*====================================================================*
* Name of the function : idx (int i_row, int j_col, int nb_row) *
* Author : Emmanuel ROY *
* Date of creation : *
*--------------------------------------------------------------------*
* Action of the function *
* *
* The matrices are stored as vectors, column by column *
* This program computes the vector index corresponding to the *
* specified line number (line), the column number (col) and the *
* number of lines (nb_line) *
*====================================================================*/
int
idx (int i_row, int j_col, int nb_row)
{
if (i_row >= nb_row)
{
printf("idx : incorrect row number\n");
return 0;
exit(0);
}
else
{
return (i_row + (j_col * nb_row));
}
}
/* *
*====================================================================*
* Name of the function : *
* Author : *
* Date of creation : *
*--------------------------------------------------------------------*
* THE ALGORITHM *
*
*
*====================================================================*
* INPUT VARIABLES *
* Name | type | role *
* | | kernel *
*--------------------------------------------------------------------*
* OUTPUT VARIABLES *
* Name | type | role *
* *
*--------------------------------------------------------------------*
* INTERNAL VARIABLES *
* Name | type | role *
* *
*====================================================================*
* SUBROUTINES USED HERE *
*--------------------------------------------------------------------*
* Name | *
* Action | *
* Place | *
*====================================================================*/
void
ifft (int Signal_Length, int Nfft, double *sig_real, double *sig_imag)
{
/*------------------------------------------------------------------*/
/* when the signal length is a power of two */
/*------------------------------------------------------------------*/
if (Signal_Length == (int) powof (2, Nfft) + 1)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?