Beispiel #1
0
        /// <summary>
        /// 行列の逆行列計算メソッド
        /// </summary>
        /// <param name="mat"></param>
        /// <returns></returns>
        public static Matrix Inverse(Matrix mat)
        {
            int    n   = mat.height;
            Matrix ret = mat.Clone();

            LUP lum = DecomposeLUP(mat);

            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 == lum.perm[j])
                    {
                        b[j] = 1.0;
                    }
                    else
                    {
                        b[j] = 0.0;
                    }
                }
                double[] x = HelperSolve(lum.mat, b);
                for (int j = 0; j < n; ++j)
                {
                    ret[j][i] = x[j];
                }
            }
            return(ret);
        }
Beispiel #2
0
        /// <summary>
        /// 行列の行列式計算メソッド
        /// </summary>
        /// <param name="mat"></param>
        /// <returns></returns>
        public static double Det(Matrix mat)
        {
            LUP lum = DecomposeLUP(mat);

            if (lum == null)
            {
                throw new Exception("Unable to compute MatrixDeterminant");
            }
            double ret = lum.toggle;

            Parallel.For(0, lum.mat.height, i => { ret *= lum.mat[i][i]; });
            return(ret);
        }
Beispiel #3
0
        /// <summary>
        /// 行列のLUP分解メソッド
        /// </summary>
        /// <param name="mat"></param>
        /// <returns></returns>
        private static LUP DecomposeLUP(Matrix mat)
        {
            LUP ret = new LUP();

            ret.toggle = 1;
            ret.mat    = mat.Clone();
            ret.perm   = new int[mat.height];
            Parallel.For(0, mat.height, i => { ret.perm[i] = i; });

            for (int j = 0; j < mat.height - 1; j++)
            {
                double colMax = Math.Abs(ret.mat[j][j]); // largest val in col j
                int    pRow   = j;
                for (int i = j + 1; i < mat.height; ++i)
                {
                    if (ret.mat[i][j] > colMax)
                    {
                        colMax = ret.mat[i][j];
                        pRow   = i;
                    }
                }
                if (pRow != j) // swap rows
                {
                    double[] rowPtr = ret.mat[pRow];
                    ret.mat[pRow] = ret.mat[j];
                    ret.mat[j]    = rowPtr;
                    int tmp = ret.perm[pRow]; // and swap perm info
                    ret.perm[pRow] = ret.perm[j];
                    ret.perm[j]    = tmp;
                    ret.toggle     = -ret.toggle; // row-swap toggle
                }
                if (Math.Abs(ret.mat[j][j]) < 1.0E-20)
                {
                    return(null);                                   // consider a throw
                }
                for (int i = j + 1; i < mat.height; ++i)
                {
                    ret.mat[i][j] /= ret.mat[j][j];
                    for (int k = j + 1; k < mat.height; k++)
                    {
                        ret.mat[i][k] -= ret.mat[i][j] * ret.mat[j][k];
                    }
                }
            }
            return(ret);
        }