Floating point 可靠地确定浮点值的向量是否(数值上)等距

Floating point 可靠地确定浮点值的向量是否(数值上)等距,floating-point,Floating Point,假设有一个浮点值向量 X = [x1, x2, x3 ... xN] 我想检查这些值是否等距分布。当然,由于浮点运算的缘故,我们不能保证相邻的差异都是相同的 执行此检查的稳健算法是什么 从某种意义上说,它是健壮的 不对矢量元素的大小和符号进行假设 也不是关于向量的长度 无论等距序列是通过重复递增还是通过乘法i*dx+x0生成的,都有效 现在我看一下差异向量,将它们四舍五入到小数点后的某个数字,然后检查它们是否都相同。但是,这不够健壮,如果向量很长,有时会失败。 我选择的小数位数是最大绝对向

假设有一个浮点值向量

X = [x1, x2, x3 ... xN]
我想检查这些值是否等距分布。当然,由于浮点运算的缘故,我们不能保证相邻的差异都是相同的

执行此检查的稳健算法是什么

从某种意义上说,它是健壮的

  • 不对矢量元素的大小和符号进行假设
  • 也不是关于向量的长度
  • 无论等距序列是通过重复递增还是通过乘法
    i*dx+x0
    生成的,都有效
现在我看一下差异向量,将它们四舍五入到小数点后的某个数字,然后检查它们是否都相同。但是,这不够健壮,如果向量很长,有时会失败。 我选择的小数位数是最大绝对向量值乘以eps乘以10的
log10
,即
log10(max(abs(vec))*eps*10)

编辑:这是当前代码(在MATLAB中)和失败的案例。一切都是双重的,即IEEE binary64类型

function [b, v0, dv] = isequidistant(vec)
    diffv = diff(vec);
    % Note round(x,N) rounds to the N-th decimal place, e.g. round(1234, -2) == 1200
    diffv = round( diffv, -ceil(log10(max(abs(vec(~isinf(vec)&vec ~= 0)))*eps*10)) );
    diffv = unique( diffv );
    if length(diffv) == 1
        b = true;
        v0 = vec(1);
        dv = diffv;
    else
        b = false;
        v0 = vec(1);
        dv = nan;
    end
end
这在这里失败了:
Isequiditant([0:330000]*3.027872455e-01)=0

最有趣的是
Isequiditistant([0:330000]*3.02787245e-01)==1


我知道人们可能会玩弄常数和因子,但我在这里寻求更好的解决方案。上面的一个生成虚假故障实际上让我担心。

直接的方法是在第一个和最后一个元素之间生成一个线性间隔序列,并将每个元素与该序列进行比较

下面的代码允许与某些公差进行比较。公差参数可以是可选的(例如,默认值为
0
eps
):

功能[b,v0,dv]=Isequiditant(向量向量,公差)
v0=vec(1);vN=vec(结束);N=长度(vec);

b=all(abs(linspace(v0,vN,N)-vec)直接方法是在第一个和最后一个元素之间生成一个线性间隔序列,并将每个元素与之进行比较

下面的代码允许与某些公差进行比较。公差参数可以是可选的(例如,默认值为
0
eps
):

功能[b,v0,dv]=Isequiditant(向量向量,公差)
v0=向量(1);vN=向量(结束);N=长度(向量);

B=所有(ABS(林空间(V0,VN,N)-VEC)

允许某种程度的不精确性,并且仍然考虑“等距”,考虑计算所有的差异,记录最高和最低,然后最终访问HI和LO相对于平均值的差异。

// Pseudo code
X = [x1, x2, x3 ... xN]
if (N <= 2) return true;
avg = sum(x1...xN)/N
lo = x2 - x1
hi = x2 - x1
for (i = 3 to N)
   diff = xi - x(i-1)
   if (diff < lo) lo = diff
   if (diff > hi) hi = diff
 
 Now assess if lo,hi are too far apart
 Maybe by comparing the |(hi-lo)/avg| <= tolerance
//伪代码
X=[x1,x2,x3…xN]
如果(N高)高=差异
现在评估lo和hi是否相距太远

也许通过比较(HI LO)/AVG>P>在一定程度的不精确性被允许并且仍然考虑“等距”,考虑计算所有的差异,记录最高和最低,然后最终访问HI和LO相对于平均值的差异。
// Pseudo code
X = [x1, x2, x3 ... xN]
if (N <= 2) return true;
avg = sum(x1...xN)/N
lo = x2 - x1
hi = x2 - x1
for (i = 3 to N)
   diff = xi - x(i-1)
   if (diff < lo) lo = diff
   if (diff > hi) hi = diff
 
 Now assess if lo,hi are too far apart
 Maybe by comparing the |(hi-lo)/avg| <= tolerance
//伪代码
X=[x1,x2,x3…xN]
如果(N高)高=差异
现在评估lo和hi是否相距太远

也许通过比较|(hi-lo)/avg,你能给出一个你的方法失败的输入示例(例如,给出一个生成这样一个序列的算法)?重复增量和
i*dx+x0
(x0*(N-i)+xN*i)/N
(以及其他替代方案)可能会生成其他任何一种方法都无法复制的序列。您是否假设IEEE 754 binary64/binary32浮点或任何东西(即使有任意基数?)Re“我选择的小数位数是最大绝对向量值的log10乘以eps乘以10”:什么?如果100是最大绝对向量值,那么log10是2,epsilon是2^-52,对于IEEE-754二进制64,10,So 2•2^−52•10=4.44e-15小数位。这没有意义。再试一次?你需要的最大N是多少?你知道x0和dx的界限是什么?它们总是非负的吗?任何接受等距点但计算中的舍入误差的测试都必须接受一些不等距点。公差有多大你对这些误报有何解释?是什么原因导致你的点的间距不相等?它们是由某个过程产生的,该过程会告诉我们它们必须偏离相等间距多少?Re“…并且不假设这个等距序列是如何生成的”:这是一个不可能处理的条件。通常,算术错误的组合会产生从0到无穷大的错误,或者可以是NaN。您必须对数字的产生方式有一些限制,以便可以确定潜在错误的界限。@chtz I添加了我的(MATLAB)代码和失败的测试用例。你能给出一个你的方法失败的输入示例吗(例如,给出一个生成这样一个序列的算法)?重复增量和
i*dx+x0
(x0*(N-i)+xN*i)/N
(和其他备选方案)可能会生成其他任何一种方法都无法复制的序列。您是否假设IEEE 754 binary64/binary32浮点或任何东西(即使有任意基数?)Re“我选择的小数位数是最大绝对向量值的log10乘以eps乘以10”:什么?如果100是最大绝对向量值,那么log10是2,epsilon是2^-52,对于IEEE-754二进制64,10,So 2•2^−52•10=4.44e-15小数位。这没有意义。再试一次?你需要的最大N是多少?你知道x0和dx的界限是什么?它们总是非负的吗?任何接受等距点但计算中的舍入误差的测试都必须接受一些不等距点。公差有多大你对这种误报有什么看法?什么会使你的观点不一致