BOOST_FORCEINLINE void combine_eigens(const T& wr, const T& wi, A0& w) { typedef typename A0::value_type type_t; int n = numel(wr); w.resize(of_size(n, 1)); nt2::container::table<type_t, nt2::shared_> sw(of_size(n, 1), share(w.data(), w.data()+n)); sw = tocomplex(wr, wi); }
BOOST_FORCEINLINE void combine_vects(const T1& rv, const T2& wi, A0& v) { typedef typename A0::value_type type_t; int n = height(rv); v.resize(of_size(n, n)); nt2::container::table<type_t, nt2::shared_> sv(of_size(n, n), share(v.data(), v.data()+numel(v))); for(int j=1; j <= n; ++j) { if(wi(j)) { sv(nt2::_, j ) = tocomplex(rv(nt2::_, j), rv(nt2::_, j+1)); sv(nt2::_, j+1) = conj(sv(nt2::_, j)); ++j; } else sv(nt2::_, j) = rv(nt2::_, j); } }
void cgauj(Complex a[], int l, int m, int n, double eps) { int c, i, iw, j, k, mm1, *p, r, *work; double api, w, wmax; Complex pivot, *q, *q1, wk, wk1; if(l < n || m < 2 || m >= n || eps <= 0.) { fprintf(stderr, "Error : Illegal parameter in cgauj()\n"); return; } work = (int *)malloc(m * sizeof(int)); if(work == NULL) { fprintf(stderr, "Error : Out of memory in cgauj()\n"); return; } for(i = 0, p = work; i < m; i++) *p++ = i; for(k = 0; k < m; k++) { wmax = 0.; for(i = k; i < m; i++) { for(j = k, q = a + i * l + k; j < m; j++) { w = cabslt(*q++); if(w > wmax) { wmax = w; r = i; c = j; } } } pivot = *(a + r * l + c); api = cabslt(pivot); if(api < eps) { fprintf(stderr, "Error : api < eps in cgauj()\n"); free((char *)work); return; } if(c != k) { iw = *(work + k); *(work + k) = *(work + c); *(work + c) = iw; for(i = 0, q = a + i * l; i < m; i++, q += l) { wk = *(q + k); *(q + k) = *(q + c); *(q + c) = wk; } } if(r != k) { for(j = k; j < n; j++) { wk = *(a + r * l + j); *(a + r * l + j) = *(a + k * l + j); *(a + k * l + j) = wk; } } *(a + k * l + k) = tocomplex(1., 0.); for(i = k + 1, q = a + k * l + k + 1; i < n; i++, q++) *q = cdiv(*q, pivot); for(i = 0; i < m; i++) { if(i != k) { wk = *(a + i * l + k); for(j = k; j < n; j++) { wk1 = cmul(wk, *(a + k * l + j)); *(a + i * l + j) = csub(*(a + i * l + j), wk1); } } } } mm1 = m - 1; for(i = 0; i < mm1; i++) { for(;;) { k = *(work + i); if(k == i) break; iw = *(work + k); *(work + k) = *(work + i); *(work + i) = iw; for(j = m, q = a + k * l + m, q1 = a + i * l + m; j < n; j++) { wk = *q; *q++ = *q1; *q1++ = wk; } } } free((char *)work); return; }
int main(void) { static double ar[8] = { 0., 0., 0., 1., 1., 0., 0., 0.}; static double ai[8] = { 0., 0., 0., 0., 0., 0., 0., 0.}; static double ar2[16] = { 0., 0., 0., 0., 0., 1., 1., 0., 0., 1., 1., 0., 0., 0., 0., 0.}; static double ai2[16] = { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}; Complex a[8], a2[16]; int flag, i, iter, j, k, n, nmax; iter = 0; n = 8; #ifndef CPX for(i = 0; i < n; i++) a[i] = tocomplex(ar[i], ai[i]); print(ar, ai, n); #else printx(a, n); #endif /* forward FFT */ flag = 0; #ifndef CPX fft1(ar, ai, n, iter, flag); print(ar, ai, n); #else fft1x(a, n, iter, flag); printx(a, n); #endif /* reverse FFT */ flag = 1; #ifndef CPX fft1(ar, ai, n, iter, flag); print(ar, ai, n); #else fft1x(a, n, iter, flag); printx(a, n); #endif n = nmax = 4; for(i = k = 0; i < n; i++) for(j = 0; j < n; j++, k++) a2[k] = tocomplex(ar2[k], ai2[k]); #ifndef CPX print2(ar2, ai2, n, nmax); #else print2x(a2, n, nmax); #endif flag = 0; #ifndef CPX fft2(ar2, ai2, n, nmax, flag); print2(ar2, ai2, n, nmax); #else fft2x(a2, n, nmax, flag); print2x(a2, n, nmax); #endif flag = 1; #ifndef CPX fft2(ar2, ai2, n, nmax, flag); print2(ar2, ai2, n, nmax); #else fft2x(a2, n, nmax, flag); print2x(a2, n, nmax); #endif return 1; }
void fft1x(Complex a[], int n, int iter, int flag) { int i, it, j, j1, j2, k, xp, xp2; double arg, sign, w; Complex d1, d2, *p, *q, t, ww; if(n < 2) { fprintf(stderr, "Error : n < 2 in fft1()\n"); return; } if(iter <= 0) { iter = 0; i = n; while((i /= 2) != 0) iter++; } j = 1; for(i = 0; i < iter; i++) j *= 2; if(n != j) { fprintf(stderr, "Error : n != 2 ^ k in fft1()\n"); return; } sign = (flag == 1)? 1.: -1.; xp2 = n; for(it = 0; it < iter; it++) { xp = xp2; xp2 = xp / 2; w = M_PI / xp2; for(k = 0; k < xp2; k++) { arg = k * w; ww = tocomplex(cos(arg), sign * sin(arg)); i = k - xp; for(j = xp, p = a + i + xp, q = a + i + xp + xp2; j <= n; j += xp, p += xp, q += xp) { t = csub(*p, *q); *p = cadd(*p, *q); *q = cmul(t, ww); } } } j1 = n / 2; j2 = n - 1; j = 1; for(i = 1, p = a; i <= j2; i++, p++) { if(i < j) swapx(p, a + j - 1); k = j1; while(k < j) { j -= k; k /= 2; } j += k; } if(flag == 0) return; w = n; for(i = 0, p = a; i < n; i++, p++) *p = cdiv1(*p, w); return; }