C# 尝试反转hessian矩阵时系统引发异常

C# 尝试反转hessian矩阵时系统引发异常,c#,matrix-inverse,hessian-matrix,C#,Matrix Inverse,Hessian Matrix,我正在尝试一些来自jamesmccaffrey web的关于逆矩阵()的代码。我使用了反转n x n hessian矩阵,但在“static double[][]MatrixDecompose()”方法中出现了异常:无法使用Doolittle的方法。以下是我使用的代码: static double[][] MatrixCreate(int rows, int cols){ double[][] result = new double[rows][]; for (int i

我正在尝试一些来自jamesmccaffrey web的关于逆矩阵()的代码。我使用了反转n x n hessian矩阵,但在“static double[][]MatrixDecompose()”方法中出现了异常:
无法使用Doolittle的方法。
以下是我使用的代码:

static double[][] MatrixCreate(int rows, int cols){

     double[][] result = new double[rows][];

     for (int i = 0; i < rows; ++i)
     {
     result[i] = new double[cols];
     }
     return result;
}

static double[][] MatrixRandom(int rows, int cols, double[,] hesian){

     double[][] result = MatrixCreate(rows, cols);
     double temp;
     for (int i = 0; i < rows; i++)
     {
          temp = 0;
          for (int j = 0; j < cols; j++)
          {
              temp = hesian[i, j];
              result[i][j] = temp;
          }
     }
     return result;
}

static double[][] MatrixDecompose(double[][] matrix, out int[] perm, out int toggle){

     // Doolittle LUP decomposition with partial pivoting.
     // rerturns: result is L (with 1s on diagonal) and U;
     // perm holds row permutations; toggle is +1 or -1 (even or odd)

     int rows = matrix.Length;
     int cols = matrix[0].Length; // assume square

     if (rows != cols)
     {
          throw new Exception("Attempt to decompose a non-square m");
     }

     int n = rows; // convenience

     double[][] result = MatrixDuplicate(matrix);

     perm = new int[n]; // set up row permutation result
     for (int i = 0; i < n; ++i) 
     { 
          perm[i] = i; 
     }

            toggle = 1; // toggle tracks row swaps.
            // +1 -greater-than even, -1 -greater-than odd. used by MatrixDeterminant

            for (int j = 0; j < n - 1; ++j) // each column
            {
                double colMax = Math.Abs(result[j][j]); // find largest val in col
                int pRow = j;
                //for (int i = j + 1; i less-than n; ++i)
                //{
                //  if (result[i][j] greater-than colMax)
                //  {
                //    colMax = result[i][j];
                //    pRow = i;
                //  }
                //}

                // reader Matt V needed this:
                for (int i = j + 1; i < n; ++i)
                {
                    if (Math.Abs(result[i][j]) > colMax)
                    {                       
                        colMax = Math.Abs(result[i][j]);
                        pRow = i;
                    }
                }
                // Not sure if this approach is needed always, or not.

                if (pRow != j) // if largest value not on pivot, swap rows
                {
                    double[] rowPtr = result[pRow];
                    result[pRow] = result[j];
                    result[j] = rowPtr;

                    int tmp = perm[pRow]; // and swap perm info
                    perm[pRow] = perm[j];
                    perm[j] = tmp;

                    toggle = -toggle; // adjust the row-swap toggle
                }

                // --------------------------------------------------
                // This part added later (not in original)
                // and replaces the 'return null' below.
                // if there is a 0 on the diagonal, find a good row
                // from i = j+1 down that doesn't have
                // a 0 in column j, and swap that good row with row j
                // --------------------------------------------------

                if (result[j][j] == 0.0)
                {
                    // find a good row to swap
                    int goodRow = -1;
                    for (int row = j + 1; row < n; ++row)
                    {
                        if (result[row][j] != 0.0)
                            goodRow = row;
                    }                    
                    if (goodRow == -1)
                        throw new Exception("Cannot use Doolittle's method");

                    // swap rows so 0.0 no longer on diagonal
                    double[] rowPtr = result[goodRow];
                    result[goodRow] = result[j];
                    result[j] = rowPtr;

                    int tmp = perm[goodRow]; // and swap perm info
                    perm[goodRow] = perm[j];
                    perm[j] = tmp;

                    toggle = -toggle; // adjust the row-swap toggle
                }
                // --------------------------------------------------
                // if diagonal after swap is zero . .
                //if (Math.Abs(result[j][j]) less-than 1.0E-20) 
                //  return null; // consider a throw

                for (int i = j + 1; i < n; ++i)
                {
                    result[i][j] /= result[j][j];
                    for (int k = j + 1; k < n; ++k)
                    {
                        result[i][k] -= result[i][j] * result[j][k];
                    }
                }


            } // main j column loop

            return result;
        } // MatrixDecompose

static double[][] MatrixInverse(double[][] matrix){

        int n = matrix.Length;
        double[][] result = MatrixDuplicate(matrix);

        int[] perm;
        int toggle;
        double[][] lum = MatrixDecompose(matrix, out perm,
          out toggle);
        if (lum == null)
            throw new Exception("Unable to compute inverse");

        double[] b = new double[n];
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                if (i == perm[j])
                    b[j] = 1.0;
                else
                    b[j] = 0.0;
            }

            double[] x = HelperSolve(lum, b); // 

            for (int j = 0; j < n; ++j)
                result[j][i] = x[j];
        }
        return result;
    }

static double MatrixDeterminant(double[][] matrix)
{

    int[] perm;
    int toggle;
    double[][] lum = MatrixDecompose(matrix, out perm, out toggle);
    if (lum == null)
    {
        throw new Exception("Unable to compute MatrixDeterminant");
    }
        double result = toggle;
        for (int i = 0; i < lum.Length; ++i)
    {
            result *= lum[i][i];
    }
        return result;
    }

static double[][] MatrixDuplicate(double[][] matrix)
{

        // allocates/creates a duplicate of a matrix.
        double[][] result = MatrixCreate(matrix.Length, matrix[0].Length);
        for (int i = 0; i < matrix.Length; ++i)
        { // copy the values
            for (int j = 0; j < matrix[i].Length; ++j)
            {
                result[i][j] = matrix[i][j];
            }
        {
        return result;
    }
static double[]MatrixCreate(int行,int列){
双精度[]结果=新的双精度[行][];
对于(int i=0;icolMax)
{                       
colMax=Math.Abs(结果[i][j]);
船头=i;
}
}
//不确定是否始终需要这种方法。
if(pRow!=j)//如果最大值不在轴上,则交换行
{
double[]rowPtr=结果[pRow];
结果[pRow]=结果[j];
结果[j]=rowPtr;
int tmp=perm[pRow];//并交换perm信息
perm[pRow]=perm[j];
perm[j]=tmp;
toggle=-toggle;//调整行交换切换
}
// --------------------------------------------------
//本部分后来添加(不是原件)
//并替换下面的“返回空值”。
//如果对角线上有一个0,找到一个好的行
//从i=j+1开始,没有
//在第j列中输入0,并将该良好行与第j行交换
// --------------------------------------------------
如果(结果[j][j]==0.0)
{
//找到一个好的行进行交换
int goodRow=-1;
对于(int行=j+1;行