diff options
author | Hans Hagen <pragma@wxs.nl> | 2017-02-23 18:12:36 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2017-02-23 18:12:36 +0100 |
commit | c91d92093b72a73a92c3ae3c641137abe6fb64b9 (patch) | |
tree | bfbdc4359ae391d0d96e577fb544023464427e81 /tex/context/modules/mkiv/m-matrix.mkiv | |
parent | e4223677ac0d23e4888e41efda0d2e6aabbe76bf (diff) | |
download | context-c91d92093b72a73a92c3ae3c641137abe6fb64b9.tar.gz |
2017-02-23 17:13:00
Diffstat (limited to 'tex/context/modules/mkiv/m-matrix.mkiv')
-rw-r--r-- | tex/context/modules/mkiv/m-matrix.mkiv | 160 |
1 files changed, 155 insertions, 5 deletions
diff --git a/tex/context/modules/mkiv/m-matrix.mkiv b/tex/context/modules/mkiv/m-matrix.mkiv index b72453bdd..f59363e94 100644 --- a/tex/context/modules/mkiv/m-matrix.mkiv +++ b/tex/context/modules/mkiv/m-matrix.mkiv @@ -28,6 +28,7 @@ local formatters = string.formatters local copy = table.copy local insert = table.insert local remove = table.remove +local random = math.random local context = context @@ -92,8 +93,8 @@ function matrix.typeset(m,options) if options.fences then whatever = fences[options.fences] or whatever elseif options.determinant then - whatever = fences.brackets - -- whatever = fences.bars + -- whatever = fences.brackets + whatever = fences.bars end local template = options.template or matrix.template if template == "yes" then @@ -125,10 +126,64 @@ end -- interchange two rows (i-th, j-th) -function matrix.swap(t,i,j) - t[i], t[j] = t[j], t[i] +-- 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" + end + local tj = t[j] + if not tj then + return "error: no row j" + end + t[i], t[j] = tj, ti + return t +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" + end + for k = 1, #t do + local tk = t[k] + tk[i], tk[j] = tk[j], tk[i] + end + return t end +matrix.swapC = matrix.swapcolumns +matrix.swapR = matrix.swaprows +matrix.swap = matrix.swaprows + -- replace i-th row with factor * (i-th row) function matrix.multiply(m,i,factor) @@ -251,7 +306,7 @@ end matrix.uppertri = uppertri -function matrix.determinant(m) +local function determinant(m) if #m == #m[1] then local d = 1 local t, s = uppertri(m,1) @@ -264,6 +319,8 @@ function matrix.determinant(m) end end +matrix.determinant = determinant + local function rowechelon(m,r) local temp = copy(m) local pRow = 1 @@ -328,6 +385,99 @@ end matrix.rowechelon = rowechelon matrix.rowEchelon = rowechelon +-- make matrices until its determinant is not 0 + +function matrix.make(n,m,low,high) + if not n then + n = 10 + end + if not m then + m = 10 + end + if not low then + low = 0 + end + if not high then + high = 100 + end + local t = { } -- make an empty n1 x n2 array + local again = true + for i=1,n do + t[i] = { } + end + while true do + for i=1,n do + local ti = t[i] + for j=1,m do + ti[j] = random(low,high) + end + end + if n ~= m or determinant(t,1) ~= 0 then + return t + end + end +end + +-- extract submatrix by using + +local function submatrix(t,i,j) + local rows = #t + local columns = #t[1] + local sign = 1 -- not used + if i <= rows and j <= columns then + local c = copy(t) + remove(c,i) + for k=1,rows-1 do + remove(c[k],j) + end + return c + else + return "error: out of bound" + end +end + +matrix.submatrix = submatrix + +-- calculating determinant using Laplace Expansion + +function matrix.laplace(t) -- not sure if this is the most effient but + local factors = { 1 } -- it's not used for number crunching anyway + local data = copy(t) + local det = 0 + while #data > 0 do + local mat = { } + local siz = #data[1] + if siz == 0 then + return "error: no determinant" + elseif siz == 1 then + det = data[1][1] + return det + end + for i=1,siz do + mat[i] = data[1] + remove(data,1) + end + local factor = remove(factors,1) + local m1 = mat[1] + if siz == 2 then + local m2 = mat[2] + det = det + factor * (m1[1]*m2[2] - m1[2]*m2[1]) + else + for j=1,#m1 do + local m1j = m1[j] + if m1j ~= 0 then + insert(factors, (-1)^(j+1) * factor * m1j) + local m = submatrix(mat,1,j) + for k, v in next, m do + insert(data,v) + end + end + end + end + end + return det +end + -- solve the linear equation m X = c local function solve(m,c) |