mirror of
https://github.com/IgorTimofeev/MineOS.git
synced 2025-12-20 11:09:21 +01:00
223 lines
5.8 KiB
Lua
223 lines
5.8 KiB
Lua
|
|
local matrixLibrary = {}
|
|
|
|
---------------------------------------------------- Matrix tables creation ----------------------------------------------------------------
|
|
|
|
function matrixLibrary.newIdentityMatrix(size)
|
|
local matrix = {}
|
|
|
|
for y = 1, size do
|
|
matrix[y] = {}
|
|
for x = 1, size do
|
|
matrix[y][x] = (x == y) and 1 or 0
|
|
end
|
|
end
|
|
|
|
return matrix
|
|
end
|
|
|
|
function matrixLibrary.newCofactorMatrix(matrix)
|
|
local cofactorMatrix = {}
|
|
for y = 1, #matrix do
|
|
cofactorMatrix[y] = {}
|
|
for x = 1, #matrix[y] do
|
|
cofactorMatrix[y][x] = matrixLibrary.getCofactor(matrix, y, x)
|
|
end
|
|
end
|
|
|
|
return cofactorMatrix
|
|
end
|
|
|
|
function matrixLibrary.newAdjugateMatrix(matrix)
|
|
return matrixLibrary.transpose(matrixLibrary.newCofactorMatrix(matrix))
|
|
end
|
|
|
|
function matrixLibrary.newFilledMatrix(width, height, value)
|
|
local matrix = {}
|
|
|
|
for y = 1, height do
|
|
matrix[y] = {}
|
|
for x = 1, width do
|
|
matrix[y][x] = value
|
|
end
|
|
end
|
|
|
|
return matrix
|
|
end
|
|
|
|
function matrixLibrary.copy(matrix)
|
|
local newMatrix = {}
|
|
|
|
for y = 1, #matrix do
|
|
newMatrix[y] = {}
|
|
for x = 1, #matrix[y] do
|
|
newMatrix[y][x] = matrix[y][x]
|
|
end
|
|
end
|
|
|
|
return newMatrix
|
|
end
|
|
|
|
function matrixLibrary.print(matrix)
|
|
print("Matrix size: " .. #matrix .. "x" .. #matrix[1])
|
|
for y = 1, #matrix do
|
|
for x = 1, #matrix[y] do
|
|
io.write(tostring((not matrix[y]) and "nil" or matrix[y][x]))
|
|
io.write(' ')
|
|
end
|
|
print("")
|
|
end
|
|
|
|
return matrix
|
|
end
|
|
|
|
---------------------------------------------------- Matrix arithmetic operations ----------------------------------------------------------------
|
|
|
|
function matrixLibrary.multiply(matrix, data)
|
|
local dataType = type(data)
|
|
if dataType == "table" then
|
|
if (#matrix[1] ~= #data) then error("Couldn't multiply matrixes AxB: A[columns] ~= B[rows]") end
|
|
|
|
local result = {}
|
|
for i = 1, #matrix do
|
|
result[i] = {}
|
|
for j = 1, #data[1] do
|
|
local resultElement = 0
|
|
for k = 1, #matrix[1] do
|
|
resultElement = resultElement + (matrix[i][k] * data[k][j])
|
|
end
|
|
result[i][j] = resultElement
|
|
end
|
|
end
|
|
|
|
return result
|
|
elseif dataType == "number" then
|
|
for y = 1, #matrix do
|
|
for x = 1, #matrix[y] do
|
|
matrix[y][x] = matrix[y][x] * data
|
|
end
|
|
end
|
|
|
|
return matrix
|
|
else
|
|
error("Unsupported operation data type: " .. tostring(dataType))
|
|
end
|
|
end
|
|
|
|
function matrixLibrary.divide(matrix, data)
|
|
local dataType = type(data)
|
|
if dataType == "table" then
|
|
error("Matrix by matrix division doesn't supported yet")
|
|
elseif dataType == "number" then
|
|
for y = 1, #matrix do
|
|
for x = 1, #matrix[y] do
|
|
matrix[y][x] = matrix[y][x] / data
|
|
end
|
|
end
|
|
|
|
return matrix
|
|
else
|
|
error("Unsupported operation data type: " .. tostring(dataType))
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------- Matrix resizing methods ----------------------------------------------------------------
|
|
|
|
function matrixLibrary.addRow(matrix, row)
|
|
if (#matrix[1] ~= #row) then error("Insertion row size doesn't match matrix row size: " .. #row .. " vs " .. #matrix[1]) end
|
|
|
|
table.insert(matrix, row)
|
|
|
|
return matrix
|
|
end
|
|
|
|
function matrixLibrary.addColumn(matrix, column)
|
|
if (#matrix ~= #column ) then error("Insertion column size doesn't match matrix column size: " .. #column .. " vs " .. #matrix) end
|
|
|
|
for y = 1, #column do
|
|
table.insert(matrix[y], column[y])
|
|
end
|
|
|
|
return matrix
|
|
end
|
|
|
|
function matrixLibrary.removeRow(matrix, row)
|
|
if row > #matrix then error("Can't remove row that is bigger then matrix height") end
|
|
|
|
table.remove(matrix, row)
|
|
|
|
return matrix
|
|
end
|
|
|
|
function matrixLibrary.removeColumn(matrix, column)
|
|
if column > #matrix[1] then error("Can't remove column that is bigger then matrix width") end
|
|
|
|
for y = 1, #matrix do
|
|
table.remove(matrix[y], column)
|
|
end
|
|
|
|
return matrix
|
|
end
|
|
|
|
---------------------------------------------------- Matrix advanced manipulation methods ----------------------------------------------------------------
|
|
|
|
function matrixLibrary.transpose(matrix)
|
|
local transposedMatrix = {}
|
|
for x = 1, #matrix[1] do
|
|
transposedMatrix[x] = {}
|
|
for y = 1, #matrix do
|
|
transposedMatrix[x][y] = matrix[y][x]
|
|
end
|
|
end
|
|
return transposedMatrix
|
|
end
|
|
|
|
function matrixLibrary.getMinor(matrix, row, column)
|
|
return matrixLibrary.getDeterminant(matrixLibrary.removeColumn(matrixLibrary.removeRow(matrixLibrary.copy(matrix), row), column))
|
|
end
|
|
|
|
function matrixLibrary.getCofactor(matrix, row, column)
|
|
return (-1) ^ (row + column) * matrixLibrary.getMinor(matrix, row, column)
|
|
end
|
|
|
|
function matrixLibrary.getDeterminant(matrix)
|
|
local matrixSize = #matrix
|
|
if matrixSize ~= #matrix[1] then error("Can't find determinant for matrix, row count != column count: " .. #matrix .. "x" .. #matrix[1]) end
|
|
|
|
if matrixSize == 1 then
|
|
return matrix[1][1]
|
|
elseif matrixSize == 2 then
|
|
return matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1]
|
|
else
|
|
local determinant = 0
|
|
for j = 1, matrixSize do
|
|
determinant = determinant + matrixLibrary.getCofactor(matrix, 1, j) * matrix[1][j]
|
|
end
|
|
|
|
return determinant
|
|
end
|
|
end
|
|
|
|
function matrixLibrary.invert(matrix)
|
|
local determinant = matrixLibrary.getDeterminant(matrix)
|
|
if determinant == 0 then error("Can't invert matrix with determinant equals 0") end
|
|
|
|
return matrixLibrary.divide(matrixLibrary.newAdjugateMatrix(matrix), determinant)
|
|
end
|
|
|
|
------------------------------------------------------------------------------------------------------------------------
|
|
|
|
-- local m = {
|
|
-- {2, 5, 4},
|
|
-- {-5, 5, 6},
|
|
-- {1, 3, 7},
|
|
-- }
|
|
-- matrixLibrary.print(m)
|
|
-- m = matrixLibrary.invert(m)
|
|
-- matrixLibrary.print(m)
|
|
|
|
------------------------------------------------------------------------------------------------------------------------
|
|
|
|
return matrixLibrary
|
|
|