首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何检验朱莉娅中特定数有效数字的近似相等

如何检验朱莉娅中特定数有效数字的近似相等
EN

Stack Overflow用户
提问于 2021-08-05 12:23:05
回答 3查看 1.5K关注 0票数 2

朱莉娅中的isapprox()函数用于测试两个数字或数组是否大致相等。我希望能够测试任何期望的有效位数的近似相等性。正如下面的代码示例所演示的那样,对于近似的公差要么是绝对值,要么是相对(百分比)偏差。

代码语言:javascript
运行
复制
# 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

我在一个设置rtol = 1e-n的论坛上读到,其中n是重要数字的数量,它将比较重要数字。(不幸的是,我又找不到了。)无论如何,正如示例所示,这显然是不正确的。

在这种情况下,如果我们想用两个有效数字近似相等,那么11.4和10.5都大约等于11。然而,两者之间的相对差大于1%,返回了近似false。然而,对于大于90的任何数,近似都是true。如代码所示,将相对容忍度提高10倍至10%将导致灵敏度过低。

是否有一个参数/值/公式,我可以将rtol设置为isapprox(),以正确返回任何所需数量的有效数字的true

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-08-06 01:30:14

快速的答案是 no ,没有固定的rtol值,您可以选择它来保证isapprox(x, y; rtol=rtol)将值xy与一定数量的重要数字进行比较。这是因为已实现rtol是相对于norm(x)norm(y)的最大值计算的。您必须为正在比较的每一对rtoly计算一个不同的y

看起来您所要求的是一种方法,将xy的值四舍五入到一定数量的有效数字(以基数10表示)。round方法有一个可能有用的关键字sigdigits

代码语言:javascript
运行
复制
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

对于第二个例子,记住10.5只是“几乎11”,如果你四舍五入。朱莉娅使用的默认RoundingModeRoundNearest,它与偶数挂钩。如果您想要联系起来,请使用RoundNearestTiesUp

代码语言:javascript
运行
复制
isapproxsigfigs2(a, b, precision) = 
    round(a, RoundNearestTiesUp, sigdigits=precision) == 
    round(b, RoundNearestTiesUp, sigdigits=precision)

isapproxsigfigs2(11.4, 10.5, 2)  # true, 11 == 11
票数 6
EN

Stack Overflow用户

发布于 2021-08-05 14:05:22

我认为您可能只需要为此定义您自己的函数。一些棘手的细节:

  1. 你关心哪个基地?
  2. 你想如何对待+0和-0?
  3. 一般都是0的数字?
  4. 非正态化数字?
  5. 接近无穷远的数字?

在大多数情况下,一个快速的穷人版本可能会做正确的事情,那就是对两个数字进行格式打印,并对两个数字进行比较。

代码语言:javascript
运行
复制
using Formatting

julia> function isapproxsigfigs(a, b, precision)
         fmt = "{:.$(precision-1)e}"
         format(fmt, a) == format(fmt, b)
       end
isapproxsigfigs (generic function with 1 method)

julia> isapproxsigfigs(pi, 3.14, 3)
true

julia> isapproxsigfigs(pi, 3.14, 4)
false

应该对基数10起作用,总是把正数和负数视为不相等的,并且可能用非正态数做正确的事情。您可能希望添加对无穷大和NaN的显式检查,因为此实现将无穷大视为相等,更糟糕的是,NaNs将其视为相等。

注意:未来的读者也许可以

代码语言:javascript
运行
复制
isapproxsigfigs(a, b, precision) = @sprintf("%.*e", precision, a) == @sprintf("%.*e", precision, b)

但朱莉娅目前不支持.*格式字符串的精确规范。不过,这是一种公关,所以也许v1.7以后会支持它。

票数 0
EN

Stack Overflow用户

发布于 2021-08-05 20:46:13

您可以从NumPy获得提示并实现:

代码语言:javascript
运行
复制
less_equal(x,y) = x <= y
isclose(x, y, atol, rtol) = less_equal(abs(x-y), atol + rtol * abs(y))

这并不是很好的向量化,所以如果您想要一个向量化版本,请确保查看allclose。而且,使用rtol使它在xy上不可交换,所以要注意这一点。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68666525

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档