2013-03-16 110 views
0

我有一项任务是尽可能使下列函数精确(速度不是目标)。我必须使用浮法方法中间矩形。你能提出一些建议吗?其实,我认为,这都是关于最小化浮动四舍五入误差。这就是我所做的:优化浮点运算

typedef float T; 

T integrate(T left, T right, long N, T (*func)(T)) { 
    long i = 0; 
    T result = 0.0; 
    T interval = right - left; 
    for(i = 0; i < N; i++) { 
     result += func(left + interval * (i + 0.5)/N) * interval/N; 
    } 
    return result; 
} 
+1

'result + = func(left + interval *(i + 0.5)/ N)* interval'和'return result/N;' – 2013-03-16 18:47:58

+0

函数指针调用是否必要?它可以内联吗? – Mysticial 2013-03-16 18:48:20

+0

@Mysticial是的,这是必要的。但我不需要速度,我需要精确度,所以没关系。 – 2013-03-16 18:51:02

回答

3

有很多方法可以避免或弥补浮点舍入(MM的建议,使用卡汉求和等)。然而,没有理由这样做,因为由整合方案的误差,舍入误差为绝对矮于;你不会得到更准确的积分,你会得到一个更准确的近似值,由中点规则计算出的错误结果。除非是在极其特殊的情况下,任何此类努力都被完全浪费。

+0

对于N = 18823,相对误差为-1,78814E-07(从0到Pi积分sin(x))。如果我将T变成双倍,那就是1,16068E-09。差异并不大,是的。 – 2013-03-16 19:06:42

1

试试这个:

{ 
    long i = 0; 
    T result = 0.0; 
    T interval = right - left; 
    for(i = 0; i < N; i++) { 
     result += func(left + interval * (i + 0.5)/N); 
    } 
    return result * interval/N; 
} 
+0

没有帮助或帮助很少。 – 2013-03-16 19:00:23

+2

这是他最好的,你可以得到,国际海事组织。它是唯一可以对精度进行优化的方法(也许是索引的计算,即i + 0.5部分 - 您可以使用while循环并递增float而不是整数值。但是您不能期望32位浮点数的精确度太高 – 2013-03-17 06:37:12

3

I have a task to make the following function as precise as possible

你说你必须使用float,所以我想这个问题是不是四舍五入,而是约更准确地计算积分。

我还假设简单增加N不是一个选项。

而不是使用中点规则,我的建议是考虑使用higher-order quadrature rule (trapezoid, Simpson's etc)

+2

完全正确。对于几乎任何'func'的选择,由于浮点舍入导致的错误归因于集成方案。显着提高准确性的唯一方法是使用更复杂的集成器。 – 2013-03-16 18:52:29

+0

哦,对不起,我编辑过问题:我必须使用中间矩形的方法。所以一切都是关于花车。我怎样才能重新组合它们,增加,乘以等等来使计算更精确。 – 2013-03-16 18:55:11

1

如果要精确计算积分,请阅读积分方案。一些家庭针织的例程不会给任何精度

"Numerical recipes"(有几个版本,一个用于C)是高度重视。没有亲自看过它。