3

我的问题 - 第 1 部分:测试浮点数是否为“整数”(在 Matlab 中)的最佳方法是什么?

我目前对第 1 部分的解决方案:显然,isinteger已经过时了,因为它测试的是元素的类型,而不是值,所以目前,我解决了这样的问题:

    abs(round(X) - X) <= sqrt(eps(X))

但也许有更原生的 Matlab 方法?

我的问题 - 第 2 部分:如果我目前的解决方案确实是最好的方法,那么我想知道是否有推荐的一般公差?正如您从上面看到的,我使用sqrt(eps(X)),但我没有任何充分的理由这样做。也许我应该只使用eps(X),或者也许5 * eps(X)?任何建议都将受到欢迎。

示例:在 Matlab 中,sqrt(2)^2 == 2返回 False。但在实践中,我们可能希望该逻辑条件返回 True。可以使用上述方法实现这一点,因为sqrt(2)^2实际上等于2 + eps(2)(即完全在 的容差范围内sqrt(eps(2))。但这是否意味着我应该始终使用eps(X)作为我的容差,或者是否有充分的理由使用更大的容差,例如5 * eps(X)sqrt(eps(X))

更新(2012-10-31): @FakeDIY 指出我的问题部分是这个 SO 问题的重复(抱歉,不知道我在最初的搜索中是如何错过它的)。鉴于此,我想强调问题的“容忍”部分(该链接未涵盖),即是eps(X)一个合理的容忍,或者我应该使用更大的东西,比如5 * eps(X),如果是,为什么?

更新(2012-11-01):感谢大家的回复。我已经 +1 了所有三个答案,因为我觉得它们都对问题的各个方面做出了有意义的贡献。我将答案打勾给 Eric Postpischil,因为该答案确实很好地确定了问题的容差部分(并且此时它的支持率最高)。

4

3 回答 3

6

No, there is no general tolerance that is recommended, and there cannot be.

The difference between a computed result and a mathematically ideal result is a function of the operations that produced the computed result. Because those operations are specific to each application, there is no general rule for testing any property of a computed result.

To design a proper test, you must determine what errors may have occurred during computation, determine bounds on the resulting error in the computed result, and test whether the computed result differs from the ideal result (perhaps the nearest integer) by less than those bounds. You must also decide whether those bounds are sufficiently small to satisfy your application’s requirements. (Using a relaxed test that accepts as an integer something that is not an integer decreases false negatives [incorrect rejections of a result as an integer where the ideal result would be an integer] but increases false positives [incorrect acceptances of a result as an integer where the ideal result would not be an integer].)

(Note that it can even be the case the testing as if the error bounds were zero can produce false negatives: It is possible a computation produces a result that is exactly an integer when the ideal result is not an integer, so any error tolerance, even zero, will falsely report this result is an integer. If this is unacceptable for your application, then, in such a case, the computations must be redesigned.)

It is not only not possible to state, without specific knowledge of the application, a numerical tolerance that may be used, it is impossible to state whether the tolerance should be absolute, should be relative to the computed value or to a target value, should be measured in ULPs (units of least precision), or should be set in some other manner. This is because errors may be introduced into computations in a variety of ways. For example, if there is a small relative error in a and a and b are close in value, then a-b has a large relative error. Additionally, if c is large, then (a-b)*c has a large absolute error.

于 2012-10-31T11:23:55.437 回答
3

它可能不是最有效的方法,但我会mod为此使用:

a = 15.0000000000;
b = mod(a,1.0)
c = 15.0000000001;
d = mod(c,1.0) 

返回b = 0d = 1.0000e-010

这里建议了许多其他替代方案:

如何在 MATLAB 中测试整数?

我也喜欢比较的想法(x == floor(x))

于 2012-10-31T09:59:02.680 回答
1

1)我历来以简单的公差使用您的方法,eps(X)。不过,mod 方法让我很感兴趣,所以我使用 Steve Eddins timeit函数对一对夫妇进行了基准测试。

f = @() abs(X - round(X)) <= eps(X);
g = @() X == round(X);
h = @() ~mod(X,1);

对于单个值,例如X=1.0,您的值似乎最快:

timeit(f) = 7.3635e-006
timeit(g) = 9.9677e-006
timeit(h) = 9.9214e-006

但是,对于向量,例如X = 1:0.01:100,其他方法更快(尽管 round 仍然优于 mod):

timeit(f) = 0.00076636
timeit(g) = 0.00028182
timeit(h) = 0.00040539

2)误差界确实取决于问题。其他答案比我能做到的要好得多。

于 2012-10-31T22:44:56.553 回答