I would like to be able to use a generalized numeric Matrix datatype ({ { number } } similar to CFrame but any dimensions, with exponentiation). For my use-case it would be easiest if the Matrix had yielding exponentiate / multiply functions that could compute for longer than the script timeout (also be parallelized?).
In order to calculate certain physical simulations on structures I’ve written a few algorithms that include operations on large numeric matrices, and they’re often slow (10s-2min) run-time for one matrix multiplication operation. I have to disperse many yields in order to avoid the script execution timeout while performing the matrix multiplication loops.
You can already do this through metatables, it seems odd to me that you are doing calculations that require such a long time to compute. Can you elaborate on your use case? Also I recommend looking into this lua-matrix/matrix.lua at master · davidm/lua-matrix · GitHub
My current solution is a matrix class similar to the one linked, it becomes slow to multiply matrices with higher dimensions than 250x250 for me (~0.3 seconds), at 1000x1000 it starts to error due to script execution timeout exhaustion, with yields added to avoid this it takes ~16sec.
I’m using big matrices to progress a physics-related simulation to determine structural integrity of complex structures of parts and even the 0.3 multiplication time per 250x250 slows my algorithm considerably as it is per-step and causes a lag spike.
This post explains the optimizations I’m seeking with this object (1000x1000 in ~1sec / 16x faster):
I’m interested in solutions for the timeouts but I meant that I get around the timeout problem already by introducing wait()s throughout the calculation, which results in the slower times for the larger matrices, or larger lagspikes.
export type Matrix = { { number } }
local function yieldingMultiply(matrix1: Matrix, matrix2: Matrix, delayFrequency: number?): Matrix
local shapeRows = #matrix1
local shapeColumns = #matrix2[1]
local result = table.create(shapeRows)
for i = 1, shapeRows do
result[i] = table.create(shapeColumns)
for j = 1, shapeColumns do
local sum = 0
for k = 1, shapeColumns do
sum = sum + matrix1[i][k] * matrix2[k][j]
end
result[i][j] = sum
end
if delayFrequency and i % delayFrequency == 0 then
task.wait(0)
end
end
return result
end
-- n = 250 ~ 0.3sec
-- n = 1000 ~ 16sec
local n = 1000
local mat = table.create(n)
for i = 1, n do
local t = {}
for k = 1, n do
t[k] = math.random()
end
table.freeze(t)
mat[i] = t
end
table.freeze(mat)
local startTime = os.clock()
-- Change this to 100 to avoid script timeout
local yieldFrequency = nil -- 100
local result = yieldingMultiply(mat, mat, yieldFrequency)
print("Multiplied in " .. os.clock() - startTime)