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); }
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); }
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); }
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); }
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); }