diff options
Diffstat (limited to 'macros/latex/contrib/tkz/tkz-elements/latex/tkz_elements_functions_matrices.lua')
-rw-r--r-- | macros/latex/contrib/tkz/tkz-elements/latex/tkz_elements_functions_matrices.lua | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/macros/latex/contrib/tkz/tkz-elements/latex/tkz_elements_functions_matrices.lua b/macros/latex/contrib/tkz/tkz-elements/latex/tkz_elements_functions_matrices.lua new file mode 100644 index 0000000000..7d3f475570 --- /dev/null +++ b/macros/latex/contrib/tkz/tkz-elements/latex/tkz_elements_functions_matrices.lua @@ -0,0 +1,374 @@ +-- tkz_elements_functions_matrices.lua +-- date 2024/03/25 +-- version 2.20c +-- Copyright 2024 Alain Matthes +-- This work may be distributed and/or modified under the +-- conditions of the LaTeX Project Public License, either version 1.3 +-- of this license or (at your option) any later version. +-- The latest version of this license is in +-- http://www.latex-project.org/lppl.txt +-- and version 1.3 or later is part of all distributions of LaTeX +-- version 2005/12/01 or later. +-- This work has the LPPL maintenance status “maintained”. +-- The Current Maintainer of this work is Alain Matthes. + +-- ---------------------------------------------------------------------------- +function print_matrix(m,mstyle) + local mstyle = (mstyle or 'bmatrix') + local m = (m.type=='matrix' and m.set or m) + tex.sprint("$") + tex.sprint("\\begin{"..mstyle.."}") + for i = 1, #m do + for j = 1, #m[1] do + local x = m[i][j] + local st = display(x) + tex.sprint(st) + if j < #m[1] then tex.sprint(" & ") end + end + tex.sprint("\\\\") + end + tex.sprint("\\end{"..mstyle.."}") + tex.sprint("$") +end + +function print_array(matrix) +local mdata = (matrix.type=='matrix' and matrix.set or matrix) +tex.sprint("\\{%") + for i = 1, #mdata do + local row = mdata[i] + local row_str = "{\\{" + for j = 1, #row do + row_str = row_str .. " " .. tostring(row[j]) + if j < #row then + row_str = row_str .. " ," + end + end + if (i~=#mdata) and (j~=#row) then + if i>1 then row_str = row_str .. " \\}}," else row_str = row_str .. " \\}}," end + tex.sprint(row_str) +else + if i>1 then row_str = row_str .. " \\}}" else row_str = row_str .. " \\}}" end + tex.sprint(row_str) + end +end +tex.sprint("\\}") +end + +function mul_matrix(A, B) +local adata = (A.type=='matrix' and A.set or A) +local bdata = (B.type=='matrix' and B.set or B) +local C = {} + for i = 1, #adata do + C[i] = {} + for j = 1, #bdata[1] do + local num = adata[i][1] * bdata[1][j] + for k = 2, #adata[1] do + num = num + adata[i][k] * bdata[k][j] + end + C[i][j] = num + end + end + return matrix : new (C) +end + + +function add_matrix(A, B) +local adata = (A.type=='matrix' and A.set or A) +local bdata = (B.type=='matrix' and B.set or B) + local S = {} + for i = 1, #adata do + local T = {} + S[i] = T + for j = 1, #adata[1] do + T[j] = adata[i][j] + bdata[i][j] + end + end + return matrix : new (S) +end + +function k_mul_matrix(n, A) +local adata = (A.type=='matrix' and A.set or A) + local S = {} + for i = 1, #adata, 1 do + local T = {} + S[i] = T + for j =1, #adata[1], 1 do + T[j] = n * adata[i][j] + end + end + return matrix : new (S) +end + + +function transposeMatrix(A) +local mdata = (A.type=='matrix' and A.set or A) + local transposedMatrix = {} + for i = 1, #mdata[1] do + transposedMatrix[i] = {} + for j = 1, #mdata do + transposedMatrix[i][j] = mdata[j][i] + end + end + return matrix : new (transposedMatrix) +end + +-- Function to calculate the determinant of a square matrix +function determinant(A) + local matrix = (A.type=='matrix' and A.set or A) + if #matrix == #matrix[1] then + local n = #matrix + if n == 1 then + return matrix[1][1] -- Base case for 1x1 matrix + elseif n == 2 then + return matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1] -- Base case for 2x2 matrix + else + local det = 0 + for j = 1, n do + local minor = {} + for i = 2, n do + minor[i - 1] = {} + for k = 1, n do + if k ~= j then + minor[i - 1][#minor[i - 1] + 1] = matrix[i][k] + end + end + end + det = det + ((-1)^(j + 1)) * matrix[1][j] * determinant(minor) -- Recursive call for larger matrices + end + return det + end + else return nil end +end + +function check_square_matrix (A) + local matrix = (A.type=='matrix' and A.set or A) + if #matrix == #matrix[1] + then + return true + else + return false + end +end + + +function id_matrix (n) + local identityMatrix = {} + for i = 1, n do + identityMatrix[i] = {} + for j = 1, n do + if i == j then + identityMatrix[i][j] = 1 + else + identityMatrix[i][j] = 0 + end + end + end + return matrix : new (identityMatrix) +end + +function inverse_2x2(A) + local m = (A.type=='matrix' and A.set or A) + local a, b, c, d = m[1][1], m[1][2], m[2][1], m[2][2] + local D = A.det + if D == 0 then + return nil -- La matrice n'est pas inversible + else + local inv ={} + inv[1]={} + inv[1][1] = d / D + inv[1][2] = -b / D + inv[2]={} + inv[2][1] = -c / D + inv[2][2] = a / D + return matrix : new (inv) + end +end + +function adjugate_(A) + local m = (A.type=='matrix' and A.set or A) + if #m == 2 then + local a,b,c,d = m[2][2],-m[1][2],- m[2][1],m[1][1] + return matrix : new ({{a,b},{c,d}}) + elseif #m == 3 then + local a, b, c = m[1][1], m[1][2], m[1][3] + local d, e, f = m[2][1], m[2][2], m[2][3] + local g, h, i = m[3][1], m[3][2], m[3][3] + return transposeMatrix(matrix : new ({ + {e * i - f * h, -(d * i - f * g), d * h - e * g}, + {-(b * i - c * h), a * i - c * g, -(a * h - b * g)}, + {b * f - c * e, -(a * f - c * d), a * e - b * d} + })) + else return nil + end +end + +function inverse_3x3(A) + local D = A.det + if D == 0 then + return nil -- La matrice n'est pas inversible + else + local adj = adjugate_(A) + local m = (adj.type=='matrix' and adj.set or adj) + local inv = {} + for i = 1, 3 do + inv[i] = {} + for j = 1, 3 do + inv[i][j] = m[i][j] / D + end + end + return matrix : new (inv) + end +end + +-- inverse only for 2x2 or 3x3 matrix +function inv_matrix (A) + if A.det ==0 then tex.print("Matrix not inversible: det = 0") return nil + else + local M = (A.type=='matrix' and A.set or A) + local n = #M + if n == 2 then + local m = (A.type=='matrix' and A.set or A) + local a, b, c, d = m[1][1], m[1][2], m[2][1], m[2][2] + local D = A.det + local inv ={} + inv[1]={} + inv[1][1] = d / D + inv[1][2] = -b / D + inv[2]={} + inv[2][1] = -c / D + inv[2][2] = a / D + return matrix : new (inv) + else + local D = A.det + local adj = adjugate_(A) + local m = (adj.type=='matrix' and adj.set or adj) + local inv = {} + for i = 1, 3 do + inv[i] = {} + for j = 1, 3 do + inv[i][j] = m[i][j] / D + end + end + return matrix : new (inv) + end + end +end + +function diagonalize_ (A) + local m = (A.type=='matrix' and A.set or A) + local trace = m[1][1] + m[2][2] + local a,b = m[1][1],m[1][2] + local det = A.det + local D = trace * trace - 4 * det + if D > 0 then + local va1 = (trace + math.sqrt(D)) / 2 + local va2 = (trace - math.sqrt(D)) / 2 + return matrix : new ({{va1,0},{0,va2}}), + matrix : new ({{1,1},{ (va1 - a )/b, (va2 - a)/b}}) + else + local va1 = point (trace/2 , math.sqrt(-D)/ 2) + local va2 = point (trace/2 , - math.sqrt(-D)/ 2) + return matrix : new ({{va1,0},{0,va2}})--, + -- matrix : new ({{1,1},{ (va1 - a )/b, (va2 - a)/b}}) + end + end + + function isDiagonal_(A) + local matrix = (A.type=='matrix' and A.set or A) + if check_square_matrix (A) == true + then + for i = 1, #matrix do + for j = 1, #matrix[1] do + if i ~= j and matrix[i][j] ~= 0 then + return false + end + end + end + return true + else + return false + end + end + + function isOrthogonal_(A) + local m = (A.type=='matrix' and A.set or A) + if (check_square_matrix (A) == true) and (A.det ~=0) + then + local mT = transposeMatrix (A) + local mI = inv_matrix (A) + if mT == mI then return true else return false end + else + return false + end + end + + + function homogenization_ (A) + local m = (A.type=='matrix' and A.set or A) + if A.cols ~= 1 then + return nil + else + local a,b,c + a=m[1][1] + b=m[2][1] + c= 1 + return matrix : new ({{a},{b},{c}}) + end + end + + function get_element_( A,i,j ) + local m = (A.type=='matrix' and A.set or A) + if m[i] and m[i][j] then + return m[i][j] + end + end + + function get_htm_point(A) + local m = (A.type=='matrix' and A.set or A) + return point : new( m[1][1],m[2][1]) + end + + function htm_apply_ (A,z) + local V = homogenization_ ( 1/scale*z.mtx) + local W = A * V + return get_htm_point(W) + end + + function htm_apply_L_ (A,obj) + local x,y + x = htm_apply_ (A,obj.pa) + y = htm_apply_ (A,obj.pb) + return line : new (x,y) + end + + function htm_apply_C_ (A,obj) + local x,y + x = htm_apply_ (A,obj.center) + y = htm_apply_ (A,obj.through) + return circle : new (x,y) + end + + function htm_apply_T_ (A,obj) + local x,y,z + x = htm_apply_ (A,obj.pa) + y = htm_apply_ (A,obj.pb) + z = htm_apply_ (A,obj.pc) + return triangle : new (x,y,z) + end + + function htm_apply_Q_ (A,obj) + local x,y,z,t + x = htm_apply_ (A,obj.pa) + y = htm_apply_ (A,obj.pb) + z = htm_apply_ (A,obj.pc) + t = htm_apply_ (A,obj.pd) + if obj.type == "square" then + return square : new (x,y,z,t) + elseif obj.type == "rectangle" then + return rectangle : new (x,y,z,t) + elseif obj.type == "parallelogram" then + return parallelogram : new (x,y,z,t) + elseif obj.type == "quadrilateral" then + return quadrilateral : new (x,y,z,t) + end + end
\ No newline at end of file |