import sequtils, typetraits type Size = uint64 type M[T: SomeNumber] = object dims: seq[Size] subsizes: seq[Size] data: seq[T] #################################################################################################### # Miscellaneous. func dotProduct[T: SomeNumber](a, b: openArray[T]): T = assert a.len == b.len for i in 0..a.high: result += a[i] * b[i] #################################################################################################### # Operations on M objects. func setDimensions(m: var M; dimensions: varargs[Size]) = for dim in dimensions: if dim == 0: raise newException(IndexDefect, "wrong dimension: 0") m.dims = @dimensions m.subsizes = m.dims for i in 0..dimensions.high: m.subsizes[i] = m.dims[(i+1)..^1].foldl(a * b, Size(1)) let dlength = m.dims[0] * m.subsizes[0] if Size(m.data.len) != dlength: m.data.setLen(dlength) #--------------------------------------------------------------------------------------------------- func initM(m: var M; dimensions: varargs[Size]) = m.setDimensions(dimensions) #--------------------------------------------------------------------------------------------------- func set1DArray(m: var M; t: varargs[m.T]) = let minLen = min(m.data.len, t.len) m.data.setLen(minLen) m.data[0.. m.dims.len: return false for i, dim in indexes: if dim >= m.dims[i]: return false result = true #--------------------------------------------------------------------------------------------------- func `[]`(m: M; indexes: varargs[Size]): m.T = if not m.checkBounds(indexes): raise newException(IndexDefect, "index out of range: " & $indexes) m.data[dotProduct(indexes, m.subsizes)] #--------------------------------------------------------------------------------------------------- func `[]=`(m: M; indexes: varargs[int]; val: m.T) = if not m.checkBounds(indexes): raise newException(IndexDefect, "index out of range: " & $indexes) m.data[dotProduct(indexes, m.subsizes)] = val #--------------------------------------------------------------------------------------------------- func `==`(a, b: M): bool = a.dims == b.dims and a.data == b.data #--------------------------------------------------------------------------------------------------- func `$`(m: M): string = $m.data #################################################################################################### # Convolution/deconvolution. func convolute(h, f: M): M = ## Result is "g". var dims = h.dims for i in 0..dims.high: dims[i] += f.dims[i] - 1 result.initM(dims) let bound = result.size for i in 0..