Lua中的矩阵(数组)-交换行并应用行操作



我有这个代码

--[[
Gaussian Elimination in Lua
--]]
-- print matrix
function printmatrix(m)
for r=1,#m do
for c=1,#m[r] do
io.write(m[r][c])
if c < #m[r] then io.write(", ") end
end
print() -- print new line
end
end
-- read matrix in CSV format
function readcsv()
local m = {}
while true do
local line = io.read("l") -- read line not including the end of line character
if line==nil or line=="" then break end -- blank line or bad input ends matrix
local row, index = {}, 0
-- the next line is tricky and goes over all entries in the row
for w in string.gmatch(line,"([^,]*),?") do
local v = tonumber(w) -- convert entry to a number
index = index+1
if v==nil then
row[index] = 0 -- default value if we coudn't read the number
else
row[index] = v -- if number is valid
end
end
m[ #m+1 ] = row
end
return m
end
-- determine the size of m and check it is rectangular
function dim(m)
local rows = #m -- number of rows
local cols = 0  -- number of columns
if rows > 0 then cols = #m[1] end
-- check that matrix is rectangular
for i=2,rows do
if cols ~= #m[i] then error("not rectangular!") end
end
return rows, cols
end
-- if m[r][c] is zero swap row r with some row i>r to make m[r][c] nonzero, if possible
function swap(m,r,c)
local nrows, ncols = dim(m)
if r<=0 or r>nrows or c<=0 or c>ncols then error("position out of range") end
if m[r][c] ~= 0 then
-- nothing to do
return
end
-- find a suitable row
local i=r+1
while i <= nrows do
if m[i][c] ~= 0 then break end
i = i+1
end
if i <= nrows then
-- swap rows i,r
-- DO IT!
end
end
-- if m[r][c] is nonzero apply row operations to make each m[i][c]==0 for i>r
function clear(m,r,c)
local nrows, ncols = dim(m)
if r<=0 or r>nrows or c<=0 or c>ncols then error("position out of range") end
if m[r][c] == 0 then
-- nothing to do
return
end
for i=r+1,nrows do
local f = m[i][c] / m[r][c] do
-- apply row_i = row_i - f*row_r
-- DO IT!**
end
end
end
-- apply Gaussian elimination to m to get it into echelon form
function echelon(m)
local nrows, ncols = dim(m)
local r,c = 1,1 -- current position
while r<=nrows and c<=ncols do
-- try to get a nonzero value at this position
swap(m,r,c)
if m[r][c] == 0 then
-- can't, so move right
c = c+1
else
clear(m,r,c)
-- done, so move diagonally
r = r+1
c = c+1
end
end
end
m = readcsv()
print("original:")
printmatrix(m)
echelon(m)
print("echelon form:")
printmatrix(m)

我希望有人能澄清如何编写代码(Lua中写着--DO IT!,我对此相当陌生,谢谢

在某些情况下,我只是在尝试高斯消去法,试图在这种计算梯次形式的特定方法中使我的工作更快——我并不太在意将1作为第一个非零元素

它应该返回这个

original:
1, 3, 5, 7
2, 1, -1, 0
3, 4, 4, 7
5, 5, 3, 7
echelon form:
1, 3, 5, 7
0, -5, -11, -14
0, 0, 0, 0
0, 0, 0, 0

t.lua:

--[[
Gaussian Elimination in Lua
--]]
-- print matrix
local function printmatrix (m)
for _, row in ipairs (m) do
io.write (table.concat (row, ', ') .. 'n')
end
end
-- read matrix in CSV format
local function readcsv (file)
io.input (file)
local m = {columns = 0, rectangular = true}
for line in io.lines () do
local row = {}
-- the next line is tricky and goes over all entries in the row
for w in line:gmatch '[^,]+' do
row [#row + 1] = tonumber (w) or 0
end
m [#m + 1] = row
-- Update matrix dimensions
m.rectangular = m.rectangular and (#row == m.columns or #m == 1)
m.columns = #row > m.columns and #row or m.columns
end
return m
end
-- if m[r][c] is zero swap row r with some row i>r to make m[r][c] nonzero, if possible
local function swap (m, r, c)
local nrows, ncols = #m, m.columns
if r <= 0 or r > nrows or c <= 0 or c > ncols then error 'Position out of range' end
if m [r] [c] ~= 0 then
-- nothing to do
return
end
-- find a suitable row
local i = r + 1
while i <= nrows and m [i] [c] == 0 do
i = i + 1
end
if i <= nrows then
m [r], m [i] = m [i], m [r]
end
end
-- if m[r][c] is nonzero apply row operations to make each m[i][c]==0 for i>r
local function clear (m, r, c)
local nrows, ncols = #m, m.columns
if r <= 0 or r > nrows or c <= 0 or c > ncols then error 'Position out of range' end
if m [r] [c] == 0 then
-- nothing to do
return
end
for i = r + 1, nrows do
local f = m [i] [c] / m [r] [c]
for j = 1, #m [i] do
m [i] [j] = m [i] [j] - f * m [r] [j]
end
end
end
-- apply Gaussian elimination to m to get it into echelon form
function echelon (m)
local nrows, ncols = #m, m.columns
local r, c = 1, 1 -- current position
while r <= nrows and c <= ncols do
-- try to get a nonzero value at this position
swap (m, r, c)
if m [r] [c] == 0 then
-- can't, so move right
c = c + 1
else
clear (m, r, c)
-- done, so move diagonally
r = r + 1
c = c + 1
end
end
end
local m = readcsv (arg [1])
print 'Original:'
printmatrix (m)
if m.rectangular then
echelon (m)
print 'Echelon form:'
printmatrix (m)
else
error 'Matrix not rectangular!'
end

t.scv:

1,3,5,7 
2,1,-1,0
3,4,4,7 
5,5,3,7

lua t.lua t.csv:

Original:
1, 3, 5, 7
2, 1, -1, 0
3, 4, 4, 7
5, 5, 3, 7
Echelon form:
1, 3, 5, 7
0, -5, -11, -14
0, 0, 0, 0
0, 0, 0, 0

您也可以使用标准输入(lua t.lua;键入值,以Ctrl + D结束(。

  1. 要交换Lua中的任何内容,只需执行a, b = b, a即可
  2. 我对您的第二个doit使用了一种简单的方法(应用row_I=row_I-f*row_r(:for j = 1, #m [i] do m [i] [j] = m [i] [j] - f * m [r] [j] end`
  3. 我使您的代码更加一致和优雅。我还简化了用于解析CSV行的正则表达式
  4. 在输入过程中,我还计算了矩阵的尺寸和矩形度

最新更新