You can use closures or pass the data parameter as an input to the function.
Here is an example with closures
type
AbstractKernel[T] = proc(dst: var T, src: Matrix[T], i, j: int)
{.closure.}
Matrix[T] = object
dim: array[2, int]
data: seq[T]
func newMatrix(rows, cols: int, T: typedesc): Matrix[T] =
result.dim[0] = rows
result.dim[1] = cols
result.data.newSeq(rows * cols)
func ncols(m: Matrix): int {.inline.} =
m.dim[1]
func nrows(m: Matrix): int {.inline.} =
m.dim[0]
template `[]`(m: Matrix, i, j: int): auto =
m.data[i * m.dim[1] + j]
template `[]=`[T](m: var Matrix[T], i, j: int, val: T) =
m.data[i * m.dim[1] + j] = val
proc calculateKernelMatrix*[T](m: Matrix[T], kernel: AbstractKernel[T]):
Matrix[T] =
result = newMatrix(m.nrows, m.ncols, T);
for i in 0 ..< m.nrows:
for j in 0 ..< m.ncols:
kernel(result[i, j], m, i, j);
let M = newMatrix(3, 3, int)
echo M # (dim: [3, 3], data: @[0, 0, 0, 0, 0, 0, 0, 0, 0])
let N = M.calculateKernelMatrix do (dst: var int, src: Matrix[int], i, j:
int):
let state = 100
dst = state * i + j
echo N # (dim: [3, 3], data: @[0, 1, 2, 100, 101, 102, 200, 201, 202])
let K = N.calculateKernelMatrix do (dst: var int, src: Matrix[int], i, j:
int):
let state = -1
dst = src[i, j] * state
echo K # (dim: [3, 3], data: @[0, -1, -2, -100, -101, -102, -200, -201,
-202])
Run
`state` can be anything beyond a simple int.