linspace 和冒号表示法的区别是给出非零元素

问题描述 投票:0回答:1

我的问题如下:在

0 : 0.2 : 10
函数中写入冒号符号
linspace
并编写一个命令,使两者的差值看起来为 0。

我尝试以下代码:

A = 0 : 0.2 : 10
B = linspace(0, 10, 51)
A - B

但是,它给出以下输出

ans =

 Columns 1 through 6:
0            0            0            0            0            0

 Columns 7 through 12:
0            0            0            0            0            0

 Columns 13 through 18:
0            0            0            0            0            0

 Columns 19 through 24:
0            0            0            0            0            0

 Columns 25 through 30:
0            0   8.8818e-16   8.8818e-16   8.8818e-16   8.8818e-16

 Columns 31 through 36:
0   8.8818e-16            0   8.8818e-16   8.8818e-16            0

 Columns 37 through 42:
8.8818e-16            0   8.8818e-16   8.8818e-16            0   1.7764e-15

 Columns 43 through 48:
0            0            0            0   1.7764e-15            0

 Columns 49 through 51:
1.7764e-15            0            0 

非零元素困扰着我。我想我已经完成了

linspace
部分。如何形成命令以使差异被视为零?我需要一些提示。请尝试在不使用高级工具的情况下尽可能地提示命令!

octave
1个回答
0
投票

为了理解发生了什么,不要试图理解“有限的二进制精度”、“不能完全用二进制表示的数字”的概念,而是考虑“十进制精度”和“不完全可以表示的数字”上下文中的等效情况可以用十进制表示。为了方便起见,让我们考虑一个更简单的问题:

A = 0 : 1/6 : 1
B = linspace( 0, 1, 7 )

我们假设我们的 CPU 精确到 4 位有效数字。

关于A;在这里,我们注意到 1/6 不能直接用十进制表示。因此,我们的十进制 CPU 会将其转换为最接近的十进制表示形式,即 0.1667。因此范围将变为:

  0,
  0      + 0.1667 = 0.1667
  0.1667 + 0.1667 = 0.3334
  0.3334 + 0.1667 = 0.5001
  0.5001 + 0.1667 = 0.6668
  0.6668 + 0.1667 = 0.8335
  0.8335 + 0.1667 = 1.0002

关于B:内部,linspace算法会尝试执行以下计算:

B = 
     0/6 = 0.0000
     1/6 = 0.1667
     2/6 = 0.3333
     3/6 = 0.5000
     4/6 = 0.6667
     5/6 = 0.8333
     6/6 = 1.0000

因此,在具有 4 位有效数字精度的十进制系统中:

A-B = 
      0
      0
      0.0001
      0.0001
      0.0001
      0.0002
      0.0002

二进制也有类似的情况;值 0.2 不能“精确地”用二进制表示,因此它是近似值。在“范围”中,它被重复添加。在“linspace”中,除法在内部进行,如果输出不能完全被 2 整除,则输出是近似值。

所以你的问题“如何让 A-B 恰好为 0”并不是选择“更好的函数”的问题。这是一个拥有无限精度的理论计算机来进行计算的问题。

因此,您问错了问题。正确的问题是,考虑到机器精度的某种程度的公差,这两个输出是否相同为零?可接受的容忍度是多少?

回答这个问题的一种方法是通过

assert
函数以及返回机器精度的
eps
函数,来查看两个变量在相对于
eps
的某个公差范围内是否相等:

try  ; assert( A, B, eps ), disp('All elements are equal for the given tolerance')
catch; disp('Elements were not equal for the given tolerance')
end_try_catch
# Elements were not equal for the given tolerance

try  ; assert( A, B, 10*eps ), disp('All elements are equal for the given tolerance')
catch; disp('Elements were not equal for the given tolerance')
end_try_catch
# All elements are equal for the given tolerance

在我的机器上,eps=2e-16。因此 A-B 为零,公差为 2e-15。这是否可以接受完全取决于您和问题的性质。但机器精度是计算机的固有限制,人们必须意识到它的存在以及它如何影响您对计算的解释。

© www.soinside.com 2019 - 2024. All rights reserved.