【问题标题】:Estimating determinant using LAPACK wrapper for LU decomposition in Cython在 Cython 中使用 LAPACK 包装器估计行列式进行 LU 分解
【发布时间】:2018-05-11 13:26:36
【问题描述】:

我在这里定义了计算矩阵行列式的函数。但有时我会得到错误的信号。我从this answer 建模了我的函数。

from scipy.linalg.cython_lapack cimport dgetrf

cpdef double det_c(double[:, ::1] A, double[:, ::1] work, double[::1] ipiv):
    '''obtain determinant of float type square matrix A

    Notes
    -----
    As is, this function is not yet computing the sign of the determinant
    correctly, help!

    Parameters
    ----------
    A : memoryview (numpy array)
        n x n array to compute determinant of
    work : memoryview (numpy array)
        n x n array to use within function
    ipiv : memoryview (numpy array)
        length n vector use within function

    Returns
    -------
    detval : float
        determinant of matrix A
    '''

    cdef int n = A.shape[0], info
    work[...] = A

    dgetrf(&n, &n, &work[0,0], &n, &ipiv[0], &info)

    cdef double detval = 1.
    cdef int j

    for j in range(n):
        if j != ipiv[j]:
            detval = -detval*work[j, j]
        else:
            detval = detval*work[j, j]

    return detval

当我测试这个函数并将其与np.linalg.det 进行比较时,有时我得到了错误的符号。

>>> a = np.array([[1,2],[3,5.]])
>>> np.linalg.det(a)
>>> -1.0000000000000004
>>> det_c(a, np.zeros((2, 2)), np.zeros(2, dtype=np.int32))
>>> 1

其他时候,正确的标志。

>>> b = np.array([[1,2,3],[1,2,1],[5,6,1.]])
>>> np.linalg.det(b)
>>> -7.999999999999998
>>> det_c(a, np.zeros((3, 3)), np.zeros(3, dtype=np.int32))
>>> -8.0

【问题讨论】:

    标签: python numpy scipy cython lapack


    【解决方案1】:

    dgetrf 是 Fortran 子例程,Fortran 使用从 1 开始的索引,因此 ipiv 中的值介于 1 和 n(含)之间。为了解决这个问题,请将循环中的测试从

            if j != ipiv[j]:
    

            if j != ipiv[j] - 1:
    

    【讨论】:

      猜你喜欢
      • 2018-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多