Lisp-Stat has extensive built-in linear algebra capabilities, including matrix inner and outer products, LU decomposition, QR decomposition, Gaussian elimination, Singular Value Decomposition, and more. We will use these tools later when we introduce linear algebra systematically. For now, let us look at a few examples of how matrices are defined and manipulated.

We can make arrays of arbitrary dimensions with the
`make-array`

function:

> (make-array (list 2 3)) #2A((NIL NIL NIL) (NIL NIL NIL)) > (print-matrix *) #2a( (NIL NIL NIL) (NIL NIL NIL) )The

`#2A`

bit says that this is a rank 2 tensor.
The `print-matrix`

function is useful for displaying
matrices in a human-readable form. Unless we tell the
interpreter otherwise, it doesn't initialize the matrix,
so all the elements are `nil`

.
We can fix this with the `initial-element`

keyword:
> (make-array (list 2 3) :initial-element 1) #2A((1 1 1) (1 1 1))We could also use the

`#2A`

form to build an array
directly as:
> '#2a((1 1 1) (1 1 1)) #2A((1 1 1) (1 1 1))In this case the single quote is needed since we don't want to evaluate the array.

Here is a function that returns a square Gaussian pseudo-random matrix of arbitrary size. In it we use several useful matrix tools, and we show how to loop over the elements of a matrix.

> (defun gaussian-matrix (l) (let* ((mat (make-array (list l l))) (row (array-dimension mat 0)) (col (array-dimension mat 1)) ) (dotimes (i row) (dotimes (j col) (setf (aref mat i j) (elt (normal-rand 1) 0)) ) ) (copy-array mat) ) ) GAUSSIAN-MATRIXAnd here is an example of its use:

> (print-matrix (gaussian-matrix 3)) #2a( ( 0.479400 0.871488 1.26546 ) ( 0.190493 -2.05859 1.25512 ) ( -8.075542E-2 -1.53208 -2.17642 ) )

First, as we saw in the autocorrelation example, we can
define local variables with `let`

. In this case
we use `let*`

, which allows us to use, sequentially,
the results of previous local definitions. In this example,
we first define `mat`

, and then we can use `mat`

itself to define new local variables such as `row`

.
`aref`

is one way of accessing a given element of a
matrix. So the line

(setf (aref mat i j) (elt (normal-rand 1) 0))say to set the

`i j`

element of `mat`

to
a normal random number. But since `(normal-rand 1)`

returns a length 1 list, we somehow need to ``flatten'' this
list so that we only have a number. There are several ways to
do this, but talking the first (i.e., 0-th) element with
`elt`

does the trick.
An even simpler, and vectorized, approach is

(defun gaussian-matrix (l) (make-array (list l l) :initial-contents (normal-rand (* l l))) )

Tue Aug 29 09:10:30 MDT 1995