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.

10 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