예제 #1
0
 /// <summary>
 /// Creates a new axis that is put backward
 /// and then sets all elements as children
 /// e. g.
 /// say you have a bunch of tensors {t1, t2, t3} with shape of [2 x 4]
 /// Stack(t1, t2, t3) => T
 /// where T is a tensor of shape of [3 x 2 x 4]
 ///
 /// O(V)
 /// </summary>
 public static GenTensor <T> Stack(params GenTensor <T>[] elements)
 {
     #if ALLOW_EXCEPTIONS
     if (elements.Length < 1)
     {
         throw new InvalidShapeException("Shoud be at least one element to stack");
     }
     #endif
     var desiredShape = elements[0].Shape;
     #if ALLOW_EXCEPTIONS
     for (int i = 1; i < elements.Length; i++)
     {
         if (elements[i].Shape != desiredShape)
         {
             throw new InvalidShapeException($"Tensors in {nameof(elements)} should be of the same shape");
         }
     }
     #endif
     var newShape = new int[desiredShape.Count + 1];
     newShape[0] = elements.Length;
     for (int i = 1; i < newShape.Length; i++)
     {
         newShape[i] = desiredShape[i - 1];
     }
     var res = new GenTensor <T>(newShape);
     for (int i = 0; i < elements.Length; i++)
     {
         res.SetSubtensor(elements[i], i);
     }
     return(res);
 }
예제 #2
0
 /// <summary>
 /// Applies matrix dot product operation for
 /// all matrices in tensors
 ///
 /// O(N^3)
 /// </summary>
 public static GenTensor <T> TensorMatrixMultiply(GenTensor <T> a,
                                                  GenTensor <T> b)
 {
     #if ALLOW_EXCEPTIONS
     if (a.Shape.Count < 2 || b.Shape.Count < 2)
     {
         throw new InvalidShapeException($"Arguments should be at least matrices while their shapes are {a.Shape} and {b.Shape}");
     }
     if (a.Shape.SubShape(0, 2) != b.Shape.SubShape(0, 2))
     {
         throw new InvalidShapeException("Other dimensions of tensors should be equal");
     }
     #endif
     var oldShape = a.Shape.SubShape(0, 2).ToArray();
     var newShape = new int[oldShape.Length + 2];
     for (int i = 0; i < oldShape.Length; i++)
     {
         newShape[i] = oldShape[i];
     }
     newShape[newShape.Length - 2] = a.Shape[a.Shape.Length - 2];
     newShape[newShape.Length - 1] = b.Shape[b.Shape.Length - 1];
     var resTensor = new GenTensor <T>(newShape);
     foreach (var subDimensions in a.IterateOverMatrices())
     {
         var product = MatrixMultiply(a.GetSubtensor(subDimensions), b.GetSubtensor(subDimensions));
         resTensor.SetSubtensor(product, subDimensions);
     }
     return(resTensor);
 }
예제 #3
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);
            }
        }
예제 #4
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);
        }
예제 #5
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);
 }
예제 #6
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);
        }