Example #1
0
        public static NdArray Concatenate(NdArray a, NdArray b, int axis)
        {
            int[] shapeList = a.Shape.ToArray();
            shapeList[axis] += b.Shape[axis];

#if DEBUG
            for (int i = 0; i < a.Shape.Length; i++)
            {
                if (i != axis && a.Shape[i] != b.Shape[i])
                {
                    throw new Exception("配列の大きさがマッチしていません");
                }
            }

            if (a.BatchCount != b.BatchCount)
            {
                throw new Exception("バッチの大きさがマッチしていません");
            }
#endif

            NdArray result = new NdArray(shapeList, a.BatchCount);

            for (int batchCount = 0; batchCount < a.BatchCount; batchCount++)
            {
                int aInputBatchoffset = batchCount * a.Length;
                int bInputBatchoffset = batchCount * b.Length;

                for (int i = 0; i < a.Length; i++)
                {
                    int resultindex = result.GetLocalIndex(batchCount, a.GetDimensionsIndex(i));

                    result.Data[resultindex] = a.Data[i + aInputBatchoffset];
                    result.Grad[resultindex] = a.Grad[i + aInputBatchoffset];
                }

                for (int i = 0; i < b.Length; i++)
                {
                    int[] tmpIndex = b.GetDimensionsIndex(i);
                    tmpIndex[axis] += a.Shape[axis];

                    int resultIndex = result.GetLocalIndex(batchCount, tmpIndex);

                    result.Data[resultIndex] = b.Data[i + bInputBatchoffset];
                    result.Grad[resultIndex] = b.Grad[i + bInputBatchoffset];
                }
            }

            return(result);
        }
Example #2
0
        private static NdArray <Real> LocalSum(NdArray <Real> input, int axis)
        {
            int[] resultShape = new int[input.Shape.Length - 1];

            for (int i = 0, j = 0; i < input.Shape.Length; i++)
            {
                if (i != axis)
                {
                    resultShape[j++] = input.Shape[i];
                }
            }

            NdArray <Real> result = new NdArray <Real>(resultShape, input.BatchCount);

            for (int i = 0; i < input.Length; i++)
            {
                List <int> index = new List <int>(input.GetDimensionsIndex(i));
                index.RemoveAt(axis);
                int localIndex = result.GetLocalIndex(0, index.ToArray());

                for (int batchCount = 0; batchCount < input.BatchCount; batchCount++)
                {
                    result.Data[batchCount * result.Length + localIndex] += input.Data[batchCount * input.Length + i];
                    if (input.Grad != null)
                    {
                        result.Grad[batchCount * result.Length + localIndex] += input.Grad[batchCount * input.Length + i];
                    }
                }
            }

            return(result);
        }
Example #3
0
        private static NdArray Sum(NdArray a, int axis)
        {
            int[] resultShape = new int[a.Shape.Length - 1];

            for (int i = 0, j = 0; i < a.Shape.Length; i++)
            {
                if (i != axis)
                {
                    resultShape[j++] = a.Shape[i];
                }
            }

            NdArray result = new NdArray(resultShape, a.BatchCount);

            for (int i = 0; i < a.Length; i++)
            {
                List <int> index = new List <int>(a.GetDimensionsIndex(i));
                index.RemoveAt(axis);
                int localIndex = result.GetLocalIndex(0, index.ToArray());

                for (int batchCount = 0; batchCount < a.BatchCount; batchCount++)
                {
                    result.Data[batchCount * result.Length + localIndex] += a.Data[batchCount * a.Length + i];
                    result.Grad[batchCount * result.Length + localIndex] += a.Grad[batchCount * a.Length + i];
                }
            }

            return(result);
        }
Example #4
0
        public static NdArray Transpose(NdArray input, params int[] dimensions)
        {
#if DEBUG
            if (input.Shape.Length != dimensions.Length)
            {
                throw new Exception("次元数がマッチしていません");
            }

            for (int i = 0; i < dimensions.Length; i++)
            {
                //自身の中にダブりがないか
                for (int j = i + 1; j < dimensions.Length; j++)
                {
                    if (dimensions[i] == dimensions[j])
                    {
                        throw new Exception("指定された要素がダブっています");
                    }
                }
                //範囲チェック
                if (dimensions[i] >= input.Shape.Length || dimensions[i] < 0)
                {
                    throw new Exception("指定された要素が範囲を超えています");
                }
            }
#endif
            int[] transposedDimensions = new int[input.Shape.Length];

            for (int j = 0; j < input.Shape.Length; j++)
            {
                transposedDimensions[j] = input.Shape[dimensions[j]];
            }

            NdArray resultMatrix = new NdArray(transposedDimensions);

            for (int b = 0; b < input.BatchCount; b++)
            {
                for (int i = 0; i < input.Length; i++)
                {
                    int[] indecies        = input.GetDimensionsIndex(i);
                    int[] transposedIndex = new int[input.Shape.Length];

                    for (int j = 0; j < input.Shape.Length; j++)
                    {
                        transposedIndex[j] = indecies[dimensions[j]];
                    }

                    resultMatrix.Data[resultMatrix.GetLocalIndex(b, transposedIndex)] = input.Data[input.GetLocalIndex(b, indecies)];
                }
            }

            return(resultMatrix);
        }
Example #5
0
        public static NdArray[] Split(NdArray array, int[] indices, int axis)
        {
            int[] shapeOffets      = new int[indices.Length + 1];   //入力されたindicesの先頭0を追加した配列
            int[] resultAxisShapes = new int[indices.Length + 1];   //分割後の指定軸のShape

            for (int i = 0; i < indices.Length; i++)
            {
                shapeOffets[i + 1]  = indices[i];
                resultAxisShapes[i] = indices[i] - shapeOffets[i];
            }
            resultAxisShapes[indices.Length] = array.Shape[axis] - indices[indices.Length - 1];

            NdArray[] resultArrays = new NdArray[indices.Length + 1];

            for (int i = 0; i < resultArrays.Length; i++)
            {
                int[] resultShape = array.Shape.ToArray();
                resultShape[axis] = resultAxisShapes[i];
                resultArrays[i]   = new NdArray(resultShape, array.BatchCount);
                if (array.Grad != null)
                {
                    resultArrays[i].InitGrad();
                }
            }

            for (int batchCount = 0; batchCount < array.BatchCount; batchCount++)
            {
                for (int i = 0; i < resultArrays.Length; i++)
                {
                    for (int j = 0; j < resultArrays[i].Length; j++)
                    {
                        int[] resultIndex = resultArrays[i].GetDimensionsIndex(j);
                        resultIndex[axis] += shapeOffets[i];
                        int localIndex = array.GetLocalIndex(batchCount, resultIndex);

                        resultArrays[i].Data[batchCount * resultArrays[i].Length + j] = array.Data[localIndex];
                        if (array.Grad != null)
                        {
                            resultArrays[i].Grad[batchCount * resultArrays[i].Length + j] = array.Grad[localIndex];
                        }
                    }
                }
            }

            return(resultArrays);
        }