Matlab linspace和range与Kahan求和算法的精度比较

Matlab linspace和range与Kahan求和算法的精度比较,matlab,parallel-processing,floating-point,vectorization,double-precision,Matlab,Parallel Processing,Floating Point,Vectorization,Double Precision,我使用Matlablinspace函数和range:操作符来获得等距向量,但我收到的是等距数字。我的代码如下: format long x1 = linspace(3,5,20); diff(x1) x2 = 3:0.1:5; diff(x2) x1 0.105263157894737 0.105263157894737 0.105263157894737 0.105263157894737 0.105263157894737 0.105263157894737

我使用Matlab
linspace
函数和range
操作符来获得等距向量,但我收到的是等距数字。我的代码如下:

format long

x1 = linspace(3,5,20);
diff(x1)

x2 = 3:0.1:5;
diff(x2)
x1    
0.105263157894737   
0.105263157894737   
0.105263157894737   
0.105263157894737
0.105263157894737
0.105263157894737
0.105263157894737   
0.105263157894737
0.105263157894737   
0.105263157894737   
0.105263157894737   
0.105263157894737
0.105263157894736   
0.105263157894737   
0.105263157894737   
0.105263157894736
0.105263157894737   
0.105263157894736   
0.105263157894737

x2
0.100000000000000   
0.100000000000000   
0.100000000000000   
0.100000000000000
0.100000000000000   
0.100000000000000   
0.100000000000000   
0.100000000000000
0.100000000000000   
0.100000000000000   
0.100000000000000   
0.100000000000001
0.100000000000000   
0.100000000000001   
0.100000000000000   
0.100000000000000
0.100000000000001   
0.100000000000000   
0.100000000000001   
0.100000000000000
向量差(
diff
)的输出如下:

format long

x1 = linspace(3,5,20);
diff(x1)

x2 = 3:0.1:5;
diff(x2)
x1    
0.105263157894737   
0.105263157894737   
0.105263157894737   
0.105263157894737
0.105263157894737
0.105263157894737
0.105263157894737   
0.105263157894737
0.105263157894737   
0.105263157894737   
0.105263157894737   
0.105263157894737
0.105263157894736   
0.105263157894737   
0.105263157894737   
0.105263157894736
0.105263157894737   
0.105263157894736   
0.105263157894737

x2
0.100000000000000   
0.100000000000000   
0.100000000000000   
0.100000000000000
0.100000000000000   
0.100000000000000   
0.100000000000000   
0.100000000000000
0.100000000000000   
0.100000000000000   
0.100000000000000   
0.100000000000001
0.100000000000000   
0.100000000000001   
0.100000000000000   
0.100000000000000
0.100000000000001   
0.100000000000000   
0.100000000000001   
0.100000000000000
为了解决这个问题,我通过以下代码使用Kahan求和方法:

dx = 2/19;
x3 = zeros(size(x1));
x3(1) = 0;
partial_sum = 0;
c = 0.0;
for k=2:20,
    y = dx - c;
    t = partial_sum + y;
    c = (t - partial_sum) - y;
    partial_sum = t;
    x3(k) = partial_sum;
end
diff(x3)
我现在得到一个等间距的向量

0.105263157894737   
0.105263157894737   
0.105263157894737   
0.105263157894737
0.105263157894737   
0.105263157894737   
0.105263157894737   
0.105263157894737
0.105263157894737   
0.105263157894737   
0.105263157894737   
0.105263157894737
0.105263157894737   
0.105263157894737   
0.105263157894737   
0.105263157894737
0.105263157894737   
0.105263157894737   
0.105263157894737
然而,这种方法是“循序渐进的”。有人知道Kahan求和方法的矢量化或并行实现,以提高效率或将其移植到(CUDA)并行简化中吗


先谢谢你

我想你是误解了

(a)使用
linspace
。你的电话

linspace(3,5,20)
返回20个等距数字,从3开始,到5结束。试一试

linspace(3,5,21)
相反。请注意,向量
x
x2
的长度相差1

(b)

浮点运算的精妙之处。这个话题已经被广泛地讨论过了,所以我不会重复已经找到的许多好的解释中的任何一个


我想你看到的是对于大多数数字应用来说,间距相等的数字。

我想这个链接会很有帮助:

您将找到
XSum
函数,您可以在其中切换和测试不同的求和方法:

  • Double:Matlab的SUM的线程安全实现。至少在Matlab2008a到2009b中,多线程求和的结果可能会因调用而异。比单线程求和(MSVC++2008)快50%,精度相当
  • Long:如果编译器支持此功能(例如LCC v3.8),则以80位长的双精度形式累积。3.5个以上有效数字,速度慢40%
  • Kahan:从下一个元素中减去局部误差。多1到3个有效数字,速度慢10%
  • Knuth:好像总和是以128位浮点形式累加的:大约多15个有效数字。速度大致相同(MSVC++2008编译器)。这适用于大多数实际问题
  • Knuth2:30个以上的有效数字,就好像它是在196位浮点中累积的一样。慢60%
  • KnuthLong:与Knuth相同,但如果编译器支持,则使用长双精度可以获得大约21个以上的有效数字。慢2.5倍

值得一看:(使用Wayback机器检索,MathWorks出于某种原因删除了页面!)非常有用。非常感谢。你是对的,但我认为这是一个一错再错的错误。另外,所用的例子并不是最好的例子。试试这个:
(0:0.1:1)-linspace(0,1,11)
我认为我们都忽略了主要问题:
卡汉总结
。我承认,我的“答案”可能是一个延伸的评论,而不是对卡汉总结问题(部分)的回答。但是,如果OP的意思是“我还没有完全理解linspace和:所以我要实现Kahan求和”,我的答案是“理解linspace和:首先”。但是嘿,不管怎样,伙计。@Amro我为什么要尝试
(0:0.1:1)-linspace(0,1,11)
?@fpe是的。更准确地说:Kahan求和法或类似方法的矢量化/并行化。非常感谢您的回答。你能简短地评论一下矢量化/并行化吗?您谈到多线程求和,至少对于“Double”方法。这已经“多线程就绪”了吗?其他的方法呢?谢谢