如何在 Julia 中测试特定数字有效数字的近似相等性

Pål*_*tan 1 significant-digits approximate julia

isapprox()Julia 中的函数用于测试两个数字或数组是否近似相等。我希望能够测试任何所需数量的有效数字的近似相等性。正如下面的代码示例所示,近似容差要么以绝对值给出,要么以相对(百分比)偏差给出。

# Syntax
isapprox(a, b; atol = <absolute tolerance>, rtol = <relative tolerance>)

# Examples
# Absolute tolerance
julia> isapprox(10.0,9.9; atol = 0.1) # Tolerance of 0.1
true

# Relative tolerance
julia> isapprox(11.5,10.5; rtol = 0.1) # Rel. tolerance of 10%
true

julia> isapprox(11.4,10.5; rtol = 0.01) # Rel. tolerance of 1%
false

julia> isapprox(98.5, 99.4; rtol = 0.01) # Rel. tolerance of 1%
true
Run Code Online (Sandbox Code Playgroud)

我在某处的论坛中读到该设置rtol = 1e-nn有效数字的数量将比较有效数字。(不幸的是,我无法再次找到它。)不管怎样,正如示例所示,这显然不是真的。

鉴于在这种情况下我们想用两位有效数字近似相等,11.4 和 10.5 都近似等于 11。但是,两者之间的相对差异大于 1%,返回近似值false。但是,对于任何大于 90 的数字,近似值将为true。如代码所示,将相对容差增加十倍至 10% 将导致灵敏度过低。

是否有一个参数/值/公式我可以设置rtolisapprox()返回true正确为显著位数任何期望是多少?

PaS*_*STE 5

快速回答是否定的,没有固定值,rtol您可以选择保证isapprox(x, y; rtol=rtol)比较值xy一定数量的有效数字。这是因为,如何isapprox实现rtol相对于计算最大norm(x)norm(y)。您必须rtol为每对计算一个不同的值,x并且y您正在比较。

看起来您要求的是一种将xy 四舍五入到一定数量的有效数字(以 10 为基数)的值进行比较的方法。该round方法有一个sigdigits可能有用的关键字:

isapproxsigfigs(a, b, precision) = round(a, sigdigits=precision) == round(b, sigdigits=precision)

isapproxsigfigs(10, 9.9, 1)  # true,  10 == 10
isapproxsigfigs(10, 9.9, 2)  # false, 10 != 9.9

isapproxsigfigs(11.4, 10.5, 1)  # true,  10 == 10
isapproxsigfigs(11.4, 10.5, 2)  # false, 11 != 10 (remember RoundingMode!)

isapproxsigfigs(11.4, 10.51, 1)  # true,  10 == 10
isapproxsigfigs(11.4, 10.51, 2)  # true,  11 == 11
isapproxsigfigs(11.4, 10.51, 3)  # false, 11.4 != 10.5
Run Code Online (Sandbox Code Playgroud)

对于第二个示例,请记住,如果您四舍五入,则 10.5 只是“几乎 11”。RoundingModeJulia 使用的默认值是RoundNearest,它舍入为偶数。如果您希望领带四舍五入,请使用RoundNearestTiesUp

isapproxsigfigs2(a, b, precision) = 
    round(a, RoundNearestTiesUp, sigdigits=precision) == 
    round(b, RoundNearestTiesUp, sigdigits=precision)

isapproxsigfigs2(11.4, 10.5, 2)  # true, 11 == 11
Run Code Online (Sandbox Code Playgroud)