added param type check + some functions

This commit is contained in:
Louis Heredero 2024-06-25 17:06:48 +02:00
parent dac6d1dc53
commit d880ebd2aa
Signed by: HEL
GPG Key ID: 8D83DE470F8544E7
4 changed files with 116 additions and 3 deletions

1
src/config.typ Normal file
View File

@ -0,0 +1 @@
#let PRECISION = 6

View File

@ -1,2 +1,4 @@
#import "mat.typ" #import "mat.typ"
#import "vec.typ" #import "vec.typ"
#import "gauss.typ"

View File

@ -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) = { #let size(mat) = {
_check(mat)
return str(mat.h) + "x" + str(mat.w) return str(mat.h) + "x" + str(mat.w)
} }
@ -11,20 +26,31 @@
panic("All rows should have the same length") panic("All rows should have the same length")
} }
return ( return (
type: "matrix",
rows: rows, rows: rows,
w: w, w: w,
h: h h: h
) )
} }
#let copy(original) = {
_check(original)
return mat(..original.rows)
}
#let of-size(h, w) = { #let of-size(h, w) = {
let rows = ((0,) * w,) * h let rows = ((0,) * w,) * h
return mat(..rows) return mat(..rows)
} }
#let display(mat) = math.mat(..mat.rows) #let display(mat) = {
_check(mat)
math.mat(..mat.rows)
}
#let add(mat1, mat2) = { #let add(mat1, mat2) = {
_check(mat1)
_check(mat2)
if mat1.w != mat2.w or mat1.h != mat2.h { if mat1.w != mat2.w or mat1.h != mat2.h {
panic("Can't add matrices of size " + size(mat1) + " and " + size(mat2)) panic("Can't add matrices of size " + size(mat1) + " and " + size(mat2))
} }
@ -41,6 +67,8 @@
} }
#let sub(mat1, mat2) = { #let sub(mat1, mat2) = {
_check(mat1)
_check(mat2)
if mat1.w != mat2.w or mat1.h != mat2.h { if mat1.w != mat2.w or mat1.h != mat2.h {
panic("Can't subtract matrices of size " + size(mat1) + " and " + size(mat2)) panic("Can't subtract matrices of size " + size(mat1) + " and " + size(mat2))
} }
@ -57,6 +85,8 @@
} }
#let mul(mat1, mat2) = { #let mul(mat1, mat2) = {
_check(mat1)
_check(mat2)
if mat1.w != mat2.h { if mat1.w != mat2.h {
panic("Can't multiply matrices of size " + size(mat1) + " and " + size(mat2)) panic("Can't multiply matrices of size " + size(mat1) + " and " + size(mat2))
} }
@ -77,6 +107,7 @@
} }
#let transpose(mat) = { #let transpose(mat) = {
_check(mat)
let mat-t = of-size(mat.w, mat.h) let mat-t = of-size(mat.w, mat.h)
for y in range(mat.h) { for y in range(mat.h) {
@ -89,11 +120,13 @@
} }
#let to-vec(mat) = { #let to-vec(mat) = {
_check(mat)
import "vec.typ" as _vec import "vec.typ" as _vec
return _vec.vec(..mat.rows.map(r => r.first())) return _vec.vec(..mat.rows.map(r => r.first()))
} }
#let mul-vec(mat1, vec) = { #let mul-vec(mat1, vec) = {
_check(mat1)
import "vec.typ" as _vec import "vec.typ" as _vec
if mat1.w != vec.size { if mat1.w != vec.size {
@ -104,4 +137,51 @@
let res = mul(mat1, mat2) let res = mul(mat1, mat2)
return to-vec(res) 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
} }

View File

@ -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 vec(..args) = {
let comps = args.pos() let comps = args.pos()
let size = comps.len() let size = comps.len()
return ( return (
type: "vector",
comps: comps, comps: comps,
size: size size: size
) )
} }
#let copy(vec) = {
_check(vec)
return vec(..vec.comps)
}
#let of-size(size) = { #let of-size(size) = {
let comps = (0,) * size let comps = (0,) * size
return vec(..comps) 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) = { #let add(vec1, vec2) = {
_check(vec1)
_check(vec2)
if vec1.size != vec2.size { if vec1.size != vec2.size {
panic("Can't add vectors of size " + str(vec1.size) + " and " + str(vec2.size)) panic("Can't add vectors of size " + str(vec1.size) + " and " + str(vec2.size))
} }
@ -24,6 +47,8 @@
} }
#let sub(vec1, vec2) = { #let sub(vec1, vec2) = {
_check(vec1)
_check(vec2)
if vec1.size != vec2.size { if vec1.size != vec2.size {
panic("Can't subtract vectors of size " + str(vec1.size) + " and " + str(vec2.size)) panic("Can't subtract vectors of size " + str(vec1.size) + " and " + str(vec2.size))
} }
@ -33,6 +58,8 @@
} }
#let dot(vec1, vec2) = { #let dot(vec1, vec2) = {
_check(vec1)
_check(vec2)
if vec1.size != vec2.size { if vec1.size != vec2.size {
panic("Can't compute dot product of vectors of size " + str(vec1.size) + " and " + str(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) = { #let cross(vec1, vec2) = {
_check(vec1)
_check(vec2)
if vec1.size != 3 or vec2.size != 3 { if vec1.size != 3 or vec2.size != 3 {
panic("Can only compute cross product of vectors of size 3") panic("Can only compute cross product of vectors of size 3")
} }
@ -60,6 +89,7 @@
} }
#let to-mat(vec) = { #let to-mat(vec) = {
_check(vec)
import "mat.typ" as _mat import "mat.typ" as _mat
return _mat.mat(..vec.comps.map(c => (c,))) return _mat.mat(..vec.comps.map(c => (c,)))
} }