示例#1
0
        /// <summary>
        /// Inverts a matrix A to B so that A * B = I
        /// Borrowed from here: https://www.geeksforgeeks.org/adjoint-inverse-matrix/
        ///
        /// O(N^5)
        /// </summary>
        public void InvertMatrix()
        {
            #if ALLOW_EXCEPTIONS
            if (!IsSquareMatrix)
            {
                throw new InvalidShapeException("this should be a square matrix");
            }
            #endif

            var diagLength = Shape.shape[0];

            var det = DeterminantGaussianSafeDivision();
            #if ALLOW_EXCEPTIONS
            if (ConstantsAndFunctions <T> .IsZero(det))
            {
                throw new InvalidDeterminantException("Cannot invert a singular matrix");
            }
            #endif

            var adj = Adjoint();
            for (int x = 0; x < diagLength; x++)
            {
                for (int y = 0; y < diagLength; y++)
                {
                    this.SetValueNoCheck(
                        ConstantsAndFunctions <T> .Divide(
                            adj.GetValueNoCheck(x, y),
                            det
                            ),
                        x, y
                        );
                }
            }
        }
示例#2
0
        private GenTensor <SafeDivisionWrapper <T> > InnerGaussianEliminationSafeDivision(int n)
        {
            InitIfNotInitted();

            var elemMatrix = GenTensor <SafeDivisionWrapper <T> >
                             .CreateMatrix(n, n,
                                           (x, y) => new SafeDivisionWrapper <T>(ConstantsAndFunctions <T> .Forward(this.GetValueNoCheck(x, y)))
                                           );

            for (int k = 1; k < n; k++)
            {
                for (int j = k; j < n; j++)
                {
                    var m = ConstantsAndFunctions <SafeDivisionWrapper <T> > .Divide(
                        elemMatrix.GetValueNoCheck(j, k - 1),
                        elemMatrix.GetValueNoCheck(k - 1, k - 1)
                        );

                    for (int i = 0; i < n; i++)
                    {
                        var curr = elemMatrix.GetValueNoCheck(j, i);
                        elemMatrix.SetValueNoCheck(ConstantsAndFunctions <SafeDivisionWrapper <T> > .Subtract(
                                                       curr,
                                                       ConstantsAndFunctions <SafeDivisionWrapper <T> > .Multiply(
                                                           m,
                                                           elemMatrix.GetValueNoCheck(k - 1, i)
                                                           )
                                                       ), j, i);
                    }
                }
            }

            return(elemMatrix);
        }
示例#3
0
        // TODO: how to avoid code duplication?
        /// <summary>
        /// Performs simple Gaussian elimination method on a tensor
        ///
        /// O(N^3)
        /// </summary>
        public T DeterminantGaussianSimple()
        {
            #if ALLOW_EXCEPTIONS
            if (!IsMatrix)
            {
                throw new InvalidShapeException("this should be matrix");
            }
            if (Shape[0] != Shape[1])
            {
                throw new InvalidShapeException("this should be square matrix");
            }
            #endif
            if (Shape[0] == 1)
            {
                return(ConstantsAndFunctions <T> .Forward(this.GetValueNoCheck(0, 0)));
            }

            var n = Shape[0];

            var elemMatrix = this.Forward();
            for (int k = 1; k < n; k++)
            {
                for (int j = k; j < n; j++)
                {
                    var m = ConstantsAndFunctions <T> .Divide(
                        ConstantsAndFunctions <T> .Forward(elemMatrix.GetValueNoCheck(j, k - 1)),
                        ConstantsAndFunctions <T> .Forward(elemMatrix.GetValueNoCheck(k - 1, k - 1))
                        );

                    for (int i = 0; i < n; i++)
                    {
                        var curr = ConstantsAndFunctions <T> .Forward(elemMatrix.GetValueNoCheck(j, i));

                        elemMatrix.SetValueNoCheck(ConstantsAndFunctions <T> .Subtract(
                                                       curr,
                                                       ConstantsAndFunctions <T> .Multiply(
                                                           m,
                                                           elemMatrix.GetValueNoCheck(k - 1, i)
                                                           )
                                                       ), j, i);
                    }
                }
            }

            var det = ConstantsAndFunctions <T> .CreateOne();

            for (int i = 0; i < n; i++)
            {
                det = ConstantsAndFunctions <T> .Multiply(det, elemMatrix.GetValueNoCheck(i, i));
            }

            return(det);
        }
示例#4
0
 public W Count() => ConstantsAndFunctions <W> .Divide(num, den);
示例#5
0
 public static GenTensor <T> PiecewiseDivide(
     T a, GenTensor <T> b)
 => CreateTensor(b.Shape, ind =>
                 ConstantsAndFunctions <T> .Divide(a, b[ind]));
示例#6
0
 public static GenTensor <T> PiecewiseDivide(GenTensor <T> a,
                                             T b)
 => CreateTensor(a.Shape, ind =>
                 ConstantsAndFunctions <T> .Divide(a[ind], b));