diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/modules/mkiv/m-matrix.mkiv')
-rw-r--r-- | Master/texmf-dist/tex/context/modules/mkiv/m-matrix.mkiv | 400 |
1 files changed, 289 insertions, 111 deletions
diff --git a/Master/texmf-dist/tex/context/modules/mkiv/m-matrix.mkiv b/Master/texmf-dist/tex/context/modules/mkiv/m-matrix.mkiv index f59363e94b0..9cac6967277 100644 --- a/Master/texmf-dist/tex/context/modules/mkiv/m-matrix.mkiv +++ b/Master/texmf-dist/tex/context/modules/mkiv/m-matrix.mkiv @@ -17,7 +17,7 @@ %D be made. Dalyoung does the clever bits, and Hans only cleanes up and %D optimizes a bit. -% \registerctxluafile{l-matrix}{1.001} % not yet +% \registerctxluafile{l-matrix}{} % not yet \startmodule[matrix] @@ -70,10 +70,16 @@ end -- todo: define a matrix at the tex end so that we have more control +-- local fences = { +-- parentheses = { left = "\\left(\\,", right = "\\,\\right)" }, +-- brackets = { left = "\\left[\\,", right = "\\,\\right]" }, +-- bars = { left = "\\left|\\,", right = "\\,\\right|" }, +-- } + local fences = { - parentheses = { left = "\\left(\\,", right = "\\,\\right)" }, - brackets = { left = "\\left[\\,", right = "\\,\\right]" }, - bars = { left = "\\left|\\,", right = "\\,\\right|" }, + parentheses = { "matrix:parentheses" }, + brackets = { "matrix:brackets" }, + bars = { "matrix:bars" }, } -- one can add more fences @@ -104,7 +110,10 @@ function matrix.typeset(m,options) elseif tonumber(template) then template = "%0." .. template .. "F" end - context.startmatrix(whatever) + context.startnamedmatrix(whatever) + if type(m[1]) ~= "table" then + m = { copy(m) } + end for i=1, #m do local mi = m[i] for j=1,#mi do @@ -118,31 +127,20 @@ function matrix.typeset(m,options) end context.NR() end - context.stopmatrix() + context.stopnamedmatrix() elseif m then context(m) end end --- interchange two rows (i-th, j-th) - --- function matrix.swaprows(t,i,j) --- if i <= #t and j <= #t then --- t[i], t[j] = t[j], t[i] --- return t --- else --- return "error: out of bound" --- end --- end - function matrix.swaprows(t,i,j) local ti = t[i] if not ti then - return "error: no row i" + return "error: no row" end local tj = t[j] if not tj then - return "error: no row j" + return "error: no row" end t[i], t[j] = tj, ti return t @@ -150,28 +148,14 @@ end -- interchange two columns (i-th, j-th) --- function matrix.swapcolumns(t, i, j) --- if i <= #t[1] and j <= #t[1] then --- for k = 1, #t do --- t[k][i], t[k][j] = t[k][j], t[k][i] --- end --- return t --- else --- return "error: out of bound" --- end --- end - function matrix.swapcolumns(t, i, j) local t1 = t[1] if not t1 then return "error: no rows" end local n = #t1 - if i <= n then - return "error: no row i" - end - if j <= n then - return "error: no row j" + if i > n or j > n then + return "error: no column" end for k = 1, #t do local tk = t[k] @@ -315,7 +299,7 @@ local function determinant(m) end return s*d else - return "error: not a square matrix" + return "error: not a square matrix" -- not context(..) end end @@ -387,7 +371,7 @@ matrix.rowEchelon = rowechelon -- make matrices until its determinant is not 0 -function matrix.make(n,m,low,high) +function matrix.make(m,n,low,high) -- m and n swapped if not n then n = 10 end @@ -398,17 +382,16 @@ function matrix.make(n,m,low,high) low = 0 end if not high then - high = 100 + high = 10 end - local t = { } -- make an empty n1 x n2 array - local again = true - for i=1,n do + local t = { } + for i=1,m do t[i] = { } end while true do - for i=1,n do + for i=1,m do local ti = t[i] - for j=1,m do + for j=1,n do ti[j] = random(low,high) end end @@ -483,14 +466,30 @@ end local function solve(m,c) local n = #m if n ~= #c then - return copy(m) + -- return "error: size mismatch" + return nil end local newm = copy(m) local temp = copy(c) + local solution = copy(c) for i=1,n do insert(newm[i],temp[i]) end - return rowechelon(newm,1) + newm = uppertri(newm, 0) + for k = n,1,-1 do + local val = 0 + local new = newm[k] + for j = k+1, n do + val = val + new[j] * solution[j] + end + if new[k] == 0 then + -- return "error: no unique solution" + return nil + else + solution[k] = (new[n+1] - val)/new[k] + end + end + return solution end matrix.solve = solve @@ -527,6 +526,9 @@ matrix.inverse = inverse \continueifinputfile{m-matrix.mkiv} +\usemodule[m-matrix] +\usemodule[art-01] + \starttext \startluacode @@ -542,147 +544,323 @@ document.DemoMatrixA = { document.DemoMatrixB = { { 0, 2, 4, -4, 1 }, { 0, 0, 2, 3, 4 }, - { 2, 2, -6, 2, 4 }, + { 2, 2, -6, 3, 4 }, { 2, 0, -6, 9, 7 }, { 2, 2, -6, 2, 4 }, - { 2, 2, -6, 2, 4 }, +} + +document.DemoMatrixC = { + { 3, 3, -1, 3 }, + { -1, 4, 1, 3 }, + { 5, 4, 0, 2 }, + { 2, 4, 0, -1 }, } \stopluacode +\startbuffer[demo] +\typebuffer +\startalignment[middle] + \dontleavehmode\inlinebuffer +\stopalignment +\stopbuffer + +\setuphead[section][before={\testpage[5]\blank[2*big]}] + \startsubject[title={A symbolic matrix}] +\startbuffer \ctxmodulematrix{typeset(moduledata.matrix.symbolic("a", "m", "n"))} \ctxmodulematrix{typeset(moduledata.matrix.symbolic("a", "m", "n", 4, 8))} +\stopbuffer + +\getbuffer[demo] + +\stopsubject + +\startsubject[title={Generate a new $m \times n$ matrix}] + +\startbuffer +\startluacode + moduledata.matrix.typeset(moduledata.matrix.make(4,3, 0,5)) + context.qquad() + moduledata.matrix.typeset(moduledata.matrix.make(5,5,-1,5)) +\stopluacode +\stopbuffer + +\getbuffer[demo] \stopsubject \startsubject[title={Swap two rows (2 and 4)}] +\startbuffer \startluacode -moduledata.matrix.typeset(document.DemoMatrixA) -context.blank() -moduledata.matrix.swap(document.DemoMatrixA, 2, 4) -context.blank() -moduledata.matrix.typeset(document.DemoMatrixA) + moduledata.matrix.typeset(document.DemoMatrixA) + context("$\\qquad \\Rightarrow \\qquad$") + moduledata.matrix.typeset(moduledata.matrix.swaprows(document.DemoMatrixA,2,4)) \stopluacode +\stopbuffer + +\getbuffer[demo] \stopsubject -\startsubject[title={Multiply $3 \times r_2$}] +\startsubject[title={Swap two columns (2 and 4)}] +\startbuffer \startluacode -moduledata.matrix.typeset(document.DemoMatrixA) -context.blank() -moduledata.matrix.typeset(moduledata.matrix.multiply(document.DemoMatrixA, 2, 3)) + moduledata.matrix.typeset(document.DemoMatrixA) + context("$\\qquad \\Rightarrow \\qquad$") + moduledata.matrix.typeset(moduledata.matrix.swapcolumns(document.DemoMatrixA,2, 4)) \stopluacode +\stopbuffer + +\getbuffer[demo] \stopsubject -\startsubject[title={Row 2 + $4 \times r_3$}] +\startsubject[title={Multiply 3 to row 2($3 \times r_2$)}] +\startbuffer \startluacode -moduledata.matrix.typeset(document.DemoMatrixA) -context.blank() -moduledata.matrix.sumrow(document.DemoMatrixA, 2, 3, 4) -context.blank() -moduledata.matrix.typeset(document.DemoMatrixA,{ fences = "bars" } ) + moduledata.matrix.typeset(document.DemoMatrixA) + context("$\\qquad \\Rightarrow \\qquad$") + moduledata.matrix.typeset(moduledata.matrix.multiply(document.DemoMatrixA,2,3)) \stopluacode +\stopbuffer + +\getbuffer[demo] \stopsubject -\startsubject[title={Transpose a matrix}] +\startsubject[title={Add 4 times of row 3 to row 2($r_2 + 4 \times r_3$)}] +\startbuffer \startluacode -moduledata.matrix.typeset(document.DemoMatrixA) -context.blank() -moduledata.matrix.typeset(moduledata.matrix.transpose(document.DemoMatrixA)) + moduledata.matrix.typeset(document.DemoMatrixA) + context("$\\qquad \\Rightarrow \\qquad$") + moduledata.matrix.sumrow(document.DemoMatrixA,2,3,4) + moduledata.matrix.typeset(document.DemoMatrixA) \stopluacode +\stopbuffer + +\getbuffer[demo] + +\stopsubject + +\startsubject[title={Transpose a matrix}] +\startbuffer +\startluacode + moduledata.matrix.typeset(document.DemoMatrixA) + context("$\\qquad \\Rightarrow \\qquad$") + moduledata.matrix.typeset(moduledata.matrix.transpose(document.DemoMatrixA)) +\stopluacode +\stopbuffer + +\getbuffer[demo] \stopsubject \startsubject[title={The inner product of two vectors}] +\startbuffer +\startluacode + context("$<1,2,3> \\cdot <3,1,2> \\ =\\ $ ") + context( moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2 })) +\stopluacode +\stopbuffer + +\getbuffer[demo] + \startluacode -context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2 })) -context.blank() +context("$<1,2,3> \\cdot <3,1,2, 4> \\ =\\ $ ") context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2, 4 })) \stopluacode +\stopbuffer + +\getbuffer[demo] + +\stopsubject \startsubject[title={The product of two matrices}] +\startbuffer \startluacode -moduledata.matrix.typeset(document.DemoMatrixA) -context.blank() -moduledata.matrix.typeset(moduledata.matrix.product(document.DemoMatrixA,document.DemoMatrixA)) + context("$\\ $") + moduledata.matrix.typeset(document.DemoMatrixB) + context("$\\cdot$") + moduledata.matrix.typeset(document.DemoMatrixA) + context("$ = $") + moduledata.matrix.typeset(moduledata.matrix.product + (document.DemoMatrixB,document.DemoMatrixB)) \stopluacode +\stopbuffer + +\getbuffer[demo] \stopsubject \startsubject[title={An Upper Triangular Matrix}] -\ctxmodulematrix{typeset(moduledata.matrix.uppertri(document.DemoMatrixB))} +\startbuffer +\startluacode + moduledata.matrix.typeset(document.DemoMatrixB) + context("$\\qquad \\Rightarrow \\qquad$") + moduledata.matrix.typeset(moduledata.matrix.uppertri(document.DemoMatrixB)) +\stopluacode +\stopbuffer + +\getbuffer[demo] -\startsubject[title={A determinant}] +\stopsubject +\startsubject[title={Determinant: using triangulation}] + +\startbuffer \startluacode -local m = { - { 1, 2, 4 }, - { 0, 0, 2 }, - { 2, 2, -6 }, -} -context(moduledata.matrix.determinant(m, "determinant=yes" )) + local m = { + { 1, 2, 4 }, + { 0, 0, 2 }, + { 2, 2, -6 }, + { 2, 2, -6 }, + } + moduledata.matrix.typeset(m, {fences="bars"}) + context("$\\qquad = \\qquad$") + moduledata.matrix.determinant(m) \stopluacode +\stopbuffer + +\getbuffer[demo] + +\startbuffer +\startluacode + moduledata.matrix.typeset(document.DemoMatrixC, { fences = "bars" }) + context("$\\qquad = \\qquad$") + context(moduledata.matrix.determinant(document.DemoMatrixC)) +\stopluacode +\stopbuffer + +\getbuffer[demo] \stopsubject -\startsubject[title={Row echelon form}] +\startsubject[title={Determinant: using Laplace Expansion}] +\startbuffer \startluacode -local m = { - { 1, 3, -2, 0, 2, 0, 0 }, - { 2, 6, -5, -2, 4, -3, -1 }, - { 0, 0, 5, 10, 0, 15, 5 }, - { 2, 6, 0, 8, 4, 18, 6 }, -} + moduledata.matrix.typeset(document.DemoMatrixC, { fences = "bars" }) + context("$\\qquad = \\qquad$") + context(moduledata.matrix.laplace(document.DemoMatrixC)) +\stopluacode +\stopbuffer + +\getbuffer[demo] + +\stopsubject + +\startsubject[title={Example of Laplace Expansion using submatrix function}] -moduledata.matrix.typeset(m) -context.blank() -moduledata.matrix.typeset(moduledata.matrix.rowechelon(m,1), { determinant = "yes" }) +\startbuffer +\startluacode + local m = { + { 1, 5, 4, 2 }, + { 5, 2, 0, 4 }, + { 2, 2, 1, 1 }, + { 1, 0, 0, 5 }, + } + local options = {fences = "bars"} + + moduledata.matrix.typeset(m,options) + context("\\par $=$") + for j = 1, #m[1] do + local mm = moduledata.matrix.submatrix(m, 1, j) + local factor = (-1)^(1+j) *(m[1][j]) + context("\\ ($%d$) \\cdot ", factor) + moduledata.matrix.typeset(mm, options) + if j < #m[1] then + context("\\ $+$ ") + end + end \stopluacode +\stopbuffer + +\getbuffer[demo] \stopsubject -\startsubject[title={Solving linear equation}] +\startsubject[title={Row echelon form}] +\startbuffer \startluacode -local m = { - { 1, 3, -2, 0 }, - { 2, 0, 1, 2 }, - { 6, -5, -2, 4 }, - { -3, -1, 5, 10 }, -} + local m = { + { 1, 3, -2, 0, 2, 0, 0 }, + { 2, 6, -5, -2, 4, -3, -1 }, + { 0, 0, 5, 10, 0, 15, 5 }, + { 2, 6, 0, 8, 4, 18, 6 }, + } + moduledata.matrix.typeset(m) + context("$\\Rightarrow$") + moduledata.matrix.typeset(moduledata.matrix.rowechelon(m,1)) +\stopluacode + +\stopbuffer -local c = { 5, 2, 6, 8 } - -moduledata.matrix.typeset(moduledata.matrix.solve(m,c)) -context.blank() -moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = 6 }) -context.blank() -moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = "no" }) -context.blank() -moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = "%0.3f" }) -context.blank() -moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = "%0.4F" }) +\getbuffer[demo] + +\stopsubject + +\startsubject[title={Solving linear equation}] + +\startbuffer +\startluacode + local m = { + { 1, 3, -2, 0 }, + { 2, 0, 1, 2 }, + { 6, -5, -2, 4 }, + { -3, -1, 5, 10 }, + } + + local c = { 5, 2, 6, 8 } + + moduledata.matrix.typeset(moduledata.matrix.solve(m,c)) + context.blank() + moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = 6 }) + context.blank() + moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = "no" }) + context.blank() + moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = "%0.3f" }) + context.blank() + moduledata.matrix.typeset(moduledata.matrix.solve(m,c), { template = "%0.4F" }) \stopluacode +\stopbuffer + +\getbuffer[demo] \stopsubject \startsubject[title={Inverse matrix}] -\startcombination[2*1] - {\ctxlua{moduledata.matrix.typeset { { 1, 1, 1 }, { 0, 2, 3 }, { 3, 2, 1 } }}} {} - {\ctxlua{moduledata.matrix.typeset(moduledata.matrix.inverse { { 1, 1, 1 }, { 0, 2, 3 }, { 3, 2, 1 } })}} {} -\stopcombination +\startbuffer +\startluacode + local m = { + { 1, 1, 1 }, + { 0, 2, 3 }, + { 3, 2, 1 }, + } + context("$A =\\quad$") + moduledata.matrix.typeset(m) + context("$\\qquad A^{-1} = \\quad$") + moduledata.matrix.typeset(moduledata.matrix.inverse(m)) + context("\\blank\\ ") + moduledata.matrix.typeset(m) + context("$\\cdot$") + moduledata.matrix.typeset(moduledata.matrix.inverse(m)) + context("$ = $") + moduledata.matrix.typeset(moduledata.matrix.product(m, moduledata.matrix.inverse(m))) +\stopluacode +\stopbuffer + +\getbuffer[demo] \stopsubject |