From the same group that brought to you the Lua Statistics library, my open-source organization, Bytebit (Roblox group) has just made the new Lua Linear Algebra library!
This library is far from complete, but it currently features a wealth of matrix and vector functions. For those of you who have used Python before, the syntax in this library often resembles that of numpy. It uses its own immutable matrix data structure which works similarly to a 2D array of size (m x n)
. Vectors are implemented by just using (n x 1)
matrix objects. All functions are annotated with RoDocs comments.
Matrices store things in A[row][column]
orientation.
To access the dimensions of a matrix, use A.Shape
, which will be a table like so: { [1] = m, [2] = n }
.
All the arithmetic operators (+, - including the unary operator, *, /, %, and ^) are implemented for matrices and individual rows as expected (at least when using scalars).
This library is open-source! Please send in pull requests, I will gladly review them and hopefully add them in!
Upcoming goals
I am hoping to implement a sparse matrix data structure so as to increase performance. I also want to implement an SVD function (that would take advantage of the sparse matrix data structure when available). I would also like to implement a way to easily sync this into a Roblox game so that people don’t have to copy-paste the script into their games, which I’d like to accomplish using @Osyris’s RbxRefresh or a similar syncing tool.
Examples
matrix transpose
local mat = linalg.matrix.new({
{ 1, 2 },
{ 3, 4 }
})
print(mat.T)
Output:
1 3
2 4
vector + vector
local v1 = linalg.vector.new({ 1, 2 })
local v2 = linalg.vector.new({ 2, 1 })
print(v1 + v2)
Output:
3
3
vector * scalar
local v = linalg.vector.new({ 1, 2 })
print(v * 3)
Output:
3
6
vector norms
local v = linalg.vector.new({ 1, 2 })
print("L1 norm: " .. tostring(linalg.vector.norm.l1(v)))
print("L2 norm: " .. tostring(linalg.vector.norm.l2(v)))
print("L-infinity norm: " .. tostring(linalg.vector.norm.linf(v)))
Output:
L1 norm: 3
L2 norm: 51/2 (it’ll actually say a decimal number of the same value)
L-infinity norm: 2
inner products
local v1 = linalg.vector.new({ 1, 2 })
local v2 = linalg.vector.new({ 2, 1 })
print(linalg.vector.ip.dot(v1, v2))
Output:
4
vector projection
local v = linalg.vector.new({ 1, 2 })
local e1 = linalg.vector.e(1, 2)
print(v.project(e1))
Output:
1
0
Gram-Schmidt vector space creation
local e1 = linalg.vector.e(1, 2)
print(unpack(linalg.gramSchmidt(e1)))
Output:
1
0
0
1