Lua - Numerical Algorithms released

10 Sep 2013

I am happy to announce a new project: lna (Lua Numerical Algorithms). lna is a Lua library that provides support for matrices, linear algebra, complex numbers, optimization algorithms, ODE solver, PCA / LDA, FFT, and other numerical algorithms for Lua.

The objective is to incentive scientific computing in Lua. It does not (yet) compares to numpy/scipy for Python, but already provides the essentials (such as efficient linear algebra operations).

Linear algebra operations such as computing the eigenvalues/vectors, matrix inversion, solving a linear system, among others, are done with lapack, while other algorithms are implemented in Lua itself.

Strictly speaking, lna it is not a Lua library, but a pure LuaJIT library since it depends on LuaJIT FFI to use lapack routines. Due to LuaJIT, the operations that are performed in Lua are roughly as fast as the ones implemented in native code. One does not need to vectorize its implementation to achieve good performance, i.e., unlike Python+numpy, you can actually loop element-by-element of a matrix and still achieve good performance.

lna is licensed under the same license as Lua (MIT) and has been implemented primary with correctness in mind (then performance and easy of use). In the git repository you will find a test suit, examples, and complete documentation of the library.

lna is still a very young project, so it may contain bugs. Every contribution (patch, ideas, bug report) is welcome.

Code samples

Solving a linear system

local matrix = require('lna.matrix')

local A = matrix.fromtable{
    { 1,  1, 1},
    { 3, -1, 2},
    {-1, -1, 4},
}
local b = matrix.fromtable{6,7,9} -- column vector

-- error estimates are computed, but they are ignores in this example
local x =  matrix.solve(A,b)
print(x)

Fourier analysis

 -- for quick tests, import everything to the global table
require('lna.lab')
local sin, w = matrix.sin, math.pi*2

-- sampled 2 seconds of a signal, with a 100Hz sampling rate
local t = matrix.linspace(0,2,200)

-- the signal has components in 15, 25 and 40Hz
local x = sin(w*15*t) + 3*sin(w*25*t) + 2*sin(w*40*t)

-- add some noise
x = x + 0.2*matrix.rand(t.m, t.n)

-- perform the transform
local X = fft.shift( fft.fft(x) )

-- plot
local f = matrix.linspace(-50, 49.5, 200)
plot(t, x)
plot(f, X:abs() )
plot(f, fft.unwrap(X:arg()) )

Related projects

gsl-shell provides a very nice environment for scientific coding in Lua. numlua also provides matrices, linear algebra, complex number support and FFT operations for Lua.