在Lua中计算行列式

时间:2018-10-27 12:23:33

标签: math lua lua-table

我正在尝试使用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的行列式时。

0 个答案:

没有答案