Расчет определителя в Lua - PullRequest
       12

Расчет определителя в Lua

0 голосов
/ 27 октября 2018

Я пытаюсь вычислить детерминанты с любым порядком, используя Lua.Я могу вычислить детерминанты для порядка меньше 4, но не для значений больше 4.У меня есть матрица 4x4, и ее определитель с программой равен 0, но реальное решение - 56. Я не знаю, заключается ли проблема в методе getSubmatrix или в методе detMat , потому что у меня нет сообщения об ошибке из консоли.Я перенес методы из моего собственного кода Java, где он работает нормально.Вот весь мой код:

function numMat(n, A)
    local S = {}
    for i = 1, #A, 1 do
        local T = {}
        S[i] = T
        for j =1, #A[1], 1 do
            T[j] = n * A[i][j]
        end
    end
    return S
end

function sumMat(A, B)
    local C = {}
    for i = 1, #A do
        local D = {}
        C[i] = D
        for j = 1, #A[1] do
            D[j] = A[i][j] + B[i][j]
        end
    end
    return C
end

function subMat(A, B)
    return sumMat(A, numMat(-1, B))
end

function printMatrix(A)
    for i, v in ipairs(A) do
        for j, w in ipairs(v) do
            print(w)
        end
    end
end

function escalarProduct(u, v)
    local w = 0
    for i = 1, #u do
        w = w + u[i] * v[i]
    end
    return w
end

function prodMat(A, B)
    local C = {}
    for i = 1, #A do
        C[i] = {}
        for j = 1, #B[1] do
            local num = A[i][1] * B[1][j]
            for k = 2, #A[1] do
                num = num + A[i][k] * B[k][j]
            end
            C[i][j] = num
        end
    end
    return C
end

function powMat(A, power)
    local B = {}
    local C = {}
    C = A
    for i = 1, power - 1 do
        B = prodMat(C, A)
        C = B
    end
    return B
end

function trasposeMat(A)
    local B = {}
    for i = 1, #A do
        local C = {}
        B[i] = C
        for j = 1, #A[1] do
            C[j] = A[j][i]
        end
    end
    return B
end

function productDiag(m)
    local prod = 1
    for i = 1, #m do
        for j = 1, #m do
            if i == j then prod = prod * m[i][i] end
        end
    end
    return prod
end

function isDiagonal(A)
    for i = 1, #A do
        for j = 1, #A do
            if i ~= j and A[i][j] ~= 0 then return false end
        end
    end
    return true
end

function isTriangSup(m)
    for i = 1, #m do
        for j = 1, i do
            if m[i][j] == 0 then return true end
        end
    end
    return false
end

function isTriangInf(m)
    return isTriangSup(trasposeMat(m))
end

function isTriang(m)
    if(isTriangSup(m)) then return true
    else
        return false
    end
end

function getSubmatrix(A, rows, cols, col)
    local submatrix = {}
    local k = 1

    for j = 1, cols do
        --local D = {}
        --submatrix[j] = D
        if j == col then
            break
        end
        for i = 2, rows do
            submatrix[i-1][k] = A[i][j]
            --D[k] = A[i][j]
        end
        k = k + 1
    end
    return submatrix
end

function det2Mat(A)
    assert(#A == 2 and #A == #A[1], 'Error: The matrix must be squared, order 2.')
    return A[1][1] * A[2][2] - A[1][2] * A[2][1]
end

function det3Mat(A)
    assert(#A == 3 and #A == #A[1], 'Error: The matrix must be squared, order 3.')
    s1 = A[1][1] * A[2][2] * A[3][3] + A[2][1] * A[3][2] * A[1][3] + A[1][2] * A[2][3] * A[3][1]
    s2 = A[1][3] * A[2][2] * A[3][1] + A[1][2] * A[2][1] * A[3][3] + A[2][3] * A[3][2] * A[1][1]
    return s1 - s2
end

function detMat(A)
    local submatrix = {}
    local det
    local sign = 1
    local rows = #A
    local cols = #A[1]

    assert(rows == cols, 'Error: The matrix must be squared.')
    if rows == 1 then
        return A[1][1]
    end
    if rows == 2 then
        return det2Mat(A)
    end
    if rows == 3 then
        return det3Mat(A)
    end

    if isDiagonal(A) or isTriang(A) then return productDiag(A) end
    if rows > 3 then
        for column = 1, cols do
            submatrix = getSubmatrix(A, rows, cols, column)
            det = det + sign * A[1][column] * detMat(submatrix)
            sign = -sign
        end
    end
    return det
end

A = {{1, 3}, {5, 6}}
B = {{2, 4}, {3, 1}}
C = {{2, 3, 4}, {-5, 4, 7}, {7, 1, 0}}
D = {{2, 0, 0, 0}, {0, 4, 0, 0}, {0, 0, 7, 0}, {0, 0, 0, 6}}
E = {{2, 3, 4, -3}, {-5, 4, 7, -2}, {7, 1, 0, 5}, {3, 4, 5, 6}}

--printMatrix(numMat(-1, A))
--printMatrix(sumMat(A, B))
--printMatrix(subMat(A, B))
--print(escalarProduct({1, 3}, {5, 6}))
--printMatrix(prodMat(A, B))
--printMatrix(trasposeMat(A))
--printMatrix(powMat(A, 2))
--printMatrix(powMat(A, 3))

print(detMat(A))
print(detMat(B))
print(detMat(C))
print(detMat(D))
print(detMat(E)) --The solution must be 56

И консольное решение:

-9 -10 1 336 0

Ошибка, когда яхочу узнать определитель матрицы E.

...