diff --git a/gallery/example3.pdf b/gallery/example3.pdf index ab2412c..2919817 100644 Binary files a/gallery/example3.pdf and b/gallery/example3.pdf differ diff --git a/gallery/example3.typ b/gallery/example3.typ index af5e7b3..3b0d861 100644 --- a/gallery/example3.typ +++ b/gallery/example3.typ @@ -25,3 +25,16 @@ $ $ E = #mat.display(E) $ + +#let M = mat.mat( + (2, 4, 5, 6), + (-1, 5, 6, 9), + (3, 7, 1, -6), + (4, -2, 3, 5) +) +$M = #mat.display(M)$ + +#let d = mat.det(M) +$det(M) = #d$ + +#mat.det-steps(M) \ No newline at end of file diff --git a/src/mat.typ b/src/mat.typ index 8fefc3d..0954883 100644 --- a/src/mat.typ +++ b/src/mat.typ @@ -43,9 +43,9 @@ return mat(..rows) } -#let display(mat) = { +#let display(mat, ..args) = { _check(mat) - math.mat(..mat.rows) + math.mat(..mat.rows, ..args.named()) } #let add(mat1, mat2) = { @@ -184,4 +184,102 @@ } return mat2 +} + +#let co-mat(mat1, elim-x, elim-y) = { + _check(mat1) + let mat2 = of-size(mat1.h - 1, mat1.w - 1) + for y in range(mat2.h) { + for x in range(mat2.w) { + let ox = if x < elim-x {x} else {x + 1} + let oy = if y < elim-y {y} else {y + 1} + mat2.rows.at(y).at(x) = mat1.rows.at(oy).at(ox) + } + } + return mat2 +} + +#let det(mat) = { + _check(mat) + if mat.w != mat.h { + panic("Matrix must be square") + } + + if mat.w == 0 { + return 1 + } + + let res = 0 + for y in range(mat.h) { + let sign = (1 - 2 * calc.rem(y, 2)) + let co-fact = det(co-mat(mat, 0, y)) + res += sign * mat.rows.at(y).at(0) * co-fact + } + return res +} + +#let det-steps(mat) = { + _check(mat) + if mat.w != mat.h { + panic("Matrix must be square") + } + + let res = [] + let lines = () + res += display(mat, delim: "|") + let ap = $&$.body + + let terms = ((1, mat,),) + for _ in range(mat.w - 2) { + let line = [ + #ap = + ] + + for (i, term) in terms.enumerate() { + let (coef, m) = term + + let sub-terms = () + for y in range(m.h) { + let c = (1 - 2 * calc.rem(y, 2)) * coef * m.rows.at(y).at(0) + let m2 = co-mat(m, 0, y) + if c != 0 { + sub-terms.push((c, m2)) + } + + if y + i != 0 and c >= 0 { + line += [+] + } + if c != 1 { + if c == -1 { + line += [-] + } else { + line += [#c #sym.dot] + } + } + line += display(m2, delim: "|") + } + + terms.at(i) = sub-terms + } + lines.push(line + linebreak()) + terms = terms.join() + } + + res += lines.join() + + res += [#ap =] + let total = 0 + for (i, term) in terms.enumerate() { + let (coef, m) = term + let value = coef * det(m) + total += value + if value != 0 { + if i != 0 and value >= 0 { + res += [+] + } + res += [#value] + } + } + res += [=#total] + return math.equation(res) } \ No newline at end of file