public static void dfct( int n, double* a, double* t, int* ip, double* w ) {
//void makewt(int nw, int *ip, double *w);
//void makect(int nc, int *ip, double *c);
//void cftfsub(int n, double *a, int *ip, int nw, double *w);
//void rftfsub(int n, double *a, int nc, double *c);
//void dctsub(int n, double *a, int nc, double *c);
int j, k, l, m, mh, nw, nc;
double xr, xi, yr, yi;
nw = ip[0];
if ( n > (nw << 3) ) {
nw = n >> 3;
makewt( nw, ip, w );
}
nc = ip[1];
if ( n > (nc << 1) ) {
nc = n >> 1;
makect( nc, ip, w + nw );
}
m = n >> 1;
yi = a[m];
xi = a[0] + a[n];
a[0] -= a[n];
t[0] = xi - yi;
t[m] = xi + yi;
if ( n > 2 ) {
mh = m >> 1;
for ( j = 1; j < mh; j++ ) {
k = m - j;
xr = a[j] - a[n - j];
xi = a[j] + a[n - j];
yr = a[k] - a[n - k];
yi = a[k] + a[n - k];
a[j] = xr;
a[k] = yr;
t[j] = xi - yi;
t[k] = xi + yi;
}
t[mh] = a[mh] + a[n - mh];
a[mh] -= a[n - mh];
dctsub( m, a, nc, w + nw );
if ( m > 4 ) {
cftfsub( m, a, ip, nw, w );
rftfsub( m, a, nc, w + nw );
} else if ( m == 4 ) {
cftfsub( m, a, ip, nw, w );
}
a[n - 1] = a[0] - a[1];
a[1] = a[0] + a[1];
for ( j = m - 2; j >= 2; j -= 2 ) {
a[2 * j + 1] = a[j] + a[j + 1];
a[2 * j - 1] = a[j] - a[j + 1];
}
l = 2;
m = mh;
while ( m >= 2 ) {
dctsub( m, t, nc, w + nw );
if ( m > 4 ) {
cftfsub( m, t, ip, nw, w );
rftfsub( m, t, nc, w + nw );
} else if ( m == 4 ) {
cftfsub( m, t, ip, nw, w );
}
a[n - l] = t[0] - t[1];
a[l] = t[0] + t[1];
k = 0;
for ( j = 2; j < m; j += 2 ) {
k += l << 2;
a[k - l] = t[j] - t[j + 1];
a[k + l] = t[j] + t[j + 1];
}
l <<= 1;
mh = m >> 1;
for ( j = 0; j < mh; j++ ) {
k = m - j;
t[j] = t[m + k] - t[m + j];
t[k] = t[m + k] + t[m + j];
}
t[mh] = t[m + mh];
m = mh;
}
a[l] = t[0];
a[n] = t[2] - t[1];
a[0] = t[2] + t[1];
} else {
a[1] = a[0];
a[2] = t[0];
a[0] = t[1];
}
}