Add Matrix Data Type

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.

This could also be useful for ML experiments.

9 Likes

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

image
image

1 Like

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):

2 Likes

We should talk about this more, I’m willing to fix the timeout problem!

1 Like

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.

1 Like

I wonder if there’s some data science we can do to make bigger calculations!!

I see, could you provide your current implementation?

1 Like

Can you submit a script with this computation, for us to use as a benchmark?

1 Like
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)

1 Like