nim-drchaos/examples/fuzz_matrix.nim

62 lines
1.9 KiB
Nim

# Code excerpt from https://github.com/andreaferretti/linear-algebra
type
Matrix32*[M, N: static[int]] = object
order: OrderType
data: ref array[N * M, float32]
OrderType* {.size: sizeof(int).} = enum
rowMajor = 101, colMajor = 102
template elem(m, i, j: untyped): untyped =
if m.order == colMajor: m.data[j * m.M + i]
else: m.data[i * m.N + j]
template slowEqPrivate(m, n: untyped) =
if m.M != n.M or m.N != n.N:
return false
for i in 0 ..< m.M:
for j in 0 ..< m.N:
if elem(m, i, j) != elem(n, i, j):
return false
return true
proc slowEq[M, N: static[int]](m, n: Matrix32[M, N]): bool = slowEqPrivate(m, n)
proc `==`*(m, n: Matrix32): bool =
if m.order == n.order: m.data[] == n.data[]
elif m.order == colMajor: slowEq(m, n)
else: slowEq(n, m)
template constantSMatrixPrivate(M, N, x, order, result: untyped) =
new result.data
result.order = order
for i in 0 ..< (M * N):
result.data[i] = x
proc constantSMatrix(M, N: static[int], x: float32, order: OrderType = colMajor): Matrix32[M, N] =
constantSMatrixPrivate(M, N, x, order, result)
proc zeros*(M, N: static[int], A: typedesc[float32], order: OrderType = colMajor): Matrix32[M, N] =
constantSMatrix(M, N, 0'f32, order)
proc eye*(N: static[int], A: typedesc[float32], order: OrderType = colMajor): Matrix32[N, N] =
result = zeros(N, N, float32, order)
for i in 0 ..< N:
result.data[i + N * i] = 1'f32
when isMainModule:
import drchaos
{.experimental: "strictFuncs".}
proc default[M, N: static[int]](_: typedesc[Matrix32[M, N]]): Matrix32[M, N] =
zeros(M, N, float32)
func fuzzTarget(x: Matrix32[3, 3]) =
when defined(dumpFuzzInput): debugEcho(x)
# Here you could multiply `x` with the identity matrix and make sure it doesn't change.
#doAssert x * eye(3, float32) =~ x
doAssert x != eye(3, float32)
defaultMutator(fuzzTarget)