我用(http://www.fftw.org/doc/Precision.html):
编译了FFTW 3.3.5库./configure --enable-long-double
make
make install
我用gcc -std=gnu99 main.c -o sample.x -lfftw3l -lm
#include <math.h>
#include <complex.h>
#include <fftw3.h>
#include <string.h>
#define PI acosl(-1.0L)
#define FMODE FFTW_MEASURE
int main() {
fftwl_complex *A = fftwl_malloc(4096*sizeof(fftwl_complex));
fftwl_plan ft = fftwl_plan_dft_1d(4096, A, A, FFTW_BACKWARD, FMODE);
long double q, u, overN = ((long double) 1.L/4096);
for (long int j = 0; j < 4096; j++) {
q = 2.L*PI*(j*overN - 0.5L);
u = 2.L*atan2l(0.5L*sinl(0.5L*q),cosl(0.5L*q));
A[j] = -1.IL*cpowl(0.01L*(1.L/ctanl(0.5L*(u-0.1IL)) - 1.IL),2);
}
printf("%26.18LE\t%26.18LE\n", creall(A[1]), cimagl(A[1]));
fftwl_execute(ft);
for (int j = 0; j < 2048; j++) {
A[j] = -1.0IL*((fftwl_complex) j*A[j])*overN;
}
printf("%26.18LE\t%26.18LE\n", creall(A[1]), cimagl(A[1]));
memset(A+2048, 0, 2048*sizeof(fftwl_complex));
fftwl_execute(ft);
printf("%26.18LE\t%26.18LE\n", creall(A[1]), cimagl(A[1]));
}
据我所知,最终printf的结果必须是 但是,对于所有运行,同样高达17-18个十进制数字 我得到的是小数点后14位。 这样的事情可能表明长双 被降级为 double 类型。代码的输出 从一次运行变为另一次运行:
2.907416794556517046E-07 9.025765251354815022E-05
-5.697284273172913999E-04 7.463682637972633967E-24
1.895341327532694420E-04 3.343168537700265992E-07
2.907416794556517046E-07 9.025765251354815022E-05
-5.697284273172913999E-04 1.965167197605865111E-23
1.895341327532697672E-04 3.343168537692799396E-07
关于我在哪里失去长双准确度的任何想法?
答案 0 :(得分:0)
由复数FFT产生的数组的每个项目都是a weighted sum of the 4096 items of the input array,可以用不同的方式计算。可以按照here所述执行对错误传播方式的研究。
由于和的权重总是为1,因此输出数组的项的方差是输入数组的项的方差之和(输入数组的项被视为独立的随机变量)。
精度1e-18是标准偏差与值的范数之比。因此,如果使用long double:
最后,结果的精度写道:
这个等式的直接结果是灾难性消除的现象:输出的标准偏差是有限的,但是值|y|
非常小,因为相似的值被减去...结果,没有数字很重要!例如,请参见此处(https://en.wikipedia.org/wiki/Loss_of_significance)。这解释了为什么7.463682637972633967E-24
在您的案例中很容易成为1.965167197605865111E-23
。实际上,如果发生部分消除,精度可以很容易地从1e-18降低到像1e-14这样的值。 | y |的值较小具有较少有效数字。
输出不同于一次运行的事实可能是由于使用了标志FFTW_MEASURE
。如果使用此标志,将尝试不同的算法,FFTW将选择最快的算法。由于长度为4096的1D FFT现在非常快,因此定时可能不是非常一致,并且可以选择具有可比性能的不同算法。不同的算法将导致不同的计算和非有效数字的不同结果。如果使用标志FFTW_ESTIMATE
,这些变体是否仍然存在?如果使用此标志,it seems that FFTW uses a simple heuristic to choose the algorithm。这种启发式很可能是确定性的......