LTFAT_API int LTFAT_NAME_COMPLEX(fftfftshift)(const LTFAT_COMPLEX* in, ltfat_int L, LTFAT_COMPLEX* out) { ltfat_div_t domod; int status = LTFATERR_SUCCESS; domod = ltfat_idiv(L, 2); if (domod.rem) { // There is no Nyquist sample, modulation is by (L-1/L)*pi status = LTFAT_NAME_COMPLEX(fftcircshift)(in, L, (double)domod.quot, out); } else { CHECKNULL(in); CHECKNULL(out); CHECK(LTFATERR_BADSIZE, L > 0, "L must be positive"); if (in != out) for (int ii = 0; ii < L; ii += 2) out[ii] = in[ii]; // There is Nyquist sample. Modulation is exactly by pi i.e. no complex // multiplication for (int ii = 1; ii < L; ii += 2) out[ii] = -in[ii]; } error: return status; }
LTFAT_EXTERN void LTFAT_NAME_REAL(dwiltiii_long)(const LTFAT_REAL *f, const LTFAT_REAL *g, const ltfatInt L, const ltfatInt W, const ltfatInt M, LTFAT_REAL *cout) { const ltfatInt N=L/M; const ltfatInt M2 = 2*M; const ltfatInt M4=4*M; LTFAT_COMPLEX *coef2 = ltfat_malloc(2*M*N*W*sizeof*coef2); LTFAT_COMPLEX *f2 = ltfat_malloc(L*W*sizeof*f2); LTFAT_COMPLEX *g2 = ltfat_malloc(L*sizeof*g2); // Real to complex for(ltfatInt ii=0; ii<L; ii++) g2[ii]=g[ii]; PREPROC LTFAT_NAME_COMPLEX(dgt_long)(f2, g2, L, W, M, 2*M, coef2); LTFAT_REAL *pcoef = cout; LTFAT_COMPLEX *pcoef2 = coef2; POSTPROC_REAL LTFAT_SAFEFREEALL(coef2,f2,g2); }
LTFAT_API int LTFAT_NAME_COMPLEX(dgtreal_phaseunlock)(const LTFAT_COMPLEX* cTimeinv, ltfat_int L, ltfat_int W, ltfat_int a, ltfat_int M, LTFAT_COMPLEX* cFreqinv) { ltfat_int N, M2; int status = LTFATERR_SUCCESS; CHECKNULL(cFreqinv); CHECKNULL(cTimeinv); CHECK(LTFATERR_NOTPOSARG, L > 0, "L must be positive"); CHECK(LTFATERR_NOTPOSARG, W > 0, "W must be positive"); CHECK(LTFATERR_NOTPOSARG, a > 0, "a must be positive"); CHECK(LTFATERR_NOTPOSARG, M > 0, "M must be positive"); N = L / a; M2 = M / 2 + 1; for (ltfat_int w = 0; w < W; w++) { for (ltfat_int n = 0; n < N; n++) { const LTFAT_COMPLEX* inCol = cTimeinv + n * M2 + w * M2 * N; LTFAT_COMPLEX* outCol = cFreqinv + n * M2 + w * M2 * N; LTFAT_NAME_COMPLEX(fftrealcircshift)( inCol, M, (double)(n * a), outCol); } } error: return status; }
LTFAT_EXTERN void LTFAT_NAME_COMPLEX(dwiltiii_long)(const LTFAT_COMPLEX *f, const LTFAT_COMPLEX *g, const ltfatInt L, const ltfatInt W, const ltfatInt M, LTFAT_COMPLEX *cout) { const ltfatInt N=L/M; const ltfatInt M2=2*M; const ltfatInt M4=4*M; const LTFAT_REAL scalconst = 1.0/sqrt(2.0); const LTFAT_COMPLEX eipi4 = cexp(I*PI/4.0); const LTFAT_COMPLEX emipi4 = cexp(-I*PI/4.0); LTFAT_COMPLEX *coef2 = ltfat_malloc(2*M*N*W*sizeof*coef2); LTFAT_COMPLEX *f2 = ltfat_malloc(L*W*sizeof*f2); PREPROC LTFAT_NAME_COMPLEX(dgt_long)(f2, g, L, W, M, 2*M, coef2); LTFAT_COMPLEX *pcoef = cout; LTFAT_COMPLEX *pcoef2 = coef2; POSTPROC_COMPLEX LTFAT_SAFEFREEALL(coef2,f2); }
LTFAT_API int LTFAT_NAME_COMPLEX(fftifftshift)(const LTFAT_COMPLEX* in, ltfat_int L, LTFAT_COMPLEX* out) { ltfat_div_t domod; int status = LTFATERR_SUCCESS; CHECK(LTFATERR_BADSIZE, L > 0, "L must be positive"); domod = ltfat_idiv(L, 2); if (domod.rem) // There is no Nyquist sample, modulation is by -(L-1/L)*pi status = LTFAT_NAME_COMPLEX(fftcircshift)(in, L, (double)(-domod.quot), out); else status = LTFAT_NAME_COMPLEX(fftfftshift)(in, L, out); error: return status; }
int main( int argc, char *argv[] ) { if (argc<3) { printf("Correct parameters: L, K, nrep\n"); return(1); } int nrep = 1; if (argc>3) { nrep = atoi(argv[3]); } const size_t L = atoi(argv[1]); const size_t K = atoi(argv[2]); LTFAT_REAL *f = (LTFAT_REAL*)ltfat_malloc(L*sizeof(LTFAT_REAL)); LTFAT_COMPLEXH *c = (LTFAT_COMPLEXH*)ltfat_malloc(K*sizeof(LTFAT_COMPLEXH)); LTFAT_NAME_COMPLEX(fillRand)(f,L); double o = 0.1; double deltao = 2.0*PI/100.0; double st0,st1; #ifndef CZT_WITH_PLAN st0=ltfat_time(); for (int jj=0;jj<nrep;jj++) { LTFAT_NAME(chzt)(f,L,1,K,deltao,o,c); } st1=ltfat_time(); #else LTFAT_NAME(chzt_plan) p = LTFAT_NAME(create_chzt_plan)(K,L); st0=ltfat_time(); for (int jj=0;jj<nrep;jj++) { LTFAT_NAME(chzt_with_plan)(p,f,1,deltao,o,c); } st1=ltfat_time(); LTFAT_NAME(destroy_chzt_plan)(p); #endif //printf("Length: %i, avr. %f ms \n",L,(st1-st0)/((double)nrep)); printf("%i, %f\n",L,(st1-st0)/((double)nrep)); ltfat_free(f); ltfat_free(c); }
LTFAT_API void LTFAT_NAME(gabdualreal_fac)(const LTFAT_COMPLEX* gf, ltfat_int L, ltfat_int R, ltfat_int a, ltfat_int M, LTFAT_COMPLEX* gdualf) { ltfat_int h_a, h_m; LTFAT_COMPLEX* Sf; const LTFAT_COMPLEX zzero = (LTFAT_COMPLEX) 0.0; const LTFAT_COMPLEX alpha = (LTFAT_COMPLEX) 1.0; //{1.0, 0.0 }; ltfat_int N = L / a; ltfat_int c = ltfat_gcd(a, M, &h_a, &h_m); ltfat_int p = a / c; ltfat_int q = M / c; ltfat_int d = N / q; /* This is a floor operation. */ ltfat_int d2 = d / 2 + 1; Sf = LTFAT_NAME_COMPLEX(malloc)(p * p); /* Copy the contents of gf to gdualf because LAPACK overwrites it input * argument */ memcpy(gdualf, gf, sizeof(LTFAT_COMPLEX)*L * R); for (ltfat_int rs = 0; rs < c * d2; rs++) { LTFAT_NAME(gemm)(CblasNoTrans, CblasConjTrans, p, p, q * R, &alpha, gf + rs * p * q * R, p, gf + rs * p * q * R, p, &zzero, Sf, p); LTFAT_NAME(posv)(p, q * R, Sf, p, gdualf + rs * p * q * R, p); } /* Clear the work-array. */ ltfat_free(Sf); }
int status = LTFATERR_SUCCESS; CHECKNULL(g); CHECKNULL(pout); CHECK(LTFATERR_BADSIZE, gl > 0, "gl (passed %td) must be positive.", gl); CHECK(LTFATERR_NOTPOSARG, a > 0, "a (passed %td) must be positive.", a); CHECK(LTFATERR_NOTPOSARG, M > 0, "M (passed %td) must be positive.", M); CHECK(LTFATERR_CANNOTHAPPEN, ltfat_phaseconvention_is_valid(ptype), "Invalid ltfat_phaseconvention enum value." ); CHECKMEM( p = LTFAT_NEW(LTFAT_NAME(idgt_fb_plan)) ); p->ptype = ptype; p->a = a; p->M = M; p->gl = gl; CHECKMEM( p->cbuf = LTFAT_NAME_COMPLEX(malloc)(M)); CHECKMEM( p->gw = LTFAT_NAME(malloc)(gl)); CHECKMEM( p->ff = LTFAT_NAME_COMPLEX(malloc)(gl > M ? gl : M)); CHECKSTATUS( LTFAT_NAME_REAL(ifft_init)(M, 1, p->cbuf, p->cbuf, flags, &p->p_small)); LTFAT_NAME(fftshift)(g, gl, p->gw); *pout = p; return status; error: if (p) LTFAT_NAME(idgt_fb_done)(&p); return status; }
int TEST_NAME(test_fftfftshift)() { ltfatInt L[] = {111, 1, 100}; for (unsigned int lId = 0; lId < ARRAYLEN(L); lId++) { LTFAT_COMPLEX* fin = LTFAT_NAME_COMPLEX(malloc)(L[lId]); TEST_NAME_COMPLEX(fillRand)(fin, L[lId]); LTFAT_COMPLEX* fout = LTFAT_NAME_COMPLEX(malloc)(L[lId]); TEST_NAME_COMPLEX(fillRand)(fout, L[lId]); mu_assert( LTFAT_NAME_COMPLEX(fftfftshift)(fin, L[lId], fout) == 0, "fftfftshift"); mu_assert( LTFAT_NAME_COMPLEX(fftfftshift)(fin, L[lId], fin) == 0, "fftfftshift inplace"); ltfat_free(fin); ltfat_free(fout); } LTFAT_COMPLEX* fin = LTFAT_NAME_COMPLEX(malloc)(L[0]); TEST_NAME_COMPLEX(fillRand)(fin, L[0]); LTFAT_COMPLEX* fout = LTFAT_NAME_COMPLEX(malloc)(L[0]); TEST_NAME_COMPLEX(fillRand)(fout, L[0]); // Inputs can be checked only once mu_assert( LTFAT_NAME_COMPLEX(fftfftshift)(NULL, L[0], fin) == LTFATERR_NULLPOINTER, "First is null"); mu_assert( LTFAT_NAME_COMPLEX(fftfftshift)(fin, L[0], NULL) == LTFATERR_NULLPOINTER, "Last is null"); mu_assert( LTFAT_NAME_COMPLEX(fftfftshift)(fin, 0, fout) == LTFATERR_BADSIZE, "Zero length"); mu_assert( LTFAT_NAME_COMPLEX(fftfftshift)(fin, -1, fout) == LTFATERR_BADSIZE, "Negative length"); mu_assert( LTFAT_NAME_COMPLEX(fftfftshift)(NULL, -1, fout) < LTFATERR_SUCCESS, "Multiple wrong inputs"); ltfat_free(fin); ltfat_free(fout); return 0; }
int TEST_NAME(test_pgauss)() { ltfatInt L[] = { 111, 1, 100 }; double w[] = { 0.001, 0.1, 0.2 }; double c_t[] = { 0.0, 0.1, -0.2 }; double c_f[] = { 0.0, 0.1, -0.2 }; for (unsigned int lId = 0; lId < ARRAYLEN(L); lId++) { LTFAT_TYPE* fin = LTFAT_NAME(malloc)(L[lId]); TEST_NAME(fillRand)(fin, L[lId]); LTFAT_COMPLEX* fincmplx = LTFAT_NAME_COMPLEX(malloc)(L[0]); TEST_NAME_COMPLEX(fillRand)(fincmplx, L[0]); for (unsigned int wId = 0; wId < ARRAYLEN(w); wId++) { for (unsigned int ctId = 0; ctId < ARRAYLEN(c_t); ctId++) { mu_assert( LTFAT_NAME(pgauss)( L[lId], w[wId], c_t[ctId], fin) == LTFATERR_SUCCESS, "pgauss"); for (unsigned int cfId = 0; cfId < ARRAYLEN(c_f); cfId++) { mu_assert( LTFAT_NAME(pgauss_cmplx)( L[lId], w[wId], c_t[ctId], c_f[cfId], fincmplx) == LTFATERR_SUCCESS, "pgauss"); } } } ltfat_free(fin); ltfat_free(fincmplx); } LTFAT_TYPE* fin = LTFAT_NAME(malloc)(L[0]); TEST_NAME(fillRand)(fin, L[0]); LTFAT_COMPLEX* fincmplx = LTFAT_NAME_COMPLEX(malloc)(L[0]); TEST_NAME_COMPLEX(fillRand)(fincmplx, L[0]); mu_assert( LTFAT_NAME(pgauss)( L[0], w[0], c_t[0], NULL) == LTFATERR_NULLPOINTER, "pgauss Array is null"); mu_assert( LTFAT_NAME(pgauss)( 0, w[0], c_t[0], fin) == LTFATERR_BADSIZE, "pgauss L is wrong"); mu_assert( LTFAT_NAME(pgauss)( L[0], 0.0, c_t[0], fin) == LTFATERR_NOTPOSARG, "pgauss Wrong t-f ratio"); mu_assert( LTFAT_NAME(pgauss_cmplx)( L[0], w[0], c_t[0], c_f[0], NULL) == LTFATERR_NULLPOINTER, "pgauss cmplx Array is null"); mu_assert( LTFAT_NAME(pgauss_cmplx)( 0, w[0], c_t[0], c_f[0], fincmplx) == LTFATERR_BADSIZE, "pgauss cmplx L is wrong"); mu_assert( LTFAT_NAME(pgauss_cmplx)( L[0], 0.0, c_t[0], c_f[0], fincmplx) == LTFATERR_NOTPOSARG, "pgauss cmplx Wrong t-f ratio"); ltfat_free(fin); ltfat_free(fincmplx); return 0; }
#endif #endif /* end of HAVE_BLAS */ struct LTFAT_NAME_COMPLEX(hermsystemsolver_plan) { ltfat_int Mmax; ltfat_int nrhs; ptrdiff_t* ipiv; LTFAT_COMPLEX* work; ptrdiff_t lwork; }; LTFAT_API int LTFAT_NAME_COMPLEX(hermsystemsolver_init)(ltfat_int M, LTFAT_NAME_COMPLEX(hermsystemsolver_plan)** pout) #ifdef HAVE_LAPACK { int status = LTFATERR_SUCCESS; LTFAT_NAME_COMPLEX(hermsystemsolver_plan)* p = NULL; ptrdiff_t info, M_t = M; char u; const ptrdiff_t nrhs = 1; const ptrdiff_t lwork = -1; LTFAT_COMPLEX dummy; LTFAT_COMPLEX outlen; CHECKMEM( p = LTFAT_NEW(LTFAT_NAME_COMPLEX(hermsystemsolver_plan))); CHECKMEM( p->ipiv = LTFAT_NEWARRAY(ptrdiff_t, M)); p->Mmax = M;