使用Python而不使用scipy.linalg.det求解行列式的代码

使用Python而不使用scipy.linalg.det求解行列式的代码,python,matrix,numerical,determinants,Python,Matrix,Numerical,Determinants,说明(这是一个hwk问题): 我不知道从哪里开始。我计划使用拉普拉斯的扩展,但我不知道如何实现它的nxn矩阵。任何帮助都将不胜感激 注意:我已经有一个函数为nxn矩阵生成随机矩阵。计算的时间也不是问题。我唯一的问题是如何计算行列式 必须删除我的班级政策的问题描述b/c 好的,这里有个提示 编写一个函数来计算次要矩阵。(提示,使用切片) 编写一个函数来计算辅因子(这应该调用第一个函数和确定函数) determinate函数调用步骤2中的函数并将结果相加。(提示:使用sum) 维奥拉,你有一个决定因

说明(这是一个hwk问题):

我不知道从哪里开始。我计划使用拉普拉斯的扩展,但我不知道如何实现它的nxn矩阵。任何帮助都将不胜感激

注意:我已经有一个函数为nxn矩阵生成随机矩阵。计算的时间也不是问题。我唯一的问题是如何计算行列式

必须删除我的班级政策的问题描述b/c

好的,这里有个提示

  • 编写一个函数来计算次要矩阵。(提示,使用切片)
  • 编写一个函数来计算辅因子(这应该调用第一个函数和确定函数)
  • determinate函数调用步骤2中的函数并将结果相加。(提示:使用
    sum
  • 维奥拉,你有一个决定因素

    另外,不要忘记,由于我们在python中编写列表的方式,索引是反向的。如果

    M = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]]
    

    那么m0,1是2,而不是4,因为它将是在正常的记数法。您可以将其视为转置或使用
    zip

    这里是用于查找矩阵行列式的adjucate方法的递归python代码

    def getMatrixMinor(m,i,j):
        return [row[:j] + row[j+1:] for row in (m[:i]+m[i+1:])]
    
    def getMatrixDeternminant(m):
        #base case for 2x2 matrix
        if len(m) == 2:
            return m[0][0]*m[1][1]-m[0][1]*m[1][0]
    
        determinant = 0
        for c in range(len(m)):
            determinant += ((-1)**c)*m[0][c]*getMatrixDeternminant(getMatrixMinor(m,0,c))
        return determinant
    

    请注意,输入是表示nxn矩阵的数组

    对于大型矩阵,不建议使用拉普拉斯方法进行行列式计算,因为它在计算上非常昂贵(递归函数)。相反,更好的方法是使用高斯消去法将原始矩阵转换为上三角矩阵。下三角矩阵或上三角矩阵的行列式只是对角线元素的乘积

    def minor(array,i,j):
        c = array
        c = c[:i] + c[i+1:]
        for k in range(0,len(c)):
            c[k] = c[k][:j]+c[k][j+1:]
        return c
    def det(array,n):
        if n == 1 :return array[0][0]
        if n == 2 :return array[0][0]*array[1][1] - array[0][1]*array[1][0]
        sum = 0
        for i in range(0,n):
            m = minor(array,0,i)
            sum =sum + ((-1)**i)*array[0][i] * det(m,n-1)
        return sum
    
    这里我们展示一个例子

    import numpy as np
    from scipy import linalg
    
    def determinant(a):
        assert len(a.shape) == 2 # check if a is a two diamentional matrix
        assert a.shape[0] == a.shape[1] # check if matrix is square
        n = a.shape[0]
       
        for k in range(0, n-1):
           
            for i in range(k+1, n):
                if a[i,k] != 0.0:
                    lam = a [i,k]/a[k,k]
                    a[i,k:n] = a[i,k:n] - lam*a[k,k:n]
    
                   
        # the matrix (a) is now in the upper triangular form
                    
        return np.prod(np.diag(a))
    
    matrix = np.random.rand(50, 50)
    
    
    print(linalg.det(matrix))
    print(determinant(matrix))
    
    结果与从Scipy行列式得到的结果相似

    -3032.573716363944

    -3032.573716915967

    但是,该函数仍然可以公式化为包含旋转。此外,通过使用numba library,它可以达到与scipy类似的效率。

    我已经将其作为基本思想,并希望与我的实现共享

    import numpy as np
    import time
    
    def minor(arr,i,j):
        c = arr[:]
        c = np.delete(c, (i),axis=0)
        return [np.delete(row, (j),axis=0) for row in (c)]
        
    
    def det(arr):
        n = len(arr)
        if n == 1 :return arr[0][0]
        if n == 2 :return arr[0][0]*arr[1][1] - arr[0][1]*arr[1][0]
        sum = 0
        for i in range(0,n):
            m = minor(arr,0,i)
            sum =sum + ((-1)**i)*arr[0][i] * det(m)
        return sum
    
    matrix = np.random.randint(-5, 5, size=(10, 10)) # martix nxn with integer values in interval [-5, 5)
    
    print(matrix)
    start_time = time.time()
    print("started:", start_time)
    det(matrix)
    end_time = time.time()
    print("finished:", end_time)
    print("--- %s seconds ---" % (end_time - start_time))
    

    由于在我的笔记本电脑上计算矩阵10*10的结果行列式大约需要1分钟,我知道我的代码不是最优的,但这一实现的主要原因(可能是我丢失了一些东西)我只需要根据看起来非常漂亮的解决方案获得工作代码。

    这不是真正的编程问题。也许,如果您提供一些代码,那么有人可以帮助您更正它。你试过什么?哦,是的,我需要一个策略,如何将其转化为代码。伙计,我认为你真的需要应用你自己。这听起来像是给我代码。如果你在我的提示中遇到任何问题,用你的代码更新问题,有人会很乐意帮助你。@aaa carp别这么轻易就这么想,伙计。那么索引是先计算列,然后计算行吗?@shagster不,先计算行,然后计算列。看看代码并思考一下。(至少对我来说,通常的表示方式是列、行。“先下大厅,然后上电梯”)这确实是一个没有实际意义的问题,因为D(a^t)=D(a)你不认为应该对代码进行一些解释吗?对于整数,这似乎经常出现零除错误。从好的方面来说,它速度很快,而且显然返回了一个精确的值result@anon01更新以处理零除错误这会给出不正确的结果。例如:
    matrix=np.array([[4,4,8],[2,2,8],[2,0,5]])
    @anon01谢谢。我恢复到原来的形式。旋转可能不适用于行列式。