计算数值误差

时间:2015-08-18 17:03:29

标签: c++ math linear-algebra numerical intel-mkl

如此question所示,MKL给出的结果与串行和分布式执行之间存在差异。出于这个原因,我想研究这个错误。从我的书中我得到了:

|ε_(x_c)| = |x - x_c| <= 1/2 * 10^(-d),其中d指定实际数字x与计算机所具有的数字x_c之间准确的十进制数字。

|ρ_(x_c)| = |x - x_c|/|x| <= 5 * 10^(-s)绝对相对错误,其中s指定有效位数。

所以,我们可以编写这样的代码:

double calc_error(double a,double x)
{
  return std::abs(x-a)/std::abs(a);
}

以便计算绝对错误,例如here

除绝对误差和绝对相对误差外,是否还有更多类型的错误要研究?

以下是我的一些数据:

serial gives:
-250207683.634793 -1353198687.861288 2816966067.598196 -144344843844.616425 323890119928.788757
distributed gives:
-250207683.634692 -1353198687.861386 2816966067.598891 -144344843844.617096 323890119928.788757

然后我可以将想法扩展到实际的数据和结果。

2 个答案:

答案 0 :(得分:3)

它不会比绝对和绝对相对错误复杂得多。还有另一种方法可以比较浮点格式的整数表示,这个想法是你想要你的&#34;容差&#34;适应你正在比较的数字的大小(特别是因为没有&#39;#34;尽可能多的&#34;数字取决于幅度)。

总而言之,我认为你的问题与浮点数比较非常相似,其中有this excellent guide,而这更详尽但much longer paper

为了比较浮点值,也可能值得投入:

#include <limits>
#include <cmath>

template <class T>
struct fp_equal_strict
{
    inline bool operator() ( const T& a, const T& b )
    {
        return std::abs(a - b) 
            <= std::max(
                std::numeric_limits<T>::min() * std::min( std::abs(a), std::abs(b) ),
                std::numeric_limits<T>::epsilon()
            );
    }
};

template <class T>
struct fp_equal_loose
{
    inline bool operator() ( const T& a, const T& b )
    {
        return std::abs(a - b) 
            <= std::max(
                std::numeric_limits<T>::min() * std::max( std::abs(a), std::abs(b) ),
                std::numeric_limits<T>::epsilon()
            );
    }
};

template <class T>
struct fp_greater
{
    inline bool operator() ( const T& a, const T& b )
    {
        return (a - b) >= std::numeric_limits<T>::min() * std::max( std::abs(a), std::abs(b) );
    }
};

template <class T>
struct fp_lesser
{
    inline bool operator() ( const T& a, const T& b )
    {
        return (b - a) >= std::numeric_limits<T>::min() * std::max( std::abs(a), std::abs(b) );
    }
};

答案 1 :(得分:2)

我要提到的是,还可以执行ULP(最后位置中的单位)比较,其显示二进制表示中两个浮点数的距离。这是&#34;亲密关系&#34;因为如果两个数字例如是一个ULP分开,则意味着它们之间没有浮点数,因此它们在二进制表示中尽可能接近而没有实际上相等。

这个方法被描述为here,这是一个比同一作者接受的答案链接的文章更新的版本。还提供了示例代码。

顺便说一句,但与工作的上下文相关(比较顺序浮点计算和并行浮点计算),重要的是要注意浮点运算不是关联的,这意味着并行实现通常不会给出与顺序相同的结果实现。即使更改编译器和优化选项实际上也会导致不同的结果(例如GCC vs ICC,-O0 vs -O3)。

可以找到关于如何减少用于执行浮点数求和的错误计算的示例算法here,并且可以找到该算法的作者的综合文档here