[racket] math/matrix

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Sun May 11 05:23:17 EDT 2014

2014-05-11 6:09 GMT+02:00 Eduardo Costa <edu500ac at gmail.com>:
> The documentation says that one should expect typed/racket to be faster than
> racket. I tested the math/matrix library and it seems to be almost as slow
> in typed/racket as in racket.

What was (is?) slow was a call in an untyped module A to a function exported
from a typed module B. The functions in B must check at runtime that
the values coming from A are of the correct type. If the A was written
in Typed Racket, the types would be known at compile time.

Here math/matrix is written in Typed Racket, so if you are writing an
untyped module, you will in general want to minimize the use of,say,
maxtrix-ref. Instead operations that works on entire matrices or
row/columns are preferred.

> (: sum : Integer Integer -> Flonum)
> (define (sum i n)
>   (let loop ((j 0) (acc 0.0))
>     (if (>= j mx) acc
>         (loop (+ j 1) (+ acc (matrix-ref A i j))) )))
>
> (: b : (Matrix Flonum))
> (define b (build-matrix mx 1 sum))

The matrix b contains the sums of each row in the matrix.
Since matrices are a subset of arrays, you can use array-axis-sum,
which computes sum along a given axis (i.e. a row or a column when
speaking of matrices).

(define A (matrix [[0. 1. 2.]
                   [3. 4. 5.]
                   [6. 7. 8.]]))

> (array-axis-sum A 1)
- : (Array Flonum)
(array #[3.0 12.0 21.0])

However as Eric points out, matrix-solve is an O(n^3) algorithm,
so the majority of the time is spent in matrix-solve.

Apart from finding a way to exploit the relationship between your
matrix A and the column vector b, I see no obvious way of
speeding up the code.

Note that when you benchmark with

   time racket matrix.rkt

you will include startup and compilation time.
Therefore if you want to time the matrix code,
insert a literal (time ...) call.

--
Jens Axel Søgaard


Posted on the users mailing list.