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

📄 complexdoublefft_mixed.java

📁 All the tool for build a network able to reconize any shapes. Very complete, a good base for anythi
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package jnt.FFT;/** Computes FFT's of complex, double precision data of arbitrary length n.  * This class uses the Mixed Radix method; it has special methods to handle  * factors 2, 3, 4, 5, 6 and 7, as well as a general factor.  * <P>  * This method appears to be faster than the Radix2 method, when both methods apply,  * but requires extra storage (which ComplexDoubleFFT_Mixed manages itself).  * <P>  * See {@link ComplexDoubleFFT ComplexDoubleFFT} for details of data layout.  *  * @author Bruce R. Miller bruce.miller@nist.gov  * @author Contribution of the National Institute of Standards and Technology,  * @author not subject to copyright.  * @author Derived from GSL (Gnu Scientific Library)  * @author GSL's FFT Code by Brian Gough bjg@vvv.lanl.gov  * @author Since GSL is released under   * @author <H HREF="http://www.gnu.org/copyleft/gpl.html">GPL</A>,  * @author this package must also be.  */public class ComplexDoubleFFT_Mixed extends ComplexDoubleFFT{  static final double PI = Math.PI;  public ComplexDoubleFFT_Mixed(int n){    super(n);    setup_wavetable(n);  }  public void transform(double data[], int i0, int stride) {    checkData(data,i0,stride);    transform_internal(data, i0, stride, -1); }  public void backtransform (double data[], int i0, int stride){    checkData(data,i0,stride);    transform_internal(data, i0, stride, +1); }  /*______________________________________________________________________   Setting up the Wavetable */  private int factors[];  // Reversed the last 2 levels of the twiddle array compared to what the C version had.  private double twiddle[][][];  private int available_factors[]={7, 6, 5, 4, 3, 2};  void setup_wavetable(int n){    if (n <= 0)      throw new Error("length must be positive integer : "+n);    this.n = n;    factors = Factorize.factor(n, available_factors);    double d_theta = -2.0 * PI / ((double) n);    int product = 1;    twiddle = new double[factors.length][][];    for (int i = 0; i < factors.length; i++) {      int factor = factors[i];      int product_1 = product;	/* product_1 = p_(i-1) */      product *= factor;      int q = n / product;      twiddle[i] = new double[q+1][2*(factor-1)];      double twid[][] = twiddle[i];      for(int j=1; j<factor; j++){	twid[0][2*(j-1)]   = 1.0;	twid[0][2*(j-1)+1] = 0.0; }      for (int k = 1; k <= q; k++) {	int m = 0;	for(int j=1; j<factor; j++){	  //	  int m = (k*j*product_1) % n;	  m += k*product_1;	  m %= n;	  double theta = d_theta * m;	/*  d_theta*j*k*p_(i-1) */	  twid[k][2*(j-1)]   = Math.cos(theta);	  twid[k][2*(j-1)+1] = Math.sin(theta); }}    }  }  /*______________________________________________________________________    The main transformation driver */  void transform_internal(double data[], int i0, int stride, int sign){    if (n == 1) return;		/* FFT of 1 data point is the identity */    double scratch[] = new double[2*n];    int product = 1;    int state = 0;    double in[], out[];    int istride, ostride;    int in0, out0;    for (int i = 0; i < factors.length; i++) {      int factor = factors[i];      product *= factor;      if (state == 0) {	in = data;	in0 = i0;	istride = stride;	out = scratch;	out0 = 0;	ostride = 2;	state = 1; }      else {	in = scratch;	in0 = 0;	istride = 2;	out = data;	out0 = i0;	ostride = stride;	state = 0; }      switch(factor){      case 2: pass_2(i,in, in0, istride, out, out0, ostride, sign, product); break;      case 3: pass_3(i,in, in0, istride, out, out0, ostride, sign, product); break;      case 4: pass_4(i,in, in0, istride, out, out0, ostride, sign, product); break;      case 5: pass_5(i,in, in0, istride, out, out0, ostride, sign, product); break;      case 6: pass_6(i,in, in0, istride, out, out0, ostride, sign, product); break;      case 7: pass_7(i,in, in0, istride, out, out0, ostride, sign, product); break;      default:pass_n(i,in, in0, istride, out, out0, ostride, sign, factor, product);  }    }    if (state == 1){	/* copy results back from scratch to data */      for (int i = 0; i < n; i++) {	data[i0+stride*i]   = scratch[2*i];	data[i0+stride*i+1] = scratch[2*i+1]; }}  }  /*______________________________________________________________________*/  void pass_2(int fi, 	      double in[],  int in0, int istride,	      double out[], int out0, int ostride,	      int sign, int product) {    int k, k1;    int factor = 2;    int m = n / factor;    int q = n / product;    int product_1 = product / factor;    int di = istride * m;    int dj = ostride * product_1;    int i = in0, j = out0;    double x_real, x_imag;    for (k = 0; k < q; k++) {      double twids[] = twiddle[fi][k];      double w_real =       twids[0];      double w_imag = -sign*twids[1];      for (k1 = 0; k1 < product_1; k1++) {	double z0_real = in[i];	double z0_imag = in[i+1];	double z1_real = in[i+di];	double z1_imag = in[i+di+1];	i += istride;	/* compute x = W(2) z */	/* apply twiddle factors */	  	/* out0 = 1 * (z0 + z1) */	out[j]   = z0_real + z1_real;	out[j+1] = z0_imag + z1_imag;	  	/* out1 = w * (z0 - z1) */	x_real = z0_real - z1_real;	x_imag = z0_imag - z1_imag;	out[j+dj]   = w_real * x_real - w_imag * x_imag;	out[j+dj+1] = w_real * x_imag + w_imag * x_real;	  	j += ostride;      }      j += (factor-1)*dj;    }}  /*______________________________________________________________________*/  void pass_3(int fi, 	      double in[],  int in0, int istride,	      double out[], int out0, int ostride,	      int sign, int product) {      int k, k1;      int factor = 3;      int m = n / factor;      int q = n / product;      int product_1 = product / factor;      int jump = (factor - 1) * product_1;      double tau = sign * Math.sqrt(3.0) / 2.0;      int di = istride * m;      int dj = ostride * product_1;      int i = in0, j = out0;      double x_real, x_imag;      for (k = 0; k < q; k++) {	double twids[] = twiddle[fi][k];	double w1_real =       twids[0];	double w1_imag = -sign*twids[1];	double w2_real =       twids[2];	double w2_imag = -sign*twids[3];	for (k1 = 0; k1 < product_1; k1++) {	  double z0_real = in[i];	  double z0_imag = in[i+1];	  double z1_real = in[i+di];	  double z1_imag = in[i+di+1];	  double z2_real = in[i+2*di];	  double z2_imag = in[i+2*di+1];	  i += istride;	  /* compute x = W(3) z */	  /* t1 = z1 + z2 */	  double t1_real = z1_real + z2_real;	  double t1_imag = z1_imag + z2_imag;	  	  /* t2 = z0 - t1/2 */	  double t2_real = z0_real - t1_real / 2.0;	  double t2_imag = z0_imag - t1_imag / 2.0;	  	  /* t3 = (+/-) sin(pi/3)*(z1 - z2) */	  double t3_real = tau * (z1_real - z2_real);	  double t3_imag = tau * (z1_imag - z2_imag);	    	  /* apply twiddle factors */	  /* out0 = 1 * (z0 + t1) */	  out[j]   = z0_real + t1_real;	  out[j+1] = z0_imag + t1_imag;	  	  /* out1 = w1 * (t2 + i t3) */	  x_real = t2_real - t3_imag;	  x_imag = t2_imag + t3_real;	  out[j+dj]   = w1_real * x_real - w1_imag * x_imag;	  out[j+dj+1] = w1_real * x_imag + w1_imag * x_real;	  	  /* out2 = w2 * (t2 - i t3) */	  x_real = t2_real + t3_imag;	  x_imag = t2_imag - t3_real;	  out[j+2*dj]   = w2_real * x_real - w2_imag * x_imag;	  out[j+2*dj+1] = w2_real * x_imag + w2_imag * x_real;  	  j += ostride;	}	j += (factor-1) * dj;      }}  /*______________________________________________________________________*/  void pass_4(int fi, 	      double in[],  int in0, int istride,	      double out[], int out0, int ostride,	      int sign, int product) {    int k, k1;    int factor = 4;    int m = n / factor;    int q = n / product;    int p_1 = product / factor;    int jump = (factor - 1) * p_1;    int i = in0, j = out0;    int di = istride * m;    int dj = ostride * p_1;    double x_real, x_imag;    for (k = 0; k < q; k++) {      double twids[] = twiddle[fi][k];      double w1_real =       twids[0];      double w1_imag = -sign*twids[1];      double w2_real =       twids[2];      double w2_imag = -sign*twids[3];      double w3_real =       twids[4];      double w3_imag = -sign*twids[5];      for (k1 = 0; k1 < p_1; k1++) {	double z0_real = in[i];	double z0_imag = in[i+1];	double z1_real = in[i+di];	double z1_imag = in[i+di+1];	double z2_real = in[i+2*di];	double z2_imag = in[i+2*di+1];	double z3_real = in[i+3*di];	double z3_imag = in[i+3*di+1];	i += istride;	/* compute x = W(4) z */	  	/* t1 = z0 + z2 */	double t1_real = z0_real + z2_real;	double t1_imag = z0_imag + z2_imag;	  	/* t2 = z1 + z3 */	double t2_real = z1_real + z3_real;	double t2_imag = z1_imag + z3_imag;	  	/* t3 = z0 - z2 */	double t3_real = z0_real - z2_real;	double t3_imag = z0_imag - z2_imag;	  	/* t4 = (+/-) (z1 - z3) */	double t4_real = sign * (z1_real - z3_real);	double t4_imag = sign * (z1_imag - z3_imag);	/* apply twiddle factors */	/* out0 = 1 * (t1 + t2) */	out[j]   = t1_real + t2_real;	out[j+1] = t1_imag + t2_imag;	/* out1 = w1 * (t3 + i t4) */	x_real = t3_real - t4_imag;	x_imag = t3_imag + t4_real;	out[j + dj]   = w1_real * x_real - w1_imag * x_imag;	out[j + dj+1] = w1_real * x_imag + w1_imag * x_real;	  	/* out2 = w2 * (t1 - t2) */	x_real = t1_real - t2_real;	x_imag = t1_imag - t2_imag;	out[j + 2 * dj]   = w2_real * x_real - w2_imag * x_imag;	out[j + 2 * dj+1] = w2_real * x_imag + w2_imag * x_real;	  	/* out3 = w3 * (t3 - i t4) */	x_real = t3_real + t4_imag;	x_imag = t3_imag - t4_real;	out[j + 3 * dj]   = w3_real * x_real - w3_imag * x_imag;	out[j + 3 * dj+1] = w3_real * x_imag + w3_imag * x_real;	  	j += ostride;      }      j += (factor - 1)*dj;    }}  /*______________________________________________________________________*/  void pass_5(int fi, 	      double in[],  int in0, int istride,	      double out[], int out0, int ostride,	      int sign, int product) {    int k, k1;    int factor = 5;    int m = n / factor;    int q = n / product;    int p_1 = product / factor;    int jump = (factor - 1) * p_1;    double tau = (Math.sqrt (5.0) / 4.0);    double sin_2pi_by_5 =  sign * Math.sin (2.0 * PI / 5.0);    double sin_2pi_by_10 = sign * Math.sin (2.0 * PI / 10.0);    int i = in0, j = out0;    int di = istride * m;    int dj = ostride * p_1;    double x_real, x_imag;    for (k = 0; k < q; k++) {      double twids[] = twiddle[fi][k];      double w1_real =       twids[0];      double w1_imag = -sign*twids[1];      double w2_real =       twids[2];      double w2_imag = -sign*twids[3];      double w3_real =       twids[4];      double w3_imag = -sign*twids[5];      double w4_real =       twids[6];      double w4_imag = -sign*twids[7];      for (k1 = 0; k1 < p_1; k1++) {	double z0_real = in[i];	double z0_imag = in[i+1];	double z1_real = in[i + di];	double z1_imag = in[i + di+1];	double z2_real = in[i + 2*di];	double z2_imag = in[i + 2*di+1];	double z3_real = in[i + 3*di];	double z3_imag = in[i + 3*di+1];	double z4_real = in[i + 4*di];	double z4_imag = in[i + 4*di+1];	i += istride;	/* compute x = W(5) z */	/* t1 = z1 + z4 */	double t1_real = z1_real + z4_real;	double t1_imag = z1_imag + z4_imag;	  	/* t2 = z2 + z3 */	double t2_real = z2_real + z3_real;	double t2_imag = z2_imag + z3_imag;	  	/* t3 = z1 - z4 */	double t3_real = z1_real - z4_real;	double t3_imag = z1_imag - z4_imag;	  	/* t4 = z2 - z3 */	double t4_real = z2_real - z3_real;	double t4_imag = z2_imag - z3_imag;	  	/* t5 = t1 + t2 */	double t5_real = t1_real + t2_real;	double t5_imag = t1_imag + t2_imag;	  	/* t6 = (sqrt(5)/4)(t1 - t2) */	double t6_real = tau * (t1_real - t2_real);	double t6_imag = tau * (t1_imag - t2_imag);	  	/* t7 = z0 - ((t5)/4) */	double t7_real = z0_real - t5_real / 4.0;	double t7_imag = z0_imag - t5_imag / 4.0;	  	/* t8 = t7 + t6 */	double t8_real = t7_real + t6_real;	double t8_imag = t7_imag + t6_imag;	  	/* t9 = t7 - t6 */	double t9_real = t7_real - t6_real;	double t9_imag = t7_imag - t6_imag;	  	/* t10 = sin(2 pi/5) t3 + sin(2 pi/10) t4 */	double t10_real = sin_2pi_by_5 * t3_real + sin_2pi_by_10 * t4_real;	double t10_imag = sin_2pi_by_5 * t3_imag + sin_2pi_by_10 * t4_imag;	  	/* t11 = sin(2 pi/10) t3 - sin(2 pi/5) t4 */	double t11_real = sin_2pi_by_10 * t3_real - sin_2pi_by_5 * t4_real;	double t11_imag = sin_2pi_by_10 * t3_imag - sin_2pi_by_5 * t4_imag;      	/* apply twiddle factors */	  	/* out0 = 1 * (z0 + t5) */	out[j]   = z0_real + t5_real;	out[j+1] = z0_imag + t5_imag;	  	/* out1 = w1 * (t8 + i t10) */	x_real = t8_real - t10_imag;	x_imag = t8_imag + t10_real;	out[j + dj]   = w1_real * x_real - w1_imag * x_imag;	out[j + dj+1] = w1_real * x_imag + w1_imag * x_real;	  	/* out2 = w2 * (t9 + i t11) */	x_real = t9_real - t11_imag;	x_imag = t9_imag + t11_real;	out[j+2*dj]   = w2_real * x_real - w2_imag * x_imag;	out[j+2*dj+1] = w2_real * x_imag + w2_imag * x_real;	  	/* out3 = w3 * (t9 - i t11) */	x_real = t9_real + t11_imag;	x_imag = t9_imag - t11_real;	out[j+3*dj]   = w3_real * x_real - w3_imag * x_imag;	out[j+3*dj+1] = w3_real * x_imag + w3_imag * x_real;	  	/* out4 = w4 * (t8 - i t10) */	x_real = t8_real + t10_imag;	x_imag = t8_imag - t10_real;	out[j+4*dj]   = w4_real * x_real - w4_imag * x_imag;	out[j+4*dj+1] = w4_real * x_imag + w4_imag * x_real;	  	j += ostride;      }      j += (factor - 1)*dj;    }}  /*______________________________________________________________________*/  void pass_6(int fi, 	      double in[],  int in0, int istride,	      double out[], int out0, int ostride,	      int sign, int product) {    int k, k1;    int factor = 6;    int m = n / factor;    int q = n / product;    int p_1 = product / factor;    int jump = (factor - 1) * p_1;    double tau = sign * Math.sqrt (3.0) / 2.0;    int i = in0, j = out0;    int di = istride * m;    int dj = ostride * p_1;    double x_real, x_imag;    for (k = 0; k < q; k++) {      double twids[] = twiddle[fi][k];      double w1_real =       twids[0];      double w1_imag = -sign*twids[1];

⌨️ 快捷键说明

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