Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何求大矩阵的行列式 我发现了一些用于寻找矩阵行列式的C++代码,用于4x4到8x8。它工作正常,但我的项目需要18x18或更大的矩阵,而且代码太慢。代码是递归的,但是递归是处理18x18矩阵的正确概念吗?否则我怎么才能找到行列式呢?_C++_Matrix - Fatal编程技术网

如何求大矩阵的行列式 我发现了一些用于寻找矩阵行列式的C++代码,用于4x4到8x8。它工作正常,但我的项目需要18x18或更大的矩阵,而且代码太慢。代码是递归的,但是递归是处理18x18矩阵的正确概念吗?否则我怎么才能找到行列式呢?

如何求大矩阵的行列式 我发现了一些用于寻找矩阵行列式的C++代码,用于4x4到8x8。它工作正常,但我的项目需要18x18或更大的矩阵,而且代码太慢。代码是递归的,但是递归是处理18x18矩阵的正确概念吗?否则我怎么才能找到行列式呢?,c++,matrix,C++,Matrix,我假设你使用的是简单的扩展方法。如果您想提高速度,您可以使用(分解为两个上下对角矩阵)分解矩阵M,这可以通过2*n^3/3次触发器中的修正高斯-乔丹消去法来实现,然后计算行列式,如下所示: det(M)=det(L)*det(U),对于三角矩阵,它只是其对角线中条目的乘积 这个过程仍然比O(n!)快 编辑:您也可以使用,这是一种广泛使用的方法。好吧,在这个领域工作的人并不认为18x18是一个大矩阵,您选择的几乎任何技术在任何现代计算机上都应该足够快。我们中的许多人也不会用递归算法来解决矩阵问题,

我假设你使用的是简单的扩展方法。如果您想提高速度,您可以使用(分解为两个上下对角矩阵)分解矩阵
M
,这可以通过
2*n^3/3次触发器中的修正高斯-乔丹消去法来实现,然后计算行列式,如下所示:

det(M)=det(L)*det(U)
,对于三角矩阵,它只是其对角线中条目的乘积

这个过程仍然比
O(n!)


编辑:您也可以使用,这是一种广泛使用的方法。

好吧,在这个领域工作的人并不认为18x18是一个大矩阵,您选择的几乎任何技术在任何现代计算机上都应该足够快。我们中的许多人也不会用递归算法来解决矩阵问题,更可能使用迭代算法——但这可能反映了一个事实,即许多研究矩阵问题的人都是科学家和工程师,而不是计算机科学家


我建议你看C++中的数字配方。不一定是你能找到的最好的代码,但它是一个学习和学习的文本。对于更好的代码,BOOST有很好的声誉,而且总是有BLAS和类似Intel数学内核库或AMD核心数学库的东西。我认为所有这些都有行列式查找例程的实现,这些例程将非常快速地处理18x18矩阵。

由于我无法评论,我希望添加以下内容:Cholesky分解(或其变体,LDLT,L a单位下三角矩阵和D a对角矩阵)可用于验证对称矩阵是否为正定/负定:如果为正定,则D的元素均为正定,且Cholesky分解将成功完成,而无需求负数的平方根。如果矩阵是负定的,D的元素都是负的,那么矩阵本身就不会有Cholesky分解,但它的负元素会有


计算三角形矩阵的行列式很简单:将对角元素相乘,因为非对角项的余因子为0。使用LU分解进一步简化了这一点,因为在大多数实现中,L是一个单位,下三角矩阵,即其对角线元素都是1。因此,你通常只需要计算U的行列式。”

  • 这里您忘了考虑高斯消去法的所有实际实现都使用(部分)旋转以获得额外的数值稳定性;因此您的描述是不完整的;计算分解阶段进行的行交换的数量,将U的所有对角元素相乘后,如果交换的数量为奇数,则此乘积应为负值

至于代码,NR不是免费的;我建议看一下LAPACK/CLAPACK/LAPACK++@作为参考,我只能告诉你“矩阵计算”“Golub和Van Loan写的。

我想这可能行得通。我是在学习数值分析课程时写的。这不仅是行列式,还有其他与矩阵有关的函数

首先,将此代码复制并保存为
Matrix.h

//Title: Matrix Header File
//Writer: Say OL
//This is a beginner code not an expert one
//No responsibilty for any errors
//Use for your own risk

using namespace std;
int row,col,Row,Col;
double Coefficient;

//Input Matrix
void Input(double Matrix[9][9],int Row,int Col)
{
    for(row=1;row<=Row;row++)
        for(col=1;col<=Col;col++)
        {
            cout<<"e["<<row<<"]["<<col<<"]=";
            cin>>Matrix[row][col];
        }
}

//Output Matrix
void Output(double Matrix[9][9],int Row,int Col)
{
    for(row=1;row<=Row;row++)
    {
        for(col=1;col<=Col;col++)
            cout<<Matrix[row][col]<<"\t";
        cout<<endl;
    }
}

//Copy Pointer to Matrix
void CopyPointer(double (*Pointer)[9],double Matrix[9][9],int Row,int Col)
{
    for(row=1;row<=Row;row++)
        for(col=1;col<=Col;col++)
            Matrix[row][col]=Pointer[row][col];
}

//Copy Matrix to Matrix
void CopyMatrix(double MatrixInput[9][9],double MatrixTarget[9][9],int Row,int Col)
{
    for(row=1;row<=Row;row++)
        for(col=1;col<=Col;col++)
            MatrixTarget[row][col]=MatrixInput[row][col];
}

//Transpose of Matrix
double MatrixTran[9][9];
double (*(Transpose)(double MatrixInput[9][9],int Row,int Col))[9]
{
    for(row=1;row<=Row;row++)
        for(col=1;col<=Col;col++)
            MatrixTran[col][row]=MatrixInput[row][col];
    return MatrixTran;
}

//Matrix Addition
double MatrixAdd[9][9];
double (*(Addition)(double MatrixA[9][9],double MatrixB[9][9],int Row,int Col))[9]
{
    for(row=1;row<=Row;row++)
        for(col=1;col<=Col;col++)
            MatrixAdd[row][col]=MatrixA[row][col]+MatrixB[row][col];
    return MatrixAdd;
}

//Matrix Subtraction
double MatrixSub[9][9];
double (*(Subtraction)(double MatrixA[9][9],double MatrixB[9][9],int Row,int Col))[9]
{
    for(row=1;row<=Row;row++)
        for(col=1;col<=Col;col++)
            MatrixSub[row][col]=MatrixA[row][col]-MatrixB[row][col];
    return MatrixSub;
}

//Matrix Multiplication
int mRow,nCol,pCol,kcol;
double MatrixMult[9][9];
double (*(Multiplication)(double MatrixA[9][9],double MatrixB[9][9],int mRow,int nCol,int pCol))[9]
{
    for(row=1;row<=mRow;row++)
        for(col=1;col<=pCol;col++)
        {
            MatrixMult[row][col]=0.0;
            for(kcol=1;kcol<=nCol;kcol++)
                MatrixMult[row][col]+=MatrixA[row][kcol]*MatrixB[kcol][col];
        }
    return MatrixMult;
}

//Interchange Two Rows
double RowTemp[9][9];
double MatrixInter[9][9];
double (*(InterchangeRow)(double MatrixInput[9][9],int Row,int Col,int iRow,int jRow))[9]
{
    CopyMatrix(MatrixInput,MatrixInter,Row,Col);
    for(col=1;col<=Col;col++)
    {
        RowTemp[iRow][col]=MatrixInter[iRow][col];
        MatrixInter[iRow][col]=MatrixInter[jRow][col];
        MatrixInter[jRow][col]=RowTemp[iRow][col];
    }
    return MatrixInter;
}

//Pivote Downward
double MatrixDown[9][9];
double (*(PivoteDown)(double MatrixInput[9][9],int Row,int Col,int tRow,int tCol))[9]
{
    CopyMatrix(MatrixInput,MatrixDown,Row,Col);
    Coefficient=MatrixDown[tRow][tCol];
    if(Coefficient!=1.0)
        for(col=1;col<=Col;col++)
            MatrixDown[tRow][col]/=Coefficient;
    if(tRow<Row)
        for(row=tRow+1;row<=Row;row++)
        {
            Coefficient=MatrixDown[row][tCol];
            for(col=1;col<=Col;col++)
                MatrixDown[row][col]-=Coefficient*MatrixDown[tRow][col];
        }
return MatrixDown;
}

//Pivote Upward
double MatrixUp[9][9];
double (*(PivoteUp)(double MatrixInput[9][9],int Row,int Col,int tRow,int tCol))[9]
{
    CopyMatrix(MatrixInput,MatrixUp,Row,Col);
    Coefficient=MatrixUp[tRow][tCol];
    if(Coefficient!=1.0)
        for(col=1;col<=Col;col++)
            MatrixUp[tRow][col]/=Coefficient;
    if(tRow>1)
        for(row=tRow-1;row>=1;row--)
        {
            Coefficient=MatrixUp[row][tCol];
            for(col=1;col<=Col;col++)
                MatrixUp[row][col]-=Coefficient*MatrixUp[tRow][col];
        }
    return MatrixUp;
}

//Pivote in Determinant
double MatrixPiv[9][9];
double (*(Pivote)(double MatrixInput[9][9],int Dim,int pTarget))[9]
{
    CopyMatrix(MatrixInput,MatrixPiv,Dim,Dim);
    for(row=pTarget+1;row<=Dim;row++)
    {
        Coefficient=MatrixPiv[row][pTarget]/MatrixPiv[pTarget][pTarget];
        for(col=1;col<=Dim;col++)
        {
            MatrixPiv[row][col]-=Coefficient*MatrixPiv[pTarget][col];
        }
    }
    return MatrixPiv;
}

//Determinant of Square Matrix
int dCounter,dRow;
double Det;
double MatrixDet[9][9];
double Determinant(double MatrixInput[9][9],int Dim)
{
    CopyMatrix(MatrixInput,MatrixDet,Dim,Dim);
    Det=1.0;
    if(Dim>1)
    {
        for(dRow=1;dRow<Dim;dRow++)
        {
            dCounter=dRow;
            while((MatrixDet[dRow][dRow]==0.0)&(dCounter<=Dim))
            {
                dCounter++;
                Det*=-1.0;
                CopyPointer(InterchangeRow(MatrixDet,Dim,Dim,dRow,dCounter),MatrixDet,Dim,Dim);
            }
            if(MatrixDet[dRow][dRow]==0)
            {
                Det=0.0;
                break;
            }
            else
            {
                Det*=MatrixDet[dRow][dRow];
                CopyPointer(Pivote(MatrixDet,Dim,dRow),MatrixDet,Dim,Dim);
            }
        }
        Det*=MatrixDet[Dim][Dim];
    }
    else Det=MatrixDet[1][1];
    return Det;
}

//Matrix Identity
double MatrixIdent[9][9];
double (*(Identity)(int Dim))[9]
{
    for(row=1;row<=Dim;row++)
        for(col=1;col<=Dim;col++)
            if(row==col)
                MatrixIdent[row][col]=1.0;
            else
                MatrixIdent[row][col]=0.0;
    return MatrixIdent;
}
//Join Matrix to be Augmented Matrix
double MatrixJoin[9][9];
double (*(JoinMatrix)(double MatrixA[9][9],double MatrixB[9][9],int Row,int ColA,int ColB))[9]
{
    Col=ColA+ColB;
    for(row=1;row<=Row;row++)
        for(col=1;col<=Col;col++)
            if(col<=ColA)
                MatrixJoin[row][col]=MatrixA[row][col];
            else
                MatrixJoin[row][col]=MatrixB[row][col-ColA];
    return MatrixJoin;
}

//Inverse of Matrix
double (*Pointer)[9];
double IdentMatrix[9][9];
int Counter;
double MatrixAug[9][9];
double MatrixInv[9][9];
double (*(Inverse)(double MatrixInput[9][9],int Dim))[9]
{
    Row=Dim;
    Col=Dim+Dim;
    Pointer=Identity(Dim);
    CopyPointer(Pointer,IdentMatrix,Dim,Dim);
    Pointer=JoinMatrix(MatrixInput,IdentMatrix,Dim,Dim,Dim);
    CopyPointer(Pointer,MatrixAug,Row,Col);
    for(Counter=1;Counter<=Dim;Counter++)   
    {
        Pointer=PivoteDown(MatrixAug,Row,Col,Counter,Counter);
        CopyPointer(Pointer,MatrixAug,Row,Col);
    }
    for(Counter=Dim;Counter>1;Counter--)
    {
        Pointer=PivoteUp(MatrixAug,Row,Col,Counter,Counter);
        CopyPointer(Pointer,MatrixAug,Row,Col);
    }
    for(row=1;row<=Dim;row++)
        for(col=1;col<=Dim;col++)
            MatrixInv[row][col]=MatrixAug[row][col+Dim];
    return MatrixInv;
}

//Gauss-Jordan Elemination
double MatrixGJ[9][9];
double VectorGJ[9][9];
double (*(GaussJordan)(double MatrixInput[9][9],double VectorInput[9][9],int Dim))[9]
{
    Row=Dim;
    Col=Dim+1;
    Pointer=JoinMatrix(MatrixInput,VectorInput,Dim,Dim,1);
    CopyPointer(Pointer,MatrixGJ,Row,Col);
    for(Counter=1;Counter<=Dim;Counter++)   
    {
        Pointer=PivoteDown(MatrixGJ,Row,Col,Counter,Counter);
        CopyPointer(Pointer,MatrixGJ,Row,Col);
    }
    for(Counter=Dim;Counter>1;Counter--)
    {
        Pointer=PivoteUp(MatrixGJ,Row,Col,Counter,Counter);
        CopyPointer(Pointer,MatrixGJ,Row,Col);
    }
    for(row=1;row<=Dim;row++)
        for(col=1;col<=1;col++)
            VectorGJ[row][col]=MatrixGJ[row][col+Dim];
    return VectorGJ;
}

//Generalized Gauss-Jordan Elemination
double MatrixGGJ[9][9];
double VectorGGJ[9][9];
double (*(GeneralizedGaussJordan)(double MatrixInput[9][9],double VectorInput[9][9],int Dim,int vCol))[9]
{
    Row=Dim;
    Col=Dim+vCol;
    Pointer=JoinMatrix(MatrixInput,VectorInput,Dim,Dim,vCol);
    CopyPointer(Pointer,MatrixGGJ,Row,Col);
    for(Counter=1;Counter<=Dim;Counter++)   
    {
        Pointer=PivoteDown(MatrixGGJ,Row,Col,Counter,Counter);
        CopyPointer(Pointer,MatrixGGJ,Row,Col);
    }
    for(Counter=Dim;Counter>1;Counter--)
    {
        Pointer=PivoteUp(MatrixGGJ,Row,Col,Counter,Counter);
        CopyPointer(Pointer,MatrixGGJ,Row,Col);
    }
    for(row=1;row<=Row;row++)
        for(col=1;col<=vCol;col++)
            VectorGGJ[row][col]=MatrixGGJ[row][col+Dim];
    return VectorGGJ;
}

//Matrix Sparse, Three Diagonal Non-Zero Elements
double MatrixSpa[9][9];
double (*(Sparse)(int Dimension,double FirstElement,double SecondElement,double ThirdElement))[9]
{
    MatrixSpa[1][1]=SecondElement;
    MatrixSpa[1][2]=ThirdElement;
    MatrixSpa[Dimension][Dimension-1]=FirstElement;
    MatrixSpa[Dimension][Dimension]=SecondElement;
    for(int Counter=2;Counter<Dimension;Counter++)
    {
        MatrixSpa[Counter][Counter-1]=FirstElement;
        MatrixSpa[Counter][Counter]=SecondElement;
        MatrixSpa[Counter][Counter+1]=ThirdElement;
    }
    return MatrixSpa;
}
//标题:矩阵头文件
//作家:说吧
//这是一个初学者代码,不是专家代码
//对任何错误概不负责
//风险自负
使用名称空间std;
int row,col,row,col;
双系数;
//输入矩阵
无效输入(双矩阵[9][9],整数行,整数列)
{

对于(row=1;row函数det_recursive适用于任何大小的方阵。然而,由于它使用的是扩展拉普拉斯公式的递归朴素方法,因此对于大尺寸的方阵来说速度非常慢

另一种方法是利用高斯消去法将矩阵变换成上三角形式,然后矩阵的行列式就是原矩阵三角变换形式的对角元素的乘积

基本上numpy是最快的,但在内部它使用了某种线性矩阵变换方法,类似于高斯消去法。但是,我不确定它到底是什么

In[1]
import numpy as np

In[2]
mat = np.random.rand(9,9)
print("numpy asnwer = ", np.linalg.det(mat))

Out[2] 
numpy asnwer =  0.016770106020608373

In[3]
def det_recursive(A):
    if A.shape[0] != A.shape[1]:
        raise ValueError('matrix {} is not Square'.format(A))

    sol = 0
    if A.shape != (1,1):
        for i in range(A.shape[0]):
            sol = sol +  (-1)**i * A[i, 0] * det_recursive(np.delete(np.delete(A, 0, axis= 1), i, axis= 0))
        return sol
    else:
        return A[0,0]
​

In[4]
print("recursive asnwer = ", det_recursive(mat))

Out[4]
recursive asnwer =  0.016770106020608397

In[5]
def det_gauss_elimination(a,tol=1.0e-9):
    """
    calculate determinant using gauss-elimination method
    """
    a = np.copy(a)

    assert(a.shape[0] == a.shape[1])
    n = a.shape[0]

    # Set up scale factors
    s = np.zeros(n)

    mult = 0
    for i in range(n):
        s[i] = max(np.abs(a[i,:])) # find the max of each row
    for k in range(0, n-1): #pivot row
        # Row interchange, if needed
        p = np.argmax(np.abs(a[k:n,k])/s[k:n]) + k 
        if abs(a[p,k]) < tol: 
            print("Matrix is singular")
            return 0
        if p != k: 
            a[[k,p],:] = a[[p, k],:] 
            s[k],s[p] = s[p],s[k]
            mult = mult + 1
​
        # convert a to upper triangular matrix
        for i in range(k+1,n):
            if a[i,k] != 0.0: # skip if a(i,k) is already zero
                lam = a [i,k]/a[k,k] 
                a[i,k:n] = a[i,k:n] - lam*a[k,k:n]
​
    deter = np.prod(np.diag(a))* (-1)**mult   
    return deter

In[6] 
print("gauss elimination asnwer = ", det_gauss_elimination(mat))

Out[6] 
gauss elimination asnwer =  0.016770106020608383

In[7] 
print("numpy time")
%timeit -n3 -r3 np.linalg.det(mat)
print("\nrecursion time")
%timeit -n3 -r3 det_recursive(mat)
print("\ngauss_elimination time")
%timeit -n3 -r3 det_gauss_elimination(mat)

Out[7]
numpy time
40.8 µs ± 17.2 µs per loop (mean ± std. dev. of 3 runs, 3 loops each)

recursion time
10.1 s ± 128 ms per loop (mean ± std. dev. of 3 runs, 3 loops each)

gauss_elimination time
472 µs ± 106 µs per loop (mean ± std. dev. of 3 runs, 3 loops each)
[1]中的

将numpy作为np导入
在[2]
mat=np.rand.rand(9,9)
打印(“numpy asnwer=”,np.linalg.det(mat))
输出[2]
numpy asnwer=0.0167701062068373
在[3]
def det_递归(A):
如果A.shape[0]!=A.shape[1]:
raise VALUERROR('矩阵{}不是正方形'。格式(A))
溶胶=0
如果A.shape!=(1,1):
对于范围内的i(A.shape[0]):
sol=sol+(-1)**i*A[i,0]*det_递归(np.delete(np.delete)(A,0,轴=1,i,轴=0))
返回溶胶
其他:
返回[0,0]
​
在[4]
打印(“递归asnwer=,det_递归(mat))
输出[4]
递归asnwer=0.0167701062068397
在[5]
def det_gauss_消元法(a,tol=1.0e-9):
"""
用高斯消去法计算行列式
"""
a=np.副本(a)
断言(a.shape[0]==a.shape[1])
n=a.形状[0]
#设置比例因子
s=np.零(n)
mult=0
对于范围(n)中的i:
s[i]=max(np.abs(a[i,:])#求每行的max
对于范围(0,n-1)中的k:#枢轴行
#行交换,如果需要
p=np.argmax(np.abs(a[k:n,k])/s[k:n])+k
如果abs(a[p,k])In[1]
import numpy as np

In[2]
mat = np.random.rand(9,9)
print("numpy asnwer = ", np.linalg.det(mat))

Out[2] 
numpy asnwer =  0.016770106020608373

In[3]
def det_recursive(A):
    if A.shape[0] != A.shape[1]:
        raise ValueError('matrix {} is not Square'.format(A))

    sol = 0
    if A.shape != (1,1):
        for i in range(A.shape[0]):
            sol = sol +  (-1)**i * A[i, 0] * det_recursive(np.delete(np.delete(A, 0, axis= 1), i, axis= 0))
        return sol
    else:
        return A[0,0]
​

In[4]
print("recursive asnwer = ", det_recursive(mat))

Out[4]
recursive asnwer =  0.016770106020608397

In[5]
def det_gauss_elimination(a,tol=1.0e-9):
    """
    calculate determinant using gauss-elimination method
    """
    a = np.copy(a)

    assert(a.shape[0] == a.shape[1])
    n = a.shape[0]

    # Set up scale factors
    s = np.zeros(n)

    mult = 0
    for i in range(n):
        s[i] = max(np.abs(a[i,:])) # find the max of each row
    for k in range(0, n-1): #pivot row
        # Row interchange, if needed
        p = np.argmax(np.abs(a[k:n,k])/s[k:n]) + k 
        if abs(a[p,k]) < tol: 
            print("Matrix is singular")
            return 0
        if p != k: 
            a[[k,p],:] = a[[p, k],:] 
            s[k],s[p] = s[p],s[k]
            mult = mult + 1
​
        # convert a to upper triangular matrix
        for i in range(k+1,n):
            if a[i,k] != 0.0: # skip if a(i,k) is already zero
                lam = a [i,k]/a[k,k] 
                a[i,k:n] = a[i,k:n] - lam*a[k,k:n]
​
    deter = np.prod(np.diag(a))* (-1)**mult   
    return deter

In[6] 
print("gauss elimination asnwer = ", det_gauss_elimination(mat))

Out[6] 
gauss elimination asnwer =  0.016770106020608383

In[7] 
print("numpy time")
%timeit -n3 -r3 np.linalg.det(mat)
print("\nrecursion time")
%timeit -n3 -r3 det_recursive(mat)
print("\ngauss_elimination time")
%timeit -n3 -r3 det_gauss_elimination(mat)

Out[7]
numpy time
40.8 µs ± 17.2 µs per loop (mean ± std. dev. of 3 runs, 3 loops each)

recursion time
10.1 s ± 128 ms per loop (mean ± std. dev. of 3 runs, 3 loops each)

gauss_elimination time
472 µs ± 106 µs per loop (mean ± std. dev. of 3 runs, 3 loops each)