Esempio n. 1
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);
        }
Esempio n. 2
0
        /// <summary>
        /// Finds a perpendicular vector to two given
        /// TODO: So far only implemented for 3D vectors
        /// </summary>
        public static GenTensor <T> VectorCrossProduct(GenTensor <T> a,
                                                       GenTensor <T> b)
        {
            #if ALLOW_EXCEPTIONS
            if (!a.IsVector || !b.IsVector)
            {
                throw new InvalidShapeException($"Both {nameof(a)} and {nameof(b)} should be vectors");
            }
            if (a.Shape[0] != b.Shape[0])
            {
                throw new InvalidShapeException($"Length of {nameof(a)} and {nameof(b)} should be equal");
            }
            if (a.Shape[0] != 3)
            {
                throw new NotImplementedException("Other than vectors of the length of 3 aren't supported for VectorCrossProduct yet");
            }
            #endif
            return(GenTensor <T> .CreateVector(
                       ConstantsAndFunctions <T> .Subtract(
                           ConstantsAndFunctions <T> .Multiply(a[1], b[2]),
                           ConstantsAndFunctions <T> .Multiply(a[2], b[1])),

                       ConstantsAndFunctions <T> .Subtract(
                           ConstantsAndFunctions <T> .Multiply(a[2], b[0]),
                           ConstantsAndFunctions <T> .Multiply(a[0], b[2])),

                       ConstantsAndFunctions <T> .Subtract(
                           ConstantsAndFunctions <T> .Multiply(a[0], b[1]),
                           ConstantsAndFunctions <T> .Multiply(a[1], b[0]))
                       ));
        }
Esempio n. 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);
        }
Esempio n. 4
0
        private static void InitIfNotInitted()
        {
            if (isFracInitted)
            {
                return;
            }
            isFracInitted = true;

            ConstantsAndFunctions <SafeDivisionWrapper <T> > .Add =
                (a, b) =>
                new SafeDivisionWrapper <T>(
                    ConstantsAndFunctions <T> .Add(
                        ConstantsAndFunctions <T> .Multiply(a.num, b.den),
                        ConstantsAndFunctions <T> .Multiply(a.den, b.num)
                        ),
                    ConstantsAndFunctions <T> .Multiply(a.den, b.den)
                    );

            ConstantsAndFunctions <SafeDivisionWrapper <T> > .Subtract =
                (a, b) =>
                new SafeDivisionWrapper <T>(
                    ConstantsAndFunctions <T> .Subtract(
                        ConstantsAndFunctions <T> .Multiply(a.num, b.den),
                        ConstantsAndFunctions <T> .Multiply(a.den, b.num)
                        ),
                    ConstantsAndFunctions <T> .Multiply(a.den, b.den)
                    );

            ConstantsAndFunctions <SafeDivisionWrapper <T> > .Multiply =
                (a, b) =>
                new SafeDivisionWrapper <T>(
                    ConstantsAndFunctions <T> .Multiply(a.num, b.num),
                    ConstantsAndFunctions <T> .Multiply(a.den, b.den)
                    );

            ConstantsAndFunctions <SafeDivisionWrapper <T> > .Divide =
                (a, b) =>
                new SafeDivisionWrapper <T>(
                    ConstantsAndFunctions <T> .Multiply(a.num, b.den),
                    ConstantsAndFunctions <T> .Multiply(a.den, b.num)
                    );

            ConstantsAndFunctions <SafeDivisionWrapper <T> > .CreateOne = () =>
                                                                          new SafeDivisionWrapper <T>(ConstantsAndFunctions <T> .CreateOne());
        }
Esempio n. 5
0
 public static GenTensor <T> PiecewiseSubtract(
     T a, GenTensor <T> b)
 => CreateTensor(b.Shape, ind =>
                 ConstantsAndFunctions <T> .Subtract(a, b[ind]));
Esempio n. 6
0
 public static GenTensor <T> PiecewiseSubtract(GenTensor <T> a,
                                               T b)
 => CreateTensor(a.Shape, ind =>
                 ConstantsAndFunctions <T> .Subtract(a[ind], b));