added matrix + vector functions
This commit is contained in:
2
src/lib.typ
Normal file
2
src/lib.typ
Normal file
@ -0,0 +1,2 @@
|
||||
#import "mat.typ"
|
||||
#import "vec.typ"
|
107
src/mat.typ
Normal file
107
src/mat.typ
Normal file
@ -0,0 +1,107 @@
|
||||
#let size(mat) = {
|
||||
return str(mat.h) + "x" + str(mat.w)
|
||||
}
|
||||
|
||||
#let mat(..args) = {
|
||||
let rows = args.pos()
|
||||
//rows = rows.map(r => if r == none {()} else {r})
|
||||
let h = rows.len()
|
||||
let w = if h == 0 {0} else {rows.first().len()}
|
||||
if rows.find(r => r.len() != w) != none {
|
||||
panic("All rows should have the same length")
|
||||
}
|
||||
return (
|
||||
rows: rows,
|
||||
w: w,
|
||||
h: h
|
||||
)
|
||||
}
|
||||
|
||||
#let of-size(h, w) = {
|
||||
let rows = ((0,) * w,) * h
|
||||
return mat(..rows)
|
||||
}
|
||||
|
||||
#let display(mat) = math.mat(..mat.rows)
|
||||
|
||||
#let add(mat1, mat2) = {
|
||||
if mat1.w != mat2.w or mat1.h != mat2.h {
|
||||
panic("Can't add matrices of size " + size(mat1) + " and " + size(mat2))
|
||||
}
|
||||
|
||||
let mat3 = of-size(mat1.h, mat1.w)
|
||||
|
||||
for y in range(mat1.h) {
|
||||
for x in range(mat1.w) {
|
||||
mat3.rows.at(y).at(x) = mat1.rows.at(y).at(x) + mat2.rows.at(y).at(x)
|
||||
}
|
||||
}
|
||||
|
||||
return mat3
|
||||
}
|
||||
|
||||
#let sub(mat1, mat2) = {
|
||||
if mat1.w != mat2.w or mat1.h != mat2.h {
|
||||
panic("Can't subtract matrices of size " + size(mat1) + " and " + size(mat2))
|
||||
}
|
||||
|
||||
let mat3 = of-size(mat1.h, mat1.w)
|
||||
|
||||
for y in range(mat1.h) {
|
||||
for x in range(mat1.w) {
|
||||
mat3.rows.at(y).at(x) = mat1.rows.at(y).at(x) - mat2.rows.at(y).at(x)
|
||||
}
|
||||
}
|
||||
|
||||
return mat3
|
||||
}
|
||||
|
||||
#let mul(mat1, mat2) = {
|
||||
if mat1.w != mat2.h {
|
||||
panic("Can't multiply matrices of size " + size(mat1) + " and " + size(mat2))
|
||||
}
|
||||
|
||||
let mat3 = of-size(mat1.h, mat2.w)
|
||||
|
||||
for y in range(mat1.h) {
|
||||
for x in range(mat2.w) {
|
||||
let sum = 0
|
||||
for i in range(mat1.w) {
|
||||
sum += mat1.rows.at(y).at(i) * mat2.rows.at(i).at(x)
|
||||
}
|
||||
mat3.rows.at(y).at(x) = sum
|
||||
}
|
||||
}
|
||||
|
||||
return mat3
|
||||
}
|
||||
|
||||
#let transpose(mat) = {
|
||||
let mat-t = of-size(mat.w, mat.h)
|
||||
|
||||
for y in range(mat.h) {
|
||||
for x in range(mat.w) {
|
||||
mat-t.rows.at(x).at(y) = mat.rows.at(y).at(x)
|
||||
}
|
||||
}
|
||||
|
||||
return mat-t
|
||||
}
|
||||
|
||||
#let to-vec(mat) = {
|
||||
import "vec.typ" as _vec
|
||||
return _vec.vec(..mat.rows.map(r => r.first()))
|
||||
}
|
||||
|
||||
#let mul-vec(mat1, vec) = {
|
||||
import "vec.typ" as _vec
|
||||
|
||||
if mat1.w != vec.size {
|
||||
panic("Can't multiply matrix of size " + size(mat1) + " and vector of size " + _vec.size(vec))
|
||||
}
|
||||
|
||||
let mat2 = _vec.to-mat(vec)
|
||||
let res = mul(mat1, mat2)
|
||||
|
||||
return to-vec(res)
|
||||
}
|
65
src/vec.typ
Normal file
65
src/vec.typ
Normal file
@ -0,0 +1,65 @@
|
||||
#let vec(..args) = {
|
||||
let comps = args.pos()
|
||||
let size = comps.len()
|
||||
return (
|
||||
comps: comps,
|
||||
size: size
|
||||
)
|
||||
}
|
||||
|
||||
#let of-size(size) = {
|
||||
let comps = (0,) * size
|
||||
return vec(..comps)
|
||||
}
|
||||
|
||||
#let display(vec) = math.vec(..vec.comps.map(c => [#c]))
|
||||
|
||||
#let add(vec1, vec2) = {
|
||||
if vec1.size != vec2.size {
|
||||
panic("Can't add vectors of size " + str(vec1.size) + " and " + str(vec2.size))
|
||||
}
|
||||
|
||||
let comps = vec1.comps.zip(vec2.comps).map(p => p.sum())
|
||||
return vec(..comps)
|
||||
}
|
||||
|
||||
#let sub(vec1, vec2) = {
|
||||
if vec1.size != vec2.size {
|
||||
panic("Can't subtract vectors of size " + str(vec1.size) + " and " + str(vec2.size))
|
||||
}
|
||||
|
||||
let comps = vec1.comps.zip(vec2.comps).map(p => p.first() - p.last())
|
||||
return vec(..comps)
|
||||
}
|
||||
|
||||
#let dot(vec1, vec2) = {
|
||||
if vec1.size != vec2.size {
|
||||
panic("Can't compute dot product of vectors of size " + str(vec1.size) + " and " + str(vec2.size))
|
||||
}
|
||||
|
||||
let res = vec1.comps.zip(vec2.comps)
|
||||
.map(p => p.product())
|
||||
.sum(default: 0)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
#let cross(vec1, vec2) = {
|
||||
if vec1.size != 3 or vec2.size != 3 {
|
||||
panic("Can only compute cross product of vectors of size 3")
|
||||
}
|
||||
|
||||
let vec3 = of-size(3)
|
||||
for i in range(3) {
|
||||
let i1 = calc.rem(i + 1, 3)
|
||||
let i2 = calc.rem(i1 + 1, 3)
|
||||
vec3.comps.at(i) = vec1.comps.at(i1) * vec2.comps.at(i2)
|
||||
vec3.comps.at(i) -= vec1.comps.at(i2) * vec2.comps.at(i1)
|
||||
}
|
||||
return vec3
|
||||
}
|
||||
|
||||
#let to-mat(vec) = {
|
||||
import "mat.typ" as _mat
|
||||
return _mat.mat(..vec.comps.map(c => (c,)))
|
||||
}
|
Reference in New Issue
Block a user