This week MartÃn started a project for implementing linear algebra routines in Crystal by binding to LAPACK, a de-facto standard library for such operations. You can check out the project in github at mverzilli/crystalla, as in Crystal Linear Algebra.
The project makes use of Crystal's simple C bindings to leverage LAPACK power. The first operation implemented for testing was computing the inverse of a matrix, which first computes de LU decomposition of the matrix and then calculates the inverse from there.
A simple benchmark shows that the implementation works quite fast with a 10000 x 10000 float random matrix, taking less than 40 seconds:
require "benchmark"
require "./src/crystalla"
cols = [] of Array(Float64)
range = 10000
r = Random.new
(1..range).each do |i|
row = [] of Float64
(1..range).each do |j|
row.push r.next_float
end
cols.push row
end
m = Crystalla::Matrix.columns cols
m.invert!
We decided to contrast this against numpy, a widely-used python package for numeric operations, which also leverages LAPACK for linear algebra.
import numpy
SIZE = 10000
m = numpy.random.rand(SIZE, SIZE)
numpy.linalg.inv(m)
A time
on this script yields one order of magnitude higher than Crystal:
real 3m38.331s
user 3m36.148s
sys 0m1.817s
We expect to continue adding basic functionality to crystalla over the following weeks. Feel free to contribute with your own additions!