Some Matrix Examples



next up previous
Next: Writing Programs with Up: A Few Simple Previous: An Example of

Some Matrix Examples

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-MATRIX
And 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)))
)



next up previous
Next: Writing Programs with Up: A Few Simple Previous: An Example of




Tue Aug 29 09:10:30 MDT 1995