void fi_c_radix2fft_blockfloatingpoint(int16_T* xr, int16_T* xi, int16_T* wr, int16_T* wi, int n, int nw, int t, int Wfraclen, int16_T lowerbnd, int16_T upperbnd, double* nshifts) { int32_T* yr = mxCalloc(n,sizeof(int32_T)); int32_T* yi = mxCalloc(n,sizeof(int32_T)); int32_T tempr, tempi; int q, i, j, k; int n1, n2, n3; int L, kL, r, L2; int needshift; bitreverse(xr,xi,n); for (i=0; i<n; i++) { yr[i] = xr[i]; yi[i] = xi[i]; } for (q=1; q<=t; q++) { L = 1; L <<= q; /* L = 2^q */ r = 1; r <<= (t-q); /* r = n/L = 2^(t-q) */ L2 = L>>1; /* L2 = L/2 */ kL = 0; /* kL = k*L */ for (k=0; k<r; k++) { for (j=0; j<L2; j++) { n3 = kL + j; n2 = n3 + L2; n1 = L2 - 1 + j; tempr = (int32_T)wr[n1]*(int32_T)yr[n2] - (int32_T)wi[n1]*(int32_T)yi[n2]; tempi = (int32_T)wr[n1]*(int32_T)yi[n2] + (int32_T)wi[n1]*(int32_T)yr[n2]; yr[n2] = ((((int32_T)yr[n3])<<Wfraclen) - tempr)>>Wfraclen; yi[n2] = ((((int32_T)yi[n3])<<Wfraclen) - tempi)>>Wfraclen; yr[n3] = ((((int32_T)yr[n3])<<Wfraclen) + tempr)>>Wfraclen; yi[n3] = ((((int32_T)yi[n3])<<Wfraclen) + tempi)>>Wfraclen; } kL += L; } needshift = 0; for (i=0; i<n; i++) { if (yr[i]<lowerbnd || yr[i]>upperbnd || yi[i]<lowerbnd || yi[i]>upperbnd) { (*nshifts)++; needshift++; break; } } if (needshift) { for (i=0; i<n; i++) { yr[i] >>= 1; yi[i] >>= 1; } } } for (i=0; i<n; i++) { xr[i] = yr[i]; xi[i] = yi[i]; } mxFree(yr); mxFree(yi); }
static void testbitreverse(void *data) { struct testdata *test; uint8_t *buf; test = data; buf = (uint8_t *)malloc(test->capa); /* different pointers */ memcpy(buf, test->bytes1, test->capa); bitreverse(buf, test->expos, test->bytes1, test->pos1, test->size); testassert(biteq(buf, 0, test->expected, 0, test->capa * 8), "failed to write reversed bits to a different pointer"); /* same pointer */ memcpy(buf, test->bytes1, test->capa); bitreverse(buf, test->expos, buf, test->pos1, test->size); testassert(biteq(buf, 0, test->expected, 0, test->capa * 8), "failed to write reversed bits to the pointer"); free(buf); }
Convolution<TYPE>::Convolution(int size, TYPE PI2) : m_Size(size) { // verify size is correct. should be a power of 2 assert ((size & (size - 1)) == 0); int bits = int(log(double(size)) / log(2.0) + 0.5); // allocate memory m_pWeights = new TYPE [size*2]; m_pBR = new int [size/2]; assert(m_pWeights && m_pBR); // fill in weights and bit reverse vector int i; for (i=0; i<size/2; ++i) { m_pWeights[realindex(i)] = cos(PI2 * i / size); m_pWeights[imagindex(i)] = -sin(PI2 * i / size); m_pBR[i] = bitreverse(i, bits-1, size/2); } }
/* JGcfft replaces float array x containing NC complex values (2*NC float values alternating real, imagininary, etc.) by its Fourier transform if forward is true, or by its inverse Fourier transform if forward is false, using a recursive Fast Fourier transform method due to Danielson and Lanczos. NC MUST be a power of 2. */ void JGcfft(float x[], int NC, int forward) { float wr, wi, wpr, wpi, theta, scale; int mmax, ND, m, i, j, delta; ND = NC << 1; bitreverse(x, ND); for (mmax = 2; mmax < ND; mmax = delta) { delta = mmax << 1; theta = TWO_PI / (forward ? mmax : -mmax); wpr = -2.0 * pow(sin(0.5 * theta), 2.0); wpi = sin(theta); wr = 1.0; wi = 0.0; for (m = 0; m < mmax; m += 2) { float rtemp, itemp; for (i = m; i < ND; i += delta) { j = i + mmax; rtemp = wr * x[j] - wi * x[j + 1]; itemp = wr * x[j + 1] + wi * x[j]; x[j] = x[i] - rtemp; x[j + 1] = x[i + 1] - itemp; x[i] += rtemp; x[i + 1] += itemp; } rtemp = wr; wr = wr * wpr - wi * wpi + wr; wi = wi * wpr + rtemp * wpi + wi; } } /* scale output */ scale = forward ? 1.0 / ND : 2.0; { float *xi = x, *xe = x + ND; while (xi < xe) *xi++ *= scale; } }