使对角矩阵和置换矩阵本身成为特殊的矩阵对象,并因此对某些运算使用更智能的算法,作为副作用,简化了处理零的微小差异。本节的内容也适用于稀疏矩阵,将在下一章中讨论。详见稀疏矩阵)
IEEE 754浮点标准定义了表达式0*Inf和0*NaN为NaN.
这被广泛认为是很好的妥协,而且Octave力求符合这一标准。
然而,为结构化和稀疏矩阵设计的算法为了提高效率,可能不符合IEEE 754浮点标准,关于应该算得NaN的零元素的操作,例如
0*Inf, 0/0, 或者0*NaN.
数值软件处理结构化和稀疏矩阵(包括Octave)几乎总是区分“数值零”和“假定为零”。 一个"numerical zero"是在可能发生任何浮点值的地方出现的零值。它通常以一个明确的值存储在内存中。 一个“假定为零”是由矩阵结构(对角,三角)或稀疏模式暗示的零矩阵元素;它的值通常在任何地方都没有明确地存储,而是由底层数据结构隐含。
主要的区别是,假定零乘以或除以任何数总是产生零,即使例如乘以Inf或除以NaN。
这种行为的原因是底层算法实际上并不在任何位置进行数值乘法;结果只是假定为零。
Octave试图通过将底层算法分支到专门实现来处理实际上影响假定零的操作,从而减轻这种行为。 这主要是在计算效率和遵循浮点标准之间的权衡,通过将假定的零视为数值零来实现。 除了计算速度的差异之外,这种行为还会影响稀疏模式,在操作非常大的稀疏矩阵时应考虑这一点,否则可能导致内存溢出错误。
在稀疏矩阵中将假定零视为数字零的操作的示例:
speye (3) ⇒ Compressed Column Sparse (rows = 3, cols = 3, nnz = 3 [33%]) (1, 1) -> 1 (2, 2) -> 1 (3, 3) -> 1 Inf * speye (3) ⇒ Compressed Column Sparse (rows = 3, cols = 3, nnz = 9 [100%]) (1, 1) -> Inf (2, 1) -> NaN (3, 1) -> NaN (1, 2) -> NaN (2, 2) -> Inf (3, 2) -> NaN (1, 3) -> NaN (2, 3) -> NaN (3, 3) -> Inf Inf * full (eye (3)) ⇒ Inf NaN NaN NaN Inf NaN NaN NaN Inf speye (3) / 0 ⇒ Compressed Column Sparse (rows = 3, cols = 3, nnz = 9 [100%]) (1, 1) -> Inf (2, 1) -> NaN (3, 1) -> NaN (1, 2) -> NaN (2, 2) -> Inf (3, 2) -> NaN (1, 3) -> NaN (2, 3) -> NaN (3, 3) -> Inf full (eye (3)) / 0 ⇒ Inf NaN NaN NaN Inf NaN NaN NaN Inf
虽然在稀疏矩阵中只有稀疏模式可能会受到某些操作的影响,但在处理对角矩阵时,这些操作也可能影响返回的类型。适用以下规则:
例如:
3 * eye (3)
⇒
Diagonal Matrix
3 0 0
0 3 0
0 0 3
Inf * eye (3)
⇒
Inf NaN NaN
NaN Inf NaN
NaN NaN Inf
eye (3) / 0
⇒
Inf NaN NaN
NaN Inf NaN
NaN NaN Inf
eye (3) / NaN
⇒
NaN NaN NaN
NaN NaN NaN
NaN NaN NaN
eye (3) / Inf
⇒
Diagonal Matrix
0 0 0
0 0 0
0 0 0
eye (3) / 2
⇒
Diagonal Matrix
0.5000 0 0
0 0.5000 0
0 0 0.5000
注意Octave (和 MATLAB)不严格符合IEEE 754浮点标准,并且在像下面的例子中的某些情况下,底层算法不将假定零视为数字零。 正如Octave 11中的那样,目的是使Octave完全符合IEEE 754标准,以便对密集、稀疏或任何其他特殊矩阵类型的操作产生相同的一致结果。 因此,预计在下面的例子中的输出可能会在未来的 Octave 版本中发生变化。
假定零与数字零的影响示例:
diag (1:3) * [NaN; 1; 1]
⇒
NaN
2
3
sparse (1:3,1:3,1:3) * [NaN; 1; 1]
⇒
NaN
2
3
[1,0,0;0,2,0;0,0,3] * [NaN; 1; 1]
⇒
NaN
NaN
NaN
版权所有 © 2024-2026 Octave中文网
ICP备案/许可证号:黑ICP备2024030411号-2