// Initialize variables, ZALLOC allocates and fills with zeroes
ZALLOC(z0q, numqbins, double) ;
ZALLOC(z1q, numqbins, double) ;
ZALLOC(z2q, numqbins, double) ;
z_in = (double*)fftw_malloc(sizeof(double) * numqbins * 2) ;
z_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * numqbins * 2) ;
r2c_plan = fftw_plan_dft_r2c_1d(2 * numqbins, z_in, z_out, FFTW_ESTIMATE) ;
c2r_plan = fftw_plan_dft_c2r_1d(2 * numqbins, z_out, z_in, FFTW_ESTIMATE) ;
... (ddbins is initialized to all 0s, z0q, z1q, and z2q are filled with values) ...
for (k1=0; k1<numx; ++k1) {
if (snpmarkers[xindex[k1]] -> ignore) {
continue ;
} else {
s = snpmarkers[xindex[k1]] -> tagnumber ;
}
y = res[k1] * wt[k1] ;
z0q[s] += 1 ;
z1q[s] += y ;
z2q[s] += y*y ;
}
// Perform convolution.
fft_ddadd(ddbins, z0q, z1q, z2q, numqbins, diffmax, z_in, z_out, r2c_plan, c2r_plan) ;
void fft_ddadd(double **ddbins, double *z0q, double *z1q, double *z2q, int numqbins,
int diffmax, double *z_in, fftw_complex *z_out, fftw_plan r2c_plan, fftw_plan c2r_plan)
{
double *dd00, *dd01, *dd10, *dd11, *dd02, *dd20 ;
int i;
fftw_complex *ft_z0q, *ft_z1q, *ft_z2q ;
dd00 = ddbins[0] ;
dd01 = ddbins[1] ;
dd10 = ddbins[3] ;
dd11 = ddbins[4] ;
dd02 = ddbins[2] ;
dd20 = ddbins[6] ;
ft_z0q = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * numqbins * 2) ;
ft_z1q = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * numqbins * 2) ;
ft_z2q = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * numqbins * 2) ;
// Copy arrays into z_in and transform, copy complex results out into ft_z's
for (i = 0; i < numqbins; ++i) {
z_in[i] = z0q[i] ;
z_in[i + numqbins] = 0 ;
}
fftw_execute(r2c_plan) ;
for (i = 0; i < numqbins; ++i) {
z_in[i] = z1q[i] ;
ft_z0q[i][0] = z_out[i][0] ;
ft_z0q[i][1] = z_out[i][1] ;
}
fftw_execute(r2c_plan) ;
for (i = 0; i < numqbins; ++i) {
z_in[i] = z2q[i] ;
ft_z1q[i][0] = z_out[i][0] ;
ft_z1q[i][1] = z_out[i][1] ;
}
fftw_execute(r2c_plan) ;
for (i = 0; i < numqbins; ++i) {
ft_z2q[i][0] = z_out[i][0] ;
ft_z2q[i][1] = z_out[i][1] ;
}
// Do correlations
fft_singledd(dd00, ft_z0q, ft_z0q, numqbins, diffmax, z_in, z_out, c2r_plan);
fft_singledd(dd01, ft_z0q, ft_z1q, numqbins, diffmax, z_in, z_out, c2r_plan);
fft_singledd(dd10, ft_z1q, ft_z0q, numqbins, diffmax, z_in, z_out, c2r_plan);
fft_singledd(dd11, ft_z1q, ft_z1q, numqbins, diffmax, z_in, z_out, c2r_plan);
fft_singledd(dd02, ft_z0q, ft_z2q, numqbins, diffmax, z_in, z_out, c2r_plan);
fft_singledd(dd20, ft_z2q, ft_z0q, numqbins, diffmax, z_in, z_out, c2r_plan);
}
void fft_singledd(double* ddbin, fftw_complex* ftz_0, fftw_complex* ftz_1, int numqbins,
int diffmax, double *z_in, fftw_complex *z_out, fftw_plan c2r_plan) {
int i ;
// Correlate ftz_0 and ftz_1 together and copy into z_out
for (i = 0; i < numqbins * 2; ++i) {
z_out[i][0] = ftz_0[i][0] * ftz_1[i][0] + ftz_0[i][1] * ftz_1[i][1] ;
z_out[i][1] = - ftz_0[i][0] * ftz_1[i][1] + ftz_0[i][1] * ftz_1[i][0] ;
}
// Transform back
fftw_execute(c2r_plan) ;
// Copy the desired results out
for (i = 1; i < diffmax; ++i) {
ddbin[i] += (z_in[2 * numqbins - i] / (2 * numqbins)) ;
}
}
void ddadd(double **ddbins, double *z0q, double *z1q, double *z2q, int numqbins, int diffmax) {
double *dd00, *dd01, *dd10, *dd11, *dd02, *dd20 ;
double a0, a1, a2, b0, b1, b2 ;
int i, s, t, tmax, d ;
dd00 = ddbins[0] ;
dd01 = ddbins[1] ;
dd10 = ddbins[3] ;
dd11 = ddbins[4] ;
dd02 = ddbins[2] ;
dd20 = ddbins[6] ;
for (s=0; s<numqbins; ++s) {
a0 = z0q[s] ;
a1 = z1q[s] ;
a2 = z2q[s] ;
tmax = MIN(numqbins-1, s + diffmax) ;
for (t=s+1; t<=tmax; ++t) {
b0 = z0q[t] ;
b1 = z1q[t] ;
b2 = z2q[t] ;
d = t - s ;
dd00[d] += a0*b0 ;
dd01[d] += a0*b1 ;
dd10[d] += a1*b0 ;
dd11[d] += a1*b1 ;
dd02[d] += a0*b2 ;
dd20[d] += a2*b0 ;
}
}
}
运行上面的代码时,我在结果中遇到问题。当将ddbins
的输出与ddadd
的输出比较到fft_ddadd
的输出ddbins[0] - fft_ddbins[0] = [0.000000000000, -0.016764512518, 0.016764511936, -0.016764512286, 0.016764512053, -0.016764512286, 0.016764512053, -0.016764512169, 0.016764511995, -0.016764512227, 0.016764512053, -0.016764512344, 0.016764512053, -0.016764512227, 0.016764511995, -0.016764512227, 0.016764512053, -0.016764512344, 0.016764512053, -0.016764512227, 0.016764512053, -0.016764512344, 0.016764511995, -0.016764512227, 0.016764512053, -0.016764512227, 0.016764512053, -0.016764512344 ...]
(非傅立叶变换,由O(n ^ 2)相关性计算)时,误差几乎是恒定且交替的:
[+1, -1, +1, -1 ...]
如您所见,这在每个地方的误差大致相同,带有交替的符号,加上或减去某些归因于机器精度的误差。
已经提出的一个可能的问题是,存在一个傅里叶变换分量,该分量在实际空间中对应于数组numqbins
,如果排除,它将解释交变误差。但是,我看不到如何排除此元素。将数组z * q完全复制(长度2*numqbins
)到计划中并执行,同时也直接复制输出数组(长度{{1}}),并且在复制输出之前引入错误。进入所需位置。
这是我第一次在此网站上提问,所以请告诉我是否需要更多(或更少!)信息,或者这不是一个正确的提问位置。预先感谢。