示例#1
0
 public GenTensor <T> GaussianEliminationSafeDivision()
 {
     #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
     var wrp = InnerGaussianEliminationSafeDivision(Shape[0]);
     return(GenTensor <T> .CreateMatrix(Shape[0], Shape[1], (x, y) => wrp.GetValueNoCheck(x, y).Count()));
 }
示例#2
0
 public bool Equals(GenTensor <T> obj)
 {
     if (obj.Shape != Shape)
     {
         return(false);
     }
     foreach (var(index, _) in obj.Iterate())
     {
         if (!ConstantsAndFunctions <T> .AreEqual(this.GetValueNoCheck(index), obj.GetValueNoCheck(index)))
         {
             return(false);
         }
     }
     return(true);
 }
示例#3
0
        /// <summary>
        /// Creates an indentity matrix whose width and height are equal to diag
        /// 1 is achieved with TWrapper.SetOne()
        /// 0 is achieved with TWrapper.SetZero()
        /// </summary>
        public static GenTensor <T> CreateIdentityMatrix(int diag)
        {
            var res = new GenTensor <T>(diag, diag);

            for (int i = 0; i < res.Data.Length; i++)
            {
                res.Data[i] = ConstantsAndFunctions <T> .CreateZero();
            }

            for (int i = 0; i < diag; i++)
            {
                res.SetValueNoCheck(ConstantsAndFunctions <T> .CreateOne, i, i);
            }
            return(res);
        }
示例#4
0
 /// <summary>
 /// A / B
 /// Finds such C = A / B that A = C * B
 ///
 /// O(N^5)
 /// </summary>
 public static GenTensor <T> MatrixDivide(GenTensor <T> a, GenTensor <T> b)
 {
     #if ALLOW_EXCEPTIONS
     if (!a.IsSquareMatrix || !b.IsSquareMatrix)
     {
         throw new InvalidShapeException("Both should be square matrices");
     }
     if (a.Shape != b.Shape)
     {
         throw new InvalidShapeException("Given matrices should be of the same shape");
     }
     #endif
     var fwd = b.Forward();
     fwd.InvertMatrix();
     return(MatrixMultiply(a, fwd));
 }
 /// <summary>
 /// Get a subtensor of a tensor
 /// If you have a t = Tensor[2 x 3 x 4],
 /// t.GetSubtensor(0) will return the proper matrix [3 x 4]
 ///
 /// O(1)
 /// </summary>
 public GenTensor <T, TWrapper> GetSubtensor(int index)
 {
     #if ALLOW_EXCEPTIONS
     ReactIfBadBound(index, 0);
     #endif
     var newLinIndexDelta = GetFlattenedIndexSilent(index);
     var newBlocks        = blocks.ToList();
     var rootAxis         = 0;
     newBlocks.RemoveAt(rootAxis);
     var newShape = Shape.CutOffset1();
     var result   = new GenTensor <T, TWrapper>(newShape, newBlocks.ToArray(), data)
     {
         LinOffset = newLinIndexDelta
     };
     return(result);
 }
 /// <summary>
 /// Applies scalar product to every vector in a tensor so that
 /// you will get a one-reduced dimensional tensor
 /// (e. g. TensorVectorDotProduct([4 x 3 x 2], [4 x 3 x 2]) -> [4 x 3]
 ///
 /// O(V)
 /// </summary>
 public static GenTensor <T> TensorVectorDotProduct(GenTensor <T> a,
                                                    GenTensor <T> b)
 {
     #if ALLOW_EXCEPTIONS
     if (a.Shape.SubShape(0, 1) != b.Shape.SubShape(0, 1))
     {
         throw new InvalidShapeException("Other dimensions of tensors should be equal");
     }
     #endif
     var resTensor = new GenTensor <T>(a.Shape.SubShape(0, 1));
     foreach (var index in resTensor.IterateOverElements())
     {
         var scal = VectorDotProduct(a.GetSubtensor(index), b.GetSubtensor(index));
         resTensor.SetValueNoCheck(scal, index);
     }
     return(resTensor);
 }
示例#7
0
        /// <summary>
        /// Creates a tensor whose all matrices are identity matrices
        /// 1 is achieved with TWrapper.SetOne()
        /// 0 is achieved with TWrapper.SetZero()
        /// </summary>
        public static GenTensor <T> CreateIdentityTensor(int[] dimensions, int finalMatrixDiag)
        {
            var newDims = new int[dimensions.Length + 2];

            for (int i = 0; i < dimensions.Length; i++)
            {
                newDims[i] = dimensions[i];
            }
            newDims[newDims.Length - 2] = newDims[newDims.Length - 1] = finalMatrixDiag;
            var res = new GenTensor <T>(newDims);

            foreach (var index in res.IterateOverMatrices())
            {
                var iden = CreateIdentityMatrix(finalMatrixDiag);
                res.SetSubtensor(iden, index);
            }
            return(res);
        }
 /// <summary>
 /// Slice with data sharing like in python
 /// A[3:5] in python
 /// same as
 /// A.Slice(3, 5) in GT
 ///
 /// O(N)
 /// </summary>
 // TODO: Make it O(1)
 public GenTensor <T, TWrapper> Slice(int leftIncluding, int rightExcluding)
 {
     #if ALLOW_EXCEPTIONS
     ReactIfBadBound(leftIncluding, 0);
     ReactIfBadBound(rightExcluding - 1, 0);
     if (leftIncluding >= rightExcluding)
     {
         throw new InvalidShapeException("Slicing cannot be performed");
     }
     #endif
     var newLength = rightExcluding - leftIncluding;
     var toStack   = new GenTensor <T, TWrapper> [newLength];
     for (int i = 0; i < newLength; i++)
     {
         toStack[i] = GetSubtensor(i + leftIncluding);
     }
     return(Stack(toStack));
 }
示例#9
0
        public static GenTensor <T> Concat(GenTensor <T> a, GenTensor <T> b)
        {
            #if ALLOW_EXCEPTIONS
            if (a.Shape.SubShape(1, 0) != b.Shape.SubShape(1, 0))
            {
                throw new InvalidShapeException("Excluding the first dimension, all others should match");
            }
            #endif

            if (a.IsVector)
            {
                var resultingVector = GenTensor <T> .CreateVector(a.Shape.shape[0] + b.Shape.shape[0]);

                for (int i = 0; i < a.Shape.shape[0]; i++)
                {
                    resultingVector.SetValueNoCheck(ConstantsAndFunctions <T> .Forward(a.GetValueNoCheck(i)), i);
                }

                for (int i = 0; i < b.Shape.shape[0]; i++)
                {
                    resultingVector.SetValueNoCheck(ConstantsAndFunctions <T> .Forward(b.GetValueNoCheck(i)), i + a.Shape.shape[0]);
                }

                return(resultingVector);
            }
            else
            {
                var newShape = a.Shape.Copy();
                newShape.shape[0] = a.Shape.shape[0] + b.Shape.shape[0];

                var res = new GenTensor <T>(newShape);
                for (int i = 0; i < a.Shape.shape[0]; i++)
                {
                    res.SetSubtensor(a.GetSubtensor(i), i);
                }

                for (int i = 0; i < b.Shape.shape[0]; i++)
                {
                    res.SetSubtensor(b.GetSubtensor(i), i + a.Shape.shape[0]);
                }

                return(res);
            }
        }
示例#10
0
 /// <summary>
 /// Calls VectorCrossProduct for every vector in the tensor
 /// </summary>
 public static GenTensor <T> TensorVectorCrossProduct(GenTensor <T> a,
                                                      GenTensor <T> b)
 {
     #if ALLOW_EXCEPTIONS
     if (a.Shape != b.Shape)
     {
         throw new InvalidShapeException($"Pre-shapes of {nameof(a)} and {nameof(b)} should be equal");
     }
     #endif
     var res = new GenTensor <T>(a.Shape);
     foreach (var index in a.IterateOverVectors())
     {
         res.SetSubtensor(
             VectorCrossProduct(a.GetSubtensor(index), b.GetSubtensor(index)),
             index
             );
     }
     return(res);
 }
示例#11
0
        /// <summary>
        /// Copies a tensor calling each cell with a .Copy()
        ///
        /// O(V)
        /// </summary>
        public GenTensor <T> Copy(bool copyElements)
        {
            var res = new GenTensor <T>(Shape);

            if (!copyElements)
            {
                foreach (var index in res.IterateOverElements())
                {
                    res.SetValueNoCheck(ConstantsAndFunctions <T> .Forward(GetValueNoCheck(index)), index);
                }
            }
            else
            {
                foreach (var index in res.IterateOverElements())
                {
                    res.SetValueNoCheck(ConstantsAndFunctions <T> .Copy(GetValueNoCheck(index)), index);
                }
            }
            return(res);
        }
示例#12
0
        /// <summary>
        /// Returns adjugate matrix
        ///
        /// O(N^5)
        /// </summary>
        public GenTensor <T> Adjoint()
        {
            #if ALLOW_EXCEPTIONS
            if (!IsSquareMatrix)
            {
                throw new InvalidShapeException("Matrix should be square");
            }
            #endif
            var diagLength = Shape.shape[0];
            var res        = GenTensor <T> .CreateSquareMatrix(diagLength);

            var temp = SquareMatrixFactory <T> .GetMatrix(diagLength);

            if (diagLength == 1)
            {
                res.SetValueNoCheck(ConstantsAndFunctions <T> .CreateOne(), 0, 0);
                return(res);
            }

            var toNegate = false;

            for (int x = 0; x < diagLength; x++)
            {
                for (int y = 0; y < diagLength; y++)
                {
                    GetCofactor(this, temp, x, y, diagLength);
                    toNegate = (x + y) % 2 == 1;
                    var det = temp.DeterminantGaussianSafeDivision(diagLength - 1);
                    if (toNegate)
                    {
                        res.SetValueNoCheck(ConstantsAndFunctions <T> .Negate(det), y, x);
                    }
                    else
                    {
                        res.SetValueNoCheck(det, y, x);
                    }
                }
            }

            return(res);
        }
示例#13
0
        private static void GetCofactor(GenTensor <T> a, GenTensor <T> temp, int rowId,
                                        int colId, int diagLength)
        {
            int i = 0, j = 0;

            for (int row = 0; row < diagLength; row++)
            {
                for (int col = 0; col < diagLength; col++)
                {
                    if (row != rowId && col != colId)
                    {
                        temp.SetValueNoCheck(a.GetValueNoCheck(row, col), i, j++);
                        if (j == diagLength - 1)
                        {
                            j = 0;
                            i++;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Finds the scalar product of two vectors
        ///
        /// O(N)
        /// </summary>
        public static T VectorDotProduct(GenTensor <T> a,
                                         GenTensor <T> b)
        {
            #if ALLOW_EXCEPTIONS
            if (!a.IsVector || !b.IsVector)
            {
                throw new InvalidShapeException($"{nameof(a)} and {nameof(b)} should be vectors");
            }
            if (a.Shape[0] != b.Shape[0])
            {
                throw new InvalidShapeException($"{nameof(a)}'s length should be the same as {nameof(b)}'s");
            }
            #endif
            var res = ConstantsAndFunctions <T> .CreateZero();

            for (int i = 0; i < a.Shape[0]; i++)
            {
                res = ConstantsAndFunctions <T> .Add(res,
                                                     ConstantsAndFunctions <T> .Multiply(a.GetValueNoCheck(i), b.GetValueNoCheck(i)));
            }
            return(res);
        }
示例#15
0
        public static GenTensor <T> TensorMatrixDivide(GenTensor <T> a, GenTensor <T> b)
        {
            #if ALLOW_EXCEPTIONS
            InvalidShapeException.NeedTensorSquareMatrix(a);
            InvalidShapeException.NeedTensorSquareMatrix(b);
            if (a.Shape != b.Shape)
            {
                throw new InvalidShapeException("Should be of the same shape");
            }
            #endif

            var res = new GenTensor <T>(a.Shape);
            foreach (var ind in res.IterateOverMatrices())
            {
                res.SetSubtensor(
                    MatrixDivide(
                        a.GetSubtensor(ind),
                        b.GetSubtensor(ind)
                        ), ind);
            }

            return(res);
        }
示例#16
0
 /// <summary>
 /// Get a subtensor of a tensor
 /// If you have a t = Tensor[2 x 3 x 4],
 /// t.GetSubtensor(0) will return the proper matrix [3 x 4]
 ///
 /// O(1)
 /// </summary>
 public GenTensor <T> GetSubtensor(int index)
 {
     #if ALLOW_EXCEPTIONS
     ReactIfBadBound(index, 0);
     #endif
     var newLinIndexDelta = GetFlattenedIndexSilent(index);
     var newBlocks        = Blocks.ToList();
     var rootAxis         = AxesOrder[0];
     newBlocks.RemoveAt(rootAxis);
     var newAxesOrder = AxesOrder.ToList();
     for (int i = 0; i < newAxesOrder.Count; i++)
     {
         if (newAxesOrder[i] > rootAxis)
         {
             newAxesOrder[i] -= 1;
         }
     }
     newAxesOrder.RemoveAt(0);
     var newShape = Shape.CutOffset1();
     var result   = new GenTensor <T>(newShape, newBlocks.ToArray(), newAxesOrder.ToArray(), Data);
     result.LinOffset = newLinIndexDelta;
     return(result);
 }
示例#17
0
 public static GenTensor <T> PiecewiseSubtract(
     T a, GenTensor <T> b)
 => CreateTensor(b.Shape, ind =>
                 ConstantsAndFunctions <T> .Subtract(a, b[ind]));
示例#18
0
 public static GenTensor <T, TWrapper> Concat(GenTensor <T, TWrapper> a, GenTensor <T, TWrapper> b)
 => Composition <T, TWrapper> .Concat(a, b);
示例#19
0
 public static GenTensor <T> PiecewiseSubtract(GenTensor <T> a,
                                               GenTensor <T> b)
 => Zip(a, b, ConstantsAndFunctions <T> .Subtract);
示例#20
0
 public static GenTensor <T> PiecewiseAdd(GenTensor <T> a,
                                          GenTensor <T> b)
 => Zip(a, b, ConstantsAndFunctions <T> .Add);
示例#21
0
 public static GenTensor <T> PiecewiseDivide(
     T a, GenTensor <T> b)
 => CreateTensor(b.Shape, ind =>
                 ConstantsAndFunctions <T> .Divide(a, b[ind]));
示例#22
0
 public static GenTensor <T> PiecewiseDivide(GenTensor <T> a,
                                             T b)
 => CreateTensor(a.Shape, ind =>
                 ConstantsAndFunctions <T> .Divide(a[ind], b));
示例#23
0
 public static GenTensor <T> PiecewiseSubtract(GenTensor <T> a,
                                               T b)
 => CreateTensor(a.Shape, ind =>
                 ConstantsAndFunctions <T> .Subtract(a[ind], b));
示例#24
0
 public static GenTensor <T> PiecewiseDivide(GenTensor <T> a,
                                             GenTensor <T> b)
 => Zip(a, b, ConstantsAndFunctions <T> .Divide);
示例#25
0
 public static GenTensor <T> PiecewiseMultiply(GenTensor <T> a,
                                               GenTensor <T> b)
 => Zip(a, b, ConstantsAndFunctions <T> .Multiply);
示例#26
0
 public static GenTensor <T> PiecewiseMultiply(GenTensor <T> a,
                                               T b)
 => CreateTensor(a.Shape, ind =>
                 ConstantsAndFunctions <T> .Multiply(a[ind], b));
示例#27
0
        /// <summary>
        /// Creates a vector from an array of primitives
        /// Its length will be equal to elements.Length
        /// </summary>
        public static GenTensor <T> CreateVector(int length)
        {
            var res = new GenTensor <T>(length);

            return(res);
        }