主要是使用FFTW库进行zfft分析中遇到的问题。
参考1
参考2
参考3
void firstfft(complex<double>*input, complex<double>*output, int N,int nf)//第一次fft,一般N
{
fftw_complex*in= (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nf);
fftw_complex*out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nf);
fftw_plan p = fftw_plan_dft_1d(nf, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
int i;
for (i = 0; i < N; i++) {
in[i][0] = input[i].real();
in[i][1] = input[i].imag();
}
for (i = N; i < nf; i++) {
in[i][0] = 0;
in[i][1] = 0;
}
fftw_execute(p);
for (i = 0; i < nf; i++) {
output[i].real(out[i][0]);
output[i].imag(out[i][1]);
}
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
}
这里使用的是fftw库中一维复数的dft转换。当然在使用该函数前,需要包含头文件fftw3.h还有complex。
参数说明:
n – 复数数据点数
in/out – 输入数据和输出数据,可以相同(原位相同)
sign – FFTW_FORWARD(-1)正变换 FFTW_BACKWORD(+1) 逆变换
flags – 主要有两个参数 FFTW_MEASURE/FFTW_ESTIMATE
FFTW_MEASURE 先进行预处理,对大数据(数据长度不变)连续FFT变化效果明显
FFTW_ESTIMATE 直接构造一个次最优的方案,非连续 实时选择这种方案
另外,与matlab中的fft对应关系可以参考下文:
参考4
最值得注意的应该就是C++中plan_backward时,结果要除以n才可以和matlab中的ifft对应上。而fft不用管,和matlab中的fft是一样的。
C++的complex类使用需要包含头文件complex,fftw中自带fftw_complex类可供使用。
参考5
参考6
参考6.二、1.数据类型中有具体介绍。
可以在变换时使用fftw_complex类,其余时候使用complex类。
complex赋值:
1.采用无名对象方式: c = complex(3.2,-6);
2.初始化时赋值:complex <double> c(3.2,-6);
3.成员函数方式: c[i].real(1);c[i].imag(2);
不可直接写 c[i].real=1
fftw_complex类赋值比较直接:
c[i][0]=1;c[i][1]=2;
这里的0位代表实部,1代表虚部。
参考7
结论:for循环中,当不用&&和||申明多个条件时,默认的是或者关系。
参考8
未知所需的内存空间时,可以用new来创建变量。
C++中不允许int a[n],但可以用
int*a=new int [n];
在使用数组完毕后,可用指令释放它所占用的内存,如
delete[]a;
使用时要注意new和delete一般搭配使用,否则容易造成内存泄漏(即无用的数据过多,影响程序的运行速度)。
参考9
void random(double*out, int n)
{
srand(time(0)); //设置时间种子
double*a = new double[n];
int i;
for (int i = 0; i < n; i++) {
a[i] = rand() % (1001);//生成区间0~1000的随机数
}
for (i = 0; i < n; i++) {
out[i] = a[i] * 0.001;
}
delete[]a;
}
6.成品
在main中实现了zfft(细化谱分析),但最后一个fft,即fftagain出来的数据与matlab中的不一样,还不知道原因。知道了再更新一下!
#include
#include //头文件
#include
#include
#include
#include
#include
using namespace std;
int main()
{
void zfft(double *x, complex<double>*y, double fi, int fs, int length, int nf, int nfft, int np);
void random(double*out, int n);
void signalmove(double* in, complex<double>* out, int N, double fi, double fa, int fs);
void firstfft(complex<double>*input, complex<double>*output, int N, int nf);
void lowpassfilter(complex<double>*in, complex<double>*out, int na, int nf);
void fftbackward(complex<double>*input, complex<double>*output, int nf);
void sortagain(complex<double>*in, complex<double>*out, int np, int N);
void fftagain(complex<double>*input, complex<double>*output, int orilength,int nfft);
void allocatedata(complex<double>*in, complex<double>*out, int nfft);
int N = 10000;//N为数据长度
double fi = 10;
int nf = 16384;
int nfft = 1024;
int fs = 300;
int np = 8;
double pi = 3.1416;//初始化数据
int i;
double* t = new double[N];
for (i = 0; i < N; i++) {
t[i] = i*1.0/ fs;
}//时间序列
for (i = 0; i < 10; i++) {
cout << t[i] << " ";
}
cout << endl;
double *x=new double[N];//模拟信号离散序列
for (i = 0; i < N; i++) {
x[i] = sin(2 * pi * 5 * t[i]) + sin(2 * pi * 20 * t[i]);
}
for (i = 0; i < 10; i++) {
cout << x[i] << " ";
}
cout << endl;
delete[]t;
complex<double> *y = new complex<double>[nfft/2];
zfft(x, y, fi, fs, N, nf, nfft, np);
delete[]x;
return 0;
}
void signalmove(double* in, complex<double>* out, int N,double fi,double fa,int fs)//移频
{
double *n = new double[N];
int j;
for (j = 0; j < N; j++) {
n[j] = 3.1416 * (fi+fa)/fs * j;
out[j].real(in[j] * cos(n[j]));
out[j].imag(in[j] * ((-1)*sin(n[j])));
}
delete[]n;
}
void firstfft(complex<double>*input, complex<double>*output, int N,int nf)//第一次fft,一般N
{
fftw_complex*in= (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nf);
fftw_complex*out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nf);
fftw_plan p = fftw_plan_dft_1d(nf, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
int i;
for (i = 0; i < N; i++) {
in[i][0] = input[i].real();
in[i][1] = input[i].imag();
}
for (i = N; i < nf; i++) {
in[i][0] = 0;
in[i][1] = 0;
}
fftw_execute(p);
for (i = 0; i < nf; i++) {
output[i].real(out[i][0]);
output[i].imag(out[i][1]);
}
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
}
void lowpassfilter(complex<double>*in, complex<double>*out, int na, int nf)//低通滤波,取两头,中间补零
{
int i;
for (i = 0; i < na; i++) {
out[i].real(in[i].real());
out[i].imag(in[i].imag());
}
for (i = na; i < nf - na; i++) {
out[i].real(0);
out[i].imag(0);
}
for (i = nf-na; i < nf; i++) {
out[i].real(in[i].real());
out[i].imag(in[i].imag());
}
}
void fftbackward(complex<double>*input, complex<double>*output, int nf)//ifft
{
fftw_complex*in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nf);
fftw_complex*out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nf);
fftw_plan p = fftw_plan_dft_1d(nf, in, out, FFTW_BACKWARD, FFTW_ESTIMATE);
int i;
for (i = 0; i < nf; i++) {
in[i][0] = input[i].real();
in[i][1] = input[i].imag();
}
fftw_execute(p);
for (i = 0; i < nf; i++) {
output[i].real(out[i][0]/nf);
output[i].imag(out[i][1]/nf);
}
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
}
void sortagain(complex<double>*in, complex<double>*out, int np,int N)//重采样
{
int i;
int j;
for (i = 0,j=0; i < N&&j<N/np; i = i + np,j++) {
out[j].real(in[i].real());
out[j].imag(in[i].real());
}
}
void fftagain(complex<double>*input, complex<double>*output,int orilength,int nfft) //再一次fft
{
fftw_complex*in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*orilength);
fftw_complex*out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*nfft);
fftw_plan p = fftw_plan_dft_1d(nfft, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
int i;
for (i = 0; i < orilength; i++) {
in[i][0] = input[i].real();
in[i][1] = input[i].imag();
}
fftw_execute(p);
for (i = 0; i < nfft; i++) {
output[i].real(out[i][0]);
output[i].imag(out[i][1]);
}
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
}
void allocatedata(complex<double>*in, complex<double>*out, int nfft)
{
int i;
int j;
for (i = 0,j=(int)0.75*nfft; i < nfft / 4&&j<nfft; i++,j++) {
out[i].real(in[j].real());
out[i].imag(in[j].imag());
}
for (i = nfft / 4,j=0; i < nfft/2&&j<nfft/4; i++,j++) {
out[i].real(in[j].real());
out[i].imag(in[j].imag());
}
}
void zfft(double *x, complex<double>*y, double fi, int fs, int length, int nf,int nfft, int np)
//fi细化最低频率
//fs采样频率
//length原始数据长度
//nf 首次fft长度
//nfft再次fft长度
//np放大倍数
{
int N = length;
int i;
double fa = fi + 0.5*fs / np;//fa最大细化频率
int na = floor(nf / np / 2 + 1);
complex<double> *a = new complex<double>[N];
signalmove(x, a, N, fi, fa, fs);//移频
for (i = 0; i < 10; i++) {
cout << a[i] << " ";
}
cout << endl;
delete[]x;
complex<double>*b = new complex<double>[nf];
firstfft(a, b, N, nf);
delete[]a;
for (i = 0; i < 10; i++) {
cout << b[i] << " ";
}
cout << endl;
complex<double> *c = new complex<double>[nf];
lowpassfilter(b, c, na, nf);
delete[]b;
for (i = 0; i < 10; i++) {
cout << c[i] << " ";
}
cout << endl;
complex<double> *d = new complex<double>[nf];
fftbackward(c, d, nf);
delete[]c;
for (i = 0; i < 10; i++) {
cout << d[i] << " ";
}
cout << endl;
complex<double> *e = new complex<double>[N / np];
sortagain(d, e, np, N);
delete[]d;
for (i = N / np - 10; i < N / np; i++) {
cout << e[i] << " ";
}
cout << endl;
complex<double> *f = new complex<double>[nfft];
fftagain(e, f, N / np, nfft);
delete[]e;
for (i = 0; i < 10; i++) {
cout << f[i] << " ";
}
cout << endl;
allocatedata(f, y, nfft);
delete[]f;
for (i = 0; i < 10; i++) {
cout << y[i] << " ";
}
cout << endl;
}