Files
mmath/matrix_test.nim
2018-12-26 08:14:25 +00:00

183 lines
4.1 KiB
Nim

from random import randomize, random
from utils import `...`
import matrix
from matrix import det
from vector import createVector, newVector, `-`, abs, norm
import unittest
suite "Nim linear algebra library":
echo "suite setup: run once before the tests"
randomize()
var mtx : Matrix[float64]
setup:
echo "run before each test"
let DIM = 100
var numbers = newSeq[float64](DIM * DIM)
for i in 0...len(numbers):
numbers[i] = float64(random(-DIM..DIM))
mtx = newMatrix[float64](DIM,DIM,numbers)
teardown:
echo "run after each test"
test "LU decomposition":
var lu = mtx.clone()
let pivot = lu.lu()
test "Linear system solve":
# let nums = [2.0,1.0,3.0,2.0,6.0,8.0,6.0,8.0,18.0]
# let nums = [-3.0, -1.0, 0.0, -2.0, 0.0, 2.0, -3.0, -1.0, 0.0]
let DIM = 100
var numbers = newSeq[float64](DIM * DIM)
for i in 0...len(numbers):
numbers[i] = float64(random(-DIM..DIM))
var mtx = newMatrix[float64](DIM,DIM,numbers)
var lu = mtx.clone()
let pivot = lu.lu()
var b = newVector[float64](DIM)
for i in 0...len(b):
b[i] = float64(random(DIM))
let x = lu.lu_solve(b, pivot)
let error = (mtx * x) - b
check(error.norm() < 1e-5)
# var mtx2 = mtx.clone
# for i in 0...10000:
# var add = random(-DIM..DIM).float64()
# discard mtx2 += add
# echo mtx
# mtx[1,1] += 10000.0
# echo mtx
# echo mtx.det()
# echo lu
# give up and stop if this fails
echo "suite teardown: run once after the tests"
# let m1 = newMatrix[float](3,3,[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0])
# var m2 = m1.clone()
# let m3 = m2.clone()
# m2[2,1] = -25
# echo m1 + m2
# echo m2
# echo m1.det()
# let nums = [-63, 3, 70, -23, 55,
# -100, -37, 81, -98, 84,
# -36, -45, -70, 98, -18,
# -15, 92, 82, 85, -2,
# 45, 54, -22, 27, 0
# ]
# let s = nums.map(proc(n : int) : float = float(n))
# let s2 = nums.map(n => float(n))
# let m4 = newMatrix[float](5,5,s)
# echo m4
# echo m4.det
# var m5 = m4.clone()
# var pivot = m5.lu()
# let b = createVector[float](1.0,2.0,3.0,4.0,5.0)
# let x = m5.lu_solve(b, pivot)
# echo x
# proc new(T: typedesc): ref T =
# echo "allocating "
# new(result)
# var n = new Vector[int]
# type
# Index = distinct int
# proc `==` (a, b: Index): bool {.borrow.}
# var af = (0, 0.Index)
# var b = (0, 0.Index)
# echo af == b # works!
# type Person = ref object of RootObj
# name : string
# age : int
# type Employee = ref object of Person
# salary: int
# type RecordType = tuple or object
# proc printFields(rec: RecordType) =
# for key, value in fieldPairs(rec):
# echo key, " = ", value
# proc printFields(rec: ref[RecordType]) =
# for key, value in fieldPairs(rec[]):
# echo key, " = ", value
# let p = Person(name : "Walter", age : 28)
# let e = Employee(name : "Walter", age : 28, salary: 45000)
# let people : seq[Person] = @[p, e]
# for person in people:
# printFields person
# let DIM = 5
# var numbers = newSeq[float](DIM * DIM)
# for i in 0...len(numbers):
# numbers[i] = float(random(DIM))
# let m = newMatrix[float](DIM,DIM, numbers)
# var m2 = new(Matrix[float])
# m2[] = m.clone()
# echo m2[]
# m2[][0,0] = 300
# echo m2[]
# let inverse = m2[].invert()
# echo m
# echo m.det
# echo m * inverse
# echo inverse * m
# let nums = [2.0,1.0,3.0,2.0,6.0,8.0,6.0,8.0,18.0]
# let nums = [-3.0, -1.0, 0.0, -2.0, 0.0, 2.0, -3.0, -1.0, 0.0]
# let DIM = 600
# var numbers = newSeq[float64](DIM * DIM)
# for i in 0...len(numbers):
# numbers[i] = float64(random(-DIM..DIM))
# var mtx = newMatrix[float64](DIM,DIM,numbers)
# var mtx2 = mtx.clone
# for i in 0...10000:
# var add = random(-DIM..DIM).float64()
# discard mtx2 += add
# echo mtx
# mtx[1,1] += 10000.0
# echo mtx
# echo mtx.det()
# var lu = mtx.clone()
# let pivot = lu.lu()
# # echo lu
# var b = newVector[float64](DIM)
# for i in 0...len(b):
# b[i] = float64(random(DIM))
# let x = lu.lu_solve(b, pivot)
# let error = (mtx * x) - b
# echo abs(error)