Пример #1
0
        public static GenTensor <T, TWrapper> Adjoint(GenTensor <T, TWrapper> t)
        {
            #if ALLOW_EXCEPTIONS
            if (!t.IsSquareMatrix)
            {
                throw new InvalidShapeException("Matrix should be square");
            }
            #endif
            var diagLength = t.Shape.shape[0];

            if (diagLength is 1)
            {
                return(GenTensor <T, TWrapper> .CreateIdentityMatrix(1));
            }

            var res = GenTensor <T, TWrapper> .CreateSquareMatrix(diagLength);

            var temp = SquareMatrixFactory <T, TWrapper> .GetMatrix(diagLength - 1);

            if (diagLength == 1)
            {
                res.SetValueNoCheck(default(TWrapper).CreateOne(), 0, 0);
                return(res);
            }

            var toNegate = false;

            for (int x = 0; x < diagLength; x++)
            {
                for (int y = 0; y < diagLength; y++)
                {
                    GetCofactorMatrix(t, temp, x, y, diagLength);

                    var cofactor = Determinant <T, TWrapper> .DeterminantGaussianSafeDivision(temp, diagLength - 1);

                    // TODO: is this statement correct?
                    toNegate = (x + y) % 2 == 1;
                    var minor = toNegate ? default(TWrapper).Negate(cofactor) : cofactor;

                    res.SetValueNoCheck(minor, y, x);
                }
            }

            return(res);
        }
Пример #2
0
        public static void InvertMatrix(GenTensor <T, TWrapper> t)
        {
            #if ALLOW_EXCEPTIONS
            if (!t.IsSquareMatrix)
            {
                throw new InvalidShapeException("this should be a square matrix");
            }
            #endif

            var diagLength = t.Shape.shape[0];

            if (diagLength is 1)
            {
                t.SetValueNoCheck(
                    default(TWrapper).Divide(
                        default(TWrapper).CreateOne(),
                        t.GetValueNoCheck(0, 0)
                        ), 0, 0);
                return;
            }

            var det = Determinant <T, TWrapper> .DeterminantGaussianSafeDivision(t);

            #if ALLOW_EXCEPTIONS
            if (default(TWrapper).IsZero(det))
            {
                throw new InvalidDeterminantException("Cannot invert a singular matrix");
            }
            #endif

            var adj = Adjoint(t);
            for (int x = 0; x < diagLength; x++)
            {
                for (int y = 0; y < diagLength; y++)
                {
                    t.SetValueNoCheck(
                        default(TWrapper).Divide(
                            adj.GetValueNoCheck(x, y),
                            det
                            ),
                        x, y
                        );
                }
            }
        }