C++学习记录(01)

主要是使用FFTW库进行zfft分析中遇到的问题。

1.FFTW的一般使用程序

参考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是一样的。

2.complex类的使用

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代表虚部。

3.for循环的多个条件

参考7
结论:for循环中,当不用&&和||申明多个条件时,默认的是或者关系。

4.new和delete

参考8
未知所需的内存空间时,可以用new来创建变量。
C++中不允许int a[n],但可以用

      int*a=new int [n];

在使用数组完毕后,可用指令释放它所占用的内存,如

      delete[]a;

使用时要注意new和delete一般搭配使用,否则容易造成内存泄漏(即无用的数据过多,影响程序的运行速度)。

5.随机数组产生

参考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;
}

你可能感兴趣的:(C++学习,c++)