From d880ebd2aaa99b97f27f2e7fffac328643da81d3 Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Tue, 25 Jun 2024 17:06:48 +0200 Subject: [PATCH] added param type check + some functions --- src/config.typ | 1 + src/lib.typ | 4 ++- src/mat.typ | 82 +++++++++++++++++++++++++++++++++++++++++++++++++- src/vec.typ | 32 +++++++++++++++++++- 4 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 src/config.typ diff --git a/src/config.typ b/src/config.typ new file mode 100644 index 0000000..6c19e83 --- /dev/null +++ b/src/config.typ @@ -0,0 +1 @@ +#let PRECISION = 6 \ No newline at end of file diff --git a/src/lib.typ b/src/lib.typ index d7d7bca..f90a91b 100644 --- a/src/lib.typ +++ b/src/lib.typ @@ -1,2 +1,4 @@ #import "mat.typ" -#import "vec.typ" \ No newline at end of file +#import "vec.typ" + +#import "gauss.typ" \ No newline at end of file diff --git a/src/mat.typ b/src/mat.typ index 793ee51..8fefc3d 100644 --- a/src/mat.typ +++ b/src/mat.typ @@ -1,4 +1,19 @@ +#import "config.typ" + +#let is-mat(mat) = { + if type(mat) != dictionary {return false} + if mat.at("type", default: none) != "matrix" {return false} + return true +} + +#let _check(mat) = { + if not is-mat(mat) { + panic("Argument is not a matrix") + } +} + #let size(mat) = { + _check(mat) return str(mat.h) + "x" + str(mat.w) } @@ -11,20 +26,31 @@ panic("All rows should have the same length") } return ( + type: "matrix", rows: rows, w: w, h: h ) } +#let copy(original) = { + _check(original) + return mat(..original.rows) +} + #let of-size(h, w) = { let rows = ((0,) * w,) * h return mat(..rows) } -#let display(mat) = math.mat(..mat.rows) +#let display(mat) = { + _check(mat) + math.mat(..mat.rows) +} #let add(mat1, mat2) = { + _check(mat1) + _check(mat2) if mat1.w != mat2.w or mat1.h != mat2.h { panic("Can't add matrices of size " + size(mat1) + " and " + size(mat2)) } @@ -41,6 +67,8 @@ } #let sub(mat1, mat2) = { + _check(mat1) + _check(mat2) if mat1.w != mat2.w or mat1.h != mat2.h { panic("Can't subtract matrices of size " + size(mat1) + " and " + size(mat2)) } @@ -57,6 +85,8 @@ } #let mul(mat1, mat2) = { + _check(mat1) + _check(mat2) if mat1.w != mat2.h { panic("Can't multiply matrices of size " + size(mat1) + " and " + size(mat2)) } @@ -77,6 +107,7 @@ } #let transpose(mat) = { + _check(mat) let mat-t = of-size(mat.w, mat.h) for y in range(mat.h) { @@ -89,11 +120,13 @@ } #let to-vec(mat) = { + _check(mat) import "vec.typ" as _vec return _vec.vec(..mat.rows.map(r => r.first())) } #let mul-vec(mat1, vec) = { + _check(mat1) import "vec.typ" as _vec if mat1.w != vec.size { @@ -104,4 +137,51 @@ let res = mul(mat1, mat2) return to-vec(res) +} + +#let mul-row(mat1, row, f) = { + _check(mat1) + let mat2 = copy(mat1) + + for x in range(mat1.w) { + mat2.rows.at(row).at(x) *= f + } + + return mat2 +} + +#let div-row(mat1, row, f) = { + _check(mat1) + if f == 0 { + panic("Can't divide by 0") + } + + return mul-row(mat1, row, 1/f) +} + +#let add-row(mat1, row1, row2, f: 1) = { + _check(mat1) + let mat2 = copy(mat1) + + for x in range(mat1.w) { + mat2.rows.at(row1).at(x) += mat1.rows.at(row2).at(x) * f + } + + return mat2 +} + +#let round(mat) = { + _check(mat) + let mat2 = copy(mat) + + for y in range(mat2.h) { + for x in range(mat2.w) { + mat2.rows.at(y).at(x) = calc.round( + mat2.rows.at(y).at(x), + digits: config.PRECISION + ) + } + } + + return mat2 } \ No newline at end of file diff --git a/src/vec.typ b/src/vec.typ index 1e7023f..ea280aa 100644 --- a/src/vec.typ +++ b/src/vec.typ @@ -1,20 +1,43 @@ +#let is-vec(vec) = { + if type(vec) != dictionary {return false} + if vec.at("type", default: none) != "vector" {return false} + return true +} + +#let _check(vec) = { + if not is-vec(vec) { + panic("Argument is not a vector") + } +} + #let vec(..args) = { let comps = args.pos() let size = comps.len() return ( + type: "vector", comps: comps, size: size ) } +#let copy(vec) = { + _check(vec) + return vec(..vec.comps) +} + #let of-size(size) = { let comps = (0,) * size return vec(..comps) } -#let display(vec) = math.vec(..vec.comps.map(c => [#c])) +#let display(vec) = { + _check(vec) + math.vec(..vec.comps.map(c => [#c])) +} #let add(vec1, vec2) = { + _check(vec1) + _check(vec2) if vec1.size != vec2.size { panic("Can't add vectors of size " + str(vec1.size) + " and " + str(vec2.size)) } @@ -24,6 +47,8 @@ } #let sub(vec1, vec2) = { + _check(vec1) + _check(vec2) if vec1.size != vec2.size { panic("Can't subtract vectors of size " + str(vec1.size) + " and " + str(vec2.size)) } @@ -33,6 +58,8 @@ } #let dot(vec1, vec2) = { + _check(vec1) + _check(vec2) if vec1.size != vec2.size { panic("Can't compute dot product of vectors of size " + str(vec1.size) + " and " + str(vec2.size)) } @@ -45,6 +72,8 @@ } #let cross(vec1, vec2) = { + _check(vec1) + _check(vec2) if vec1.size != 3 or vec2.size != 3 { panic("Can only compute cross product of vectors of size 3") } @@ -60,6 +89,7 @@ } #let to-mat(vec) = { + _check(vec) import "mat.typ" as _mat return _mat.mat(..vec.comps.map(c => (c,))) } \ No newline at end of file