python - 如何在 Python 文档字符串测试中处理四舍五入到负零

标签 python numpy docstring doctest

与此问题相关:How to have negative zero always formatted as positive zero in a python string?
我有以下使用 Numpy 实现 Matlab 的 orth.m 的函数。我有一个依赖于 np.array2string 的 docstring 测试,使用suppress_small=True,这将使小值四舍五入为零。但是,有时它们会舍入到正零,有时会舍入到负零,这取决于答案是 1e-16 还是 -1e-17 或类似结果。哪种情况发生基于 SVD 分解,并且可能因平台或 Python 版本而异,具体取决于使用的底层线性代数求解器(BLAS、Lapack 等)
设计文档字符串测试以解决此问题的最佳方法是什么?
在最终的 doctest 中,有时 Q[0, 1] 项是 -0。有时它是0。

import doctest
import numpy as np

def orth(A):
    r"""
    Orthogonalization basis for the range of A.

    That is, Q.T @ Q = I, the columns of Q span the same space as the columns of A, and the number
    of columns of Q is the rank of A.

    Parameters
    ----------
    A : 2D ndarray
        Input matrix

    Returns
    -------
    Q : 2D ndarray
        Orthogonalization matrix of A

    Notes
    -----
    #.  Based on the Matlab orth.m function.

    Examples
    --------
    >>> import numpy as np

    Full rank matrix
    >>> A = np.array([[1, 0, 1], [-1, -2, 0], [0, 1, -1]])
    >>> r = np.linalg.matrix_rank(A)
    >>> print(r)
    3

    >>> Q = orth(A)
    >>> with np.printoptions(precision=8):
    ...     print(Q)
    [[-0.12000026 -0.80971228  0.57442663]
     [ 0.90175265  0.15312282  0.40422217]
     [-0.41526149  0.5664975   0.71178541]]

    Rank deficient matrix
    >>> A = np.array([[1, 0, 1], [0, 1, 0], [1, 0, 1]])
    >>> r = np.linalg.matrix_rank(A)
    >>> print(r)
    2

    >>> Q = orth(A)
    >>> print(np.array2string(Q, precision=8, suppress_small=True))  # Sometimes this fails
    [[-0.70710678 -0.        ]
     [ 0.          1.        ]
     [-0.70710678  0.        ]]

    """
    # compute the SVD
    (Q, S, _) = np.linalg.svd(A, full_matrices=False)
    # calculate a tolerance based on the first eigenvalue (instead of just using a small number)
    tol = np.max(A.shape) * S[0] * np.finfo(float).eps
    # sum the number of eigenvalues that are greater than the calculated tolerance
    r = np.sum(S > tol, axis=0)
    # return the columns corresponding to the non-zero eigenvalues
    Q = Q[:, np.arange(r)]
    return Q

if __name__ == '__main__':
    doctest.testmod(verbose=False)

最佳答案

您可以打印圆形数组加0.0消除 -0 :

A = np.array([[1, 0, 1], [0, 1, 0], [1, 0, 1]])
Q = orth(A)
Q[0,1] = -1e-16   # simulate a small floating point deviation

print(np.array2string(Q.round(8)+0.0, precision=8, suppress_small=True))
#[[-0.70710678  0.        ]
# [ 0.          1.        ]
# [-0.70710678  0.        ]]
所以你的文档字符串应该是:
>>> Q = orth(A)
>>> print(np.array2string(Q.round(8)+0.0, precision=8, suppress_small=True)) # guarantee non-negative zeros
[[-0.70710678  0.        ]
 [ 0.          1.        ]
 [-0.70710678  0.        ]]

关于python - 如何在 Python 文档字符串测试中处理四舍五入到负零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66283651/

相关文章:

python - Paramiko 有时会引发 'AuthenticationException'

python数组时间复杂度?

python - 带条件的 Pandas DF 中的一系列算术 - 先前的操作被覆盖

python - Sphinx 中是否有使用 sphinx.ext.napoleon 记录函数类型参数的标准格式?

python - @param 和 : param in Pycharm 有什么区别

python - 在类方法文档字符串中使用字符串格式

python - 执行 Python 脚本而不生成带有子进程的新进程

python - 谷歌云函数 : How to get access tokens in cloud function for the required scope?

python - 提高纯 Numpy/Scipy 卷积神经网络实现的速度

python - 为什么导入 cupy 时会出现 ModuleNotFoundError 错误?