public IMatrix ReverseMaxPool(IMatrix error, int size, int filterSize, int filterDepth, IReadOnlyList <int[]> indexList) { var filterIndex = 0; var filters = error.ConvertInPlaceToVector().Split(filterDepth); var sparseDictionary = Enumerable.Range(0, filterDepth).Select(i => new Dictionary <Tuple <int, int>, float>()).ToList(); foreach (var item in filters) { var itemIndex = 0; int xOffset = 0, yOffset = 0; foreach (var value in item.AsIndexable().Values) { var maxIndex = indexList[itemIndex][filterIndex]; var yIndex = maxIndex / filterSize; var xIndex = maxIndex % filterSize; sparseDictionary[filterIndex].Add(Tuple.Create(xOffset + xIndex, yOffset + yIndex), value); xOffset += filterSize; if (xOffset >= size) { yOffset += filterSize; xOffset = 0; } ++itemIndex; } ++filterIndex; } var ret = DenseMatrix.Create(size * size, filterDepth, (i, j) => { var y = i / size; var x = i % size; float val; if (sparseDictionary[j].TryGetValue(Tuple.Create(x, y), out val)) { return(val); } return(0f); }); return(new CpuMatrix(ret)); }