简体   繁体   English

cholesky分解浮点错误

[英]cholesky decomposition floating point error

Implementing the Choleky decomposition in Python without the use of numpy.linalg.* (yes this is an assignment) I encountered a Problem regarding the use of floating point numbers.在不使用 numpy.linalg.* 的情况下在 Python 中实现 Choleky 分解(是的,这是一项任务)我遇到了一个关于使用浮点数的问题。 My Algorithm works fine with regualar integers:我的算法适用于常规整数:

    for i in range(n):
        for k in range(i + 1):
            sum = 0
            for j in range(k):
                sum += L[i, j] * L[k, j]
            if i == k:
                if M[i, i] - sum < 0:
                    raise ValueError("Matrix is non-positive definite")
                L[i, i] = np.sqrt(M[i, i] - sum)
            else:
                if np.isclose(L[k, k] * (M[i, k] - sum), 0):
                    raise ValueError("Matrix is non-positive definite")
                L[i, k] = (L[k, k] * (M[i, k] - sum)) ** (-1)

I tested the matrix for symmetry beforehand;我事先测试了矩阵的对称性; n is the dimension and L becomes the lower triangular Cholesky Factor. n 是维度,L 成为下三角 Cholesky 因子。

Using random floating point nxn matrices multiplied with their transpose (in order to get a positive definite matrix) both ValueErrors are raised, ie w/out raising the ValueErrors the L output matrix is partly filled with NaN and inf values.使用随机浮点 nxn 矩阵乘以它们的转置(为了获得正定矩阵)两个 ValueErrors 都会被引发,即没有引发 ValueErrors L 输出矩阵部分填充 NaN 和 inf 值。 How can I work with floating point numbers in python?我如何在 python 中使用浮点数?

Edit: Minimal Reproducible Example:编辑:最小可重现示例:

M = np.random.randn(2, 2)
M = np.dot(M, M.transpose())
# produces for example [[0.68283219, -0.33497034], [-0.33497034, 0.72113541]]
run_cholesky(M)

Saving M[i, k] in a variable and then subtracting instead of summing up is fixing the problem:将 M[i, k] 保存在一个变量中然后减去而不是求和可以解决问题:

for i in range(n):
    for k in range(i + 1):
        val = M[i, k]
        for j in range(k):
            val -= L[i, j] * L[k, j]
        if i == k:
            if val < 0:
                raise ValueError("Matrix is non-positive definite")
            L[i, k] = np.sqrt(val)
        else:
            if np.isclose(L[k, k], 0):
                raise ValueError("Matrix is non-positive definite")
            L[i, k] = val / L[k, k]

Declare the matrix like this, and go from there:像这样声明矩阵,然后从那里开始:

M = np.zeros((n, n), dtype=float) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM