Lua Linear provides comprehensive linear algebra and statistics support for the Lua programming language. Where applicable, the BLAS and LAPACK implementations on the system are used.
Here are some quick examples.
local linear = require("linear")
-- Calculate an inner product
local x = linear.tolinear({ 1, 2, 3 })
local y = linear.tolinear({ 3, 2, 1 })
print("x^T y", linear.dot(x, y)) -- should be 10
x^T y 10.0
-- Generate and analyze normally distributed random numbers with mean 10, std 5, i.e., N(10,5)
local x = linear.vector(100)
linear.normal(x) -- N(0,1)
linear.scal(x, 5) -- N(0,5)
linear.inc(x, 10) -- N(10,5)
print("N(10,5)", x[1], x[2], x[3], "...")
print("mean, std", linear.mean(x), linear.std(x, 1)) -- should approximate 10, 5
N(10,5) 7.6755368439453 11.817516987964 11.047801936107 ...
mean, std 9.6617642376046 4.8338730760376
-- Solve a system of linear equations: x + 2y = 7, 2x - y = 9
local A = linear.tolinear({ { 1, 2 }, { 2, -1 } })
local B = linear.matrix(2, 1)
local b = linear.tvector(B, 1) -- column vector
b[1], b[2] = 7, 9
linear.gesv(A, B)
print("solutions", b[1], b[2]) -- should be 5, 1
solutions 5.0 1.0
-- Calculate pairwise Pearson correlation coefficients of 10k uniform random numbers
local A = linear.matrix(10000, 3)
linear.uniform(A)
local C = linear.matrix(3, 3)
linear.corr(A, C)
print("correlations", C[1][2], C[1][3], C[2][3]) -- should be close to zero
correlations -0.0026144290886127 0.0063412466674457 -0.004072920697946
-- Approximate the normal distribution through percentiles, and compare with its CDF
local x = linear.vector(100000)
linear.normal(x) -- 100k random variables from N(0,1)
local percentiles = linear.vector(101) -- use 101 sample percentiles
linear.ranks(100, percentiles, "zq") -- set percentile ranks, i.e., [0.00, 0.01, ..., 0.99, 1.00]
linear.quantile(x, percentiles) -- calculate the actual sample percentiles
local r = linear.vector(#x)
linear.copy(x, r) -- copy values of x to r
linear.rank(percentiles, r) -- calculate the rank of each value of x
for i = 1, 3 do
local rank = r[i] -- rank within percentiles should approximate CDF
local cdf = linear.normalcdf(x[i]) -- actual CDF
print("cdf", x[i], rank, cdf, rank - cdf) -- difference should be close to 0
end
cdf -1.7726983852418 0.039258615499493 0.038139349413071 0.0011192660864221
cdf -0.90382210127255 0.18323948061584 0.18304487023318 0.00019461038265881
cdf 0.53756751344972 0.70285856454599 0.70456216834327 -0.0017036037972724
-- Make a cubic spline interpolant of the Runge function, and analyze its mean absolute error
local function runge (x)
return 1 / (1 + 25 * x^2)
end
local x, y = { }, { }
for i = -5, 5 do
table.insert(x, i / 5)
table.insert(y, runge(i / 5))
end
x, y = linear.tolinear(x), linear.tolinear(y)
local sp = linear.spline(x, y, "not-a-knot")
local d = { }
for i = -100, 100 do
table.insert(d, math.abs(sp(i / 100) - runge(i / 100)))
end
print("mae", "not-a-knot", linear.mean(linear.tolinear(d))) -- should be close to 0
-- As we know the derivative, a clamped spline should be even better
local function rungep (x)
return (-50 * x) / (1 + 25 * x^2)^2
end
sp = linear.spline(x, y, "clamped", nil, rungep(-1), rungep(1))
d = { }
for i = -100, 100 do
table.insert(d, math.abs(sp(i / 100) - runge(i / 100)))
end
print("mae", "clamped", linear.mean(linear.tolinear(d))) -- should be closer to 0
mae not-a-knot 0.0042786643621508
mae clamped 0.004061824568681
You may need to install the following packages to build Lua Linear:
- libopenblas-dev
- liblapacke-dev
To build and install with LuaRocks, run:
luarocks install lua-linear
Lua Linear comes with a simple Makefile. Please adapt the Makefile to your environment, and then run:
make
make test
make install
Please see the release notes document.
Please browse the documentation folder for the extensive documentation.
Lua Linear supports Lua 5.1, Lua 5.2, Lua 5.3, and Lua 5.4.
Lua Linear has been built and tested on Ubuntu Linux (64-bit).
Lua Linear uses the BLAS and LAPACK implementations on the system.
Lua Linear is released under the MIT license. See LICENSE for license terms.