示例#1
0
        public static Matrix SubMatrixOfInv(this Matrix mat, IList <int> idxs, ILinAlg ila, string invopt)
        {
            Matrix InvInvA = mat.InvOfSubMatrixOfInv(idxs, ila, invopt);
            /// (inv(M))_00 = inv(A - B inv(D) C)
            var    InvInvAA = ila.ToILMat(InvInvA);
            var    InvAA    = ila.PInv(InvInvAA);
            Matrix InvA     = InvAA.ToArray();

            return(InvA);
        }
示例#2
0
        public static Matrix InvSymm(this ILinAlg ila, Matrix A)
        {
            var    AA    = ila.ToILMat(A);
            var    invAA = ila.InvSymm(AA);
            Matrix invA  = ToMatrix(invAA);

            AA.Dispose();
            invAA.Dispose();
            GC.Collect();
            return(invA);
        }
示例#3
0
        public static Tuple <Matrix, Vector> EigSymm(this ILinAlg ila, Matrix A)
        {
            var    AA   = ila.ToILMat(A);
            var    VVDD = ila.EigSymm(AA);
            Matrix V    = VVDD.Item1.ToMatrix();
            Vector D    = VVDD.Item2;

            AA.Dispose();
            VVDD.Item1.Dispose();
            GC.Collect();
            return(new Tuple <Matrix, Vector>(V, D));
        }
示例#4
0
        public static Matrix LinSolve(this ILinAlg ila, Matrix A, Matrix B)
        {
            var    AA = ila.ToILMat(A);
            var    BB = ila.ToILMat(B);
            var    XX = ila.LinSolve(AA, BB);
            Matrix X  = XX.ToMatrix();

            AA.Dispose();
            BB.Dispose();
            XX.Dispose();
            GC.Collect();
            return(X);
        }
示例#5
0
        public static Matrix HInv(this ILinAlg ila, Matrix A, string invtype, params object[] invopt)
        {
            Matrix invA;

            {
                ILinAlgMat AA    = ila.ToILMat(A);
                ILinAlgMat invAA = ila.HInv(AA, invtype, invopt);
                invA = invAA.ToMatrix();
                AA.Dispose();
                invAA.Dispose();
            }
            GC.Collect();
            return(invA);
        }
示例#6
0
        public static Matrix Mul(this ILinAlg ila, params Matrix[] mats)
        {
            ILinAlgMat[] MATS = new ILinAlgMat[mats.Length];
            for (int i = 0; i < mats.Length; i++)
            {
                MATS[i] = ila.ToILMat(mats[i]);
            }
            ILinAlgMat MUL = ila.Mul(MATS);
            Matrix     mul = ToMatrix(MUL);

            MUL.Dispose();
            foreach (var MAT in MATS)
            {
                MAT.Dispose();
            }
            return(mul);
        }
示例#7
0
        public static Matrix InvOfSubMatrixOfInv(this Matrix mat, IList <int> idxs, ILinAlg ila, string invtype, params object[] invopt)
        {
            if (HDebug.Selftest())
            {
                MatrixByArr tH = new double[, ] {
                    { 1, 2, 3, 4 }
                    , { 2, 5, 6, 7 }
                    , { 3, 6, 8, 9 }
                    , { 4, 7, 9, 10 }
                };
                MatrixByArr tInvH = new double[, ] {
                    { 0.5, -0.5, -1.5, 1.5 }                                 // = inv(tH)
                    , { -0.5, 1.5, -1.5, 0.5 }
                    , { -1.5, -1.5, 3.5, -1.5 }
                    , { 1.5, 0.5, -1.5, 0.5 }
                };
                MatrixByArr tInvH12 = new double[, ] {
                    { 0.5, -0.5 }                                            // = block matrix of tInvH
                    , { -0.5, 1.5 }
                };
                MatrixByArr tInvtInvH12 = new double[, ] {
                    { 3, 1 }                                            // = inv([ 0.5, -0.5])
                    , { 1, 1 }
                };                                                      //       [-0.5,  1.5]
                MatrixByArr ttInvtInvH12 = tH.InvOfSubMatrixOfInv(new int[] { 0, 1 }, ila, null).ToArray();
                HDebug.AssertTolerance(0.00000001, tInvtInvH12 - ttInvtInvH12);
            }

            int ColSize = mat.ColSize;
            int RowSize = mat.RowSize;

            if (ColSize != RowSize)
            {
                HDebug.Assert(false); return(null);
            }
            if (idxs.Count != idxs.HToHashSet().Count)
            {
                HDebug.Assert(false); return(null);
            }

            List <int> idxs0 = idxs.ToList();
            List <int> idxs1 = new List <int>();

            for (int i = 0; i < ColSize; i++)
            {
                if (idxs.Contains(i) == false)
                {
                    idxs1.Add(i);
                }
            }

            Matrix InvInvA;

            {
                Matrix A = mat.SubMatrix(idxs0, idxs0); Matrix B = mat.SubMatrix(idxs0, idxs1); // [A B]
                Matrix C = mat.SubMatrix(idxs1, idxs0); Matrix D = mat.SubMatrix(idxs1, idxs1); // [C D]

                /// http://en.wikipedia.org/wiki/Invertable_matrix#Blockwise_inversion
                ///
                /// M^-1 = [M_00 M_01] = [A B]-1 = [ (A - B D^-1 C)^-1  ... ]
                ///      = [M_10 M_11] = [C D]     [   ...              ... ]
                ///
                /// (inv(M))_00 = inv(A - B inv(D) C)
                /// inv((inv(M))_00) = (A - B inv(D) C)
                var AA       = ila.ToILMat(A);
                var BB       = ila.ToILMat(B);
                var CC       = ila.ToILMat(C);
                var DD       = ila.ToILMat(D);
                var InvDD    = ila.HInv(DD, invtype, invopt);
                var InvInvAA = AA - BB * InvDD * CC;
                //var xx = BB * InvDD * CC;

                InvInvA = InvInvAA.ToArray();
                AA.Dispose();
                BB.Dispose();
                CC.Dispose();
                DD.Dispose();
                InvDD.Dispose();
                InvInvAA.Dispose();
            }
            GC.Collect();
            return(InvInvA);
        }
示例#8
0
        public static ILinAlgMat HInv(this ILinAlg ila, ILinAlgMat AA, string invtype, params object[] invopt)
        {
            if (invtype == null)
            {
                invtype = "inv";
            }
            object optparam = null;

            switch (invtype)
            {
            case "inv":
                return(ila.Inv(AA));

            case "pinv":
                return(ila.PInv(AA));

            case "eig-zerothres":
            {
                var VVDD = ila.EigSymm(AA);

                double threshold = (double)invopt[0];
                for (int i = 0; i < VVDD.Item2.Length; i++)
                {
                    if (Math.Abs(VVDD.Item2[i]) < threshold)
                    {
                        VVDD.Item2[i] = 0;
                    }
                }

                optparam = VVDD;
            }
                goto case "eig-VVDD";

            case "eig-zerocount":
            {
                var VVDD = ila.EigSymm(AA);

                int zerocount = (int)invopt[0];
                for (int i = 0; i < zerocount; i++)
                {
                    VVDD.Item2[i] = 0;
                }

                optparam = VVDD;
            }
                goto case "eig-VVDD";

            case "eig-VVDD":
            {
                Tuple <ILinAlgMat, double[]> VVDD = optparam as Tuple <ILinAlgMat, double[]>;
                for (int i = 0; i < VVDD.Item2.Length; i++)
                {
                    if (VVDD.Item2[i] != 0)
                    {
                        VVDD.Item2[i] = 1 / VVDD.Item2[i];
                    }
                }
                var invAA = ila.Mul(VVDD.Item1, ila.ToILMat(VVDD.Item2).Diag(), VVDD.Item1.Tr);
                if (HDebug.IsDebuggerAttached)
                {
                    var check = AA * invAA;
                    check.Dispose();
                }
                VVDD.Item1.Dispose();
                return(invAA);
            }

            default:
                throw new NotImplementedException();
            }
        }
示例#9
0
 public static ILinAlg.ILinAlgMat AddDisposable(this ILinAlg.ILinAlgMat mat)
 {
     ILinAlg.AddDisposable(mat);
     return(mat);
 }