Exemple #1
0
        /// <summary>
        /// [i, j, k...]th element of the resulting tensor is
        /// operation(a[i, j, k...], b[i, j, k...])
        /// </summary>
        public static GenTensor <T> Zip(GenTensor <T> a,
                                        GenTensor <T> b, Func <T, T, T> operation)
        {
            #if ALLOW_EXCEPTIONS
            if (a.Shape != b.Shape)
            {
                throw new InvalidShapeException("Arguments should be of the same shape");
            }
            #endif
            var res = new GenTensor <T>(a.Shape);

            if (res.Shape.shape.Length == 1)
            {
                for (int x = 0; x < res.Shape.shape[0]; x++)
                {
                    res.Data[x] = ConstantsAndFunctions <T> .Forward(
                        operation(a.GetValueNoCheck(x), b.GetValueNoCheck(x)));
                }
            }
            else if (res.Shape.shape.Length == 2)
            {
                for (int x = 0; x < res.Shape.shape[0]; x++)
                {
                    for (int y = 0; y < res.Shape.shape[1]; y++)
                    {
                        res.Data[x * res.Blocks[0] + y] = ConstantsAndFunctions <T> .Forward(
                            operation(a.GetValueNoCheck(x, y), b.GetValueNoCheck(x, y)));
                    }
                }
            }
            else if (res.Shape.shape.Length == 3)
            {
                for (int x = 0; x < res.Shape.shape[0]; x++)
                {
                    for (int y = 0; y < res.Shape.shape[1]; y++)
                    {
                        for (int z = 0; z < res.Shape.shape[2]; z++)
                        {
                            res.Data[x * res.Blocks[0] + y * res.Blocks[1] + z] = ConstantsAndFunctions <T> .Forward(
                                operation(a.GetValueNoCheck(x, y, z), b.GetValueNoCheck(x, y, z)));
                        }
                    }
                }
            }
            else
            {
                foreach (var index in res.IterateOverElements())
                {
                    res.SetValueNoCheck(ConstantsAndFunctions <T> .Forward(
                                            operation(a.GetValueNoCheck(index), b.GetValueNoCheck(index))), index);
                }
            }
            return(res);
        }
        /// <summary>
        /// Finds matrix multiplication result
        /// a and b are matrices
        /// a.Shape[1] should be equal to b.Shape[0]
        /// the resulting matrix is [a.Shape[0] x b.Shape[1]] shape
        ///
        /// O(N^3)
        /// </summary>
        public static GenTensor <T> MatrixMultiply(GenTensor <T> a,
                                                   GenTensor <T> b)
        {
            #if ALLOW_EXCEPTIONS
            if (!a.IsMatrix || !b.IsMatrix)
            {
                throw new InvalidShapeException($"Both {nameof(a)} and {nameof(b)} should be matrices");
            }
            if (a.Shape[1] != b.Shape[0])
            {
                throw new InvalidShapeException($"{nameof(a)}'s height must be equal to {nameof(b)}'s width");
            }
            #endif

            var width  = a.Shape[0];
            var height = b.Shape[1];
            var row    = a.Shape[1];
            var res    = CreateMatrix(width, height);
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    var s = ConstantsAndFunctions <T> .CreateZero();

                    for (int i = 0; i < row; i++)
                    {
                        var v1 = a.GetValueNoCheck(x, i);
                        var v2 = b.GetValueNoCheck(i, y);
                        s = ConstantsAndFunctions <T> .Add(s, ConstantsAndFunctions <T> .Multiply(v1, v2));
                    }
                    res.SetValueNoCheck(s, x, y);
                }
            }
            return(res);
        }
Exemple #3
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++;
                        }
                    }
                }
            }
        }
        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);
            }
        }
        /// <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);
        }
 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);
 }