# Gnudl prototype tutorial

In this tutorial section, the prompt `; ->` will indicate output from gnudl (I will not reproduce most output here, just interesting output lines); lines in the

```example typeface
```

without `; ->` are lines you should type. You can cut the example sections from this manual and paste them into gnudl.

You can invoke gnudl by typing

```gnudl
```

Also: the demos in this tutorial are all stored in the file "demo.scm", so you can type `(load "demo")` in gnudl and it will tell you how you can run the individual demos.

## Elementary examples

• Try creating an array with
```(define x (indgen 30))
; -> x
x
; -> #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29)
```
`(indgen n)` returns a vector of `n` numbers, each set equal to its index in the array. Note the `#(0 1 2 3 ...)` notation for vectors used by gnudl:
```(define y #(3 2 9.1 4.4))
; -> y
y
; -> #(3 2 9.1 4.4)
```
• Now create an array that is more finely spaced:
```(define x (span -10 10 400))
; -> x
x
; -> #(-10 -9.95 -9.9 -9.85 -9.8 -9.75 -9.7 -9.65 -9.6 -9.55 -9.5 -9.45 - ...)
```
`(span min max n-points)` returns an array of `n-points` numbers, evenly spaced, between `min` and `max`.
• Now create a second array `y` by applying the `sin` function to the array `x`:
```(define y (sin x))
; -> y
y
; -> #(544.02111088937e-3 501.4051281792e-3 457.53589377532e-3 412.52305791709e-3 ...)
```
Notice how gnudl performs operations on entire vectors with a single instruction by just invoking `(sin x)`.
• Let us see how easily (1) gnudl allows plotting of data arrays:
```(plot x y)
```
The `plot` instruction takes arrays of x-y data and plots them in the graphics window.
• Now let us try a more complicated application of functions to arrays:
```(define y (times (sin (times x 8)) (exp (minus (divide x 3)))))
(plot x y)
```
• You might have noted that by default gnudl shows you 6 plots on a page: two across and three down. You can change this with the `p-multi` instruction:
```(p-multi 2 2)
(define x (span -4 4 200))
(plot x (sin x))
(plot x (exp x))
(plot x (tan x) '(yrange .(-10 . 10)))
(plot x (exp (divide 1 (plus 1 (times x x)))))
```

## Surface plots

Gnudl provides, in the proto4 snapshot, a very elementary surface plotting mechanism. If you have a height matrix `a`, which you could form with

```(define a (make-matrix-index (lambda (x y)
(* (exp (- (/ (+ (* (- x 5) (- x 5))
(* (- y 5) (- y 5))) 30)))
(sin (/ x 2))))
20 20))
```

then you can render a surface wire mesh plot with hidden lines using:

```(surface a)
```

Notice that the height matrix `a` was formed with the `make-matrix-index` procedure, which makes a matrix of the given size (20x20), and fills it with the given procedure:

```(lambda (x y)
(* (exp (- (/ (+ (* (- x 5) (- x 5))
(* (- y 5) (- y 5))) 30)))
(sin (/ x 2))))
```

The procedure is applied to the matrix indices, and it scales down the x and y values (since they are integers).

Right now there are no options for shifting the view angle (should be easy to add), or for shading the wire mesh (probably harder). The `surface` call is a trivial call to gnuplot's `splot` command, with the hidden line removal option.

[NOTE: I am still looking for someone to take the lead on 3D work for Gnudl. Talk to Mark Galassi (rosalia@nis.lanl.gov) if you are interested.]

You can also draw a contour plot of the same height matrix with

```(contour m)
```

If you want more contour levels (the default is 6), use

```(contour m n-levels)
```

Like `surface`, `contour` is just a pipe to ghostscript right now, and pretty unsophisticated.

## Random numbers and probability distributions

Gnudl provides several routines that generate vectors filled with random numbers satisfying various probability distributions.

• Here's an example in which we plot a set of data distributed according to uniform, poisson and gaussian probability distributions. The uniform distribution consists of numbers evenly spread between 0 and 1. The poisson distribution of mean gamma (`p(x) = (1/gamma) * exp(-gamma*x)`) is uniquely characterized by its mean, and the standard deviation is equal to the mean. The gaussian distribution is given by ```p(x) = 1/(2*PI*sigma) * exp(-x*x/(2*sigma*sigma))```, and is the classic "bell shaped curve".
```(p-multi 2 3)
(plot (rnd-vector 100))
(plot (rnd-vector 1000))
(plot (poisson-rnd-vector 100 2.2))
(plot (poisson-rnd-vector 1000 2.2))
(plot (gauss-rnd-vector 100 2.2 1.1 10))
(plot (gauss-rnd-vector 1000 2.2 1.1 10))
```
• Here we look at histograms of these probability distributions:
```(p-multi 3 2)
(plot (poisson-rnd-vector 100 2.1))
(plot (poisson-rnd-vector 1000 2.1))
(plot (histogram (poisson-rnd-vector 1000 2.1) 100))
(plot (gauss-rnd-vector 100 2.2 1.1 10))
(plot (gauss-rnd-vector 1000 2.2 1.1 10))
(plot (histogram (gauss-rnd-vector 1000 2.2 1.1 10) 100))
```

## Getting data from a file

It is nice to create vectors online and play with them, but most of the time experimental scientists will be reading in data from a file. We provide a sample data file with the gnudl distribution, called hete_sample.dat. This file contains actual data from the HETE satellite experiment, organized as X and Y columns of numbers.

• Try reading in the data and displaying it with
```(define th-data (read-xy "sample_data/hete_sample.dat"))
(p-multi 1 5)                   ; to see long narrow plots
(plot th-data)
(plot (car th-data) (smooth (cdr th-data) 7))
```
• The previous example showed how to read simple x-y data from a file. Gnudl also provides a more general (i.e. slower) mechanism to read files with columns of data. The `read-cols` procedure will read from a file or a pipe if the filename ends with the `|` (pipe) symbol. `read-cols` accepts a format string specifying how the columns should be interpreted, and returns a list of vectors containing the various columns of data.
```(define th-cols (read-cols "sample_data/hete_time_hist.dat" "%s %s %f %f"))
(p-multi 1 3)
(plot th-time th-counts)
(plot th-time (smooth th-counts 3))
(plot (histogram th-counts 300))
```
Notice how we discard the first two columns of data (read in with \%s options) and are picking out using the next two columns of data with the scheme `caddr` and `cadddr` procedures. The file `hete.scm` shows a more complete example of data analysis for the HETE data.

## Display of images

Gnudl has facilities for incorporating pre-made images in a variety of formats into its plotting window. Here are some examples, based on two GIF files supplied with the software:

• Try reading in the data and displaying it with
```(p-multi 2 3)
(image-gif "t.gif")
(image-gif "l.gif")
```
• Gnudl will also display raytrace images by invoking `pov`, the persistence of view raytracer. If you have a `.pov` file called `file.pov`, you can simply run
```(image-pov "file.pov")
```
We are considering to use POV raytrace rendering to render 3-dimensional surface plots with shading and hidden lines.

## The plotting screen layout

So far you have seen gnudl operate in a mode where it shows x columns and y rows of plots. But gnudl can have very general plot screens of all sorts of shapes and sizes: the `p-multi` procedure is simply a short cut for more general plot-list management routines.

The underlying mechanism to add a plot to the `plot-list` is the `plot-list-add` procedure. To demonstrate its use, try resetting the plot list to only have a background plot:

```(plot-list-reinit)
```

now add a plot in the rectangle `(100 100 400 300`:

```(set! default-plot-list (plot-list-add default-plot-list '(100 100 400 300) '() #f '()))
```

The arguments `'() #f '()` specify, respectively, that there is no "hook" procedure to be invoked for this plot; that this plot is not to be skipped by `plot`, and that we start with no list of postscript instructions.

Now add a second plot rectangle

```(set! default-plot-list (plot-list-add '(400 400 550 600) '() #f '()))
```

and reset the `current-plot` variable with

```(reset-current-plot!)
```

and refresh the screen by typing

```(refreshD)
```

Now try making some new plots:

```(define (new-func x) (times (cos x) (sin x)))
(define x-vals (span -10 10 500))
(plot (new-func x-vals))
(plot (sin x-vals) (new-func x-vals))
```

As you see, these plots went into the two rectangles defined with `plot-list-add`.

There is another much more general routine for manipulating the plot-list: `boxl->plot-listD` takes a box list describing a full screen layout and uses it to add several plots to the `default-plot-list`. The box matrix is a list of nested lists that describe how many columns and rows should be nested in the various areas of the plot list.

Box lists are best explained by example; try pasting these in (notice that new-func and x-vals are defined in previous examples):

```(boxl->plot-listD '(1))
(plot (times (sin (times 4 x-vals)) (exp (divide x-vals -4))))
```
```(boxl->plot-listD '(3 1 2))
(plot (times (sin (times 4 x-vals)) (exp (divide x-vals 3))))
(plot ((lambda (x) (times (sin (times 4 x)) (divide 1 (plus 1 (times x x))))) x-vals))
(plot ((lambda (x) (times (sin (times 4 x)) (divide 1 (plus 1 (times x x))))) x-vals))
(plot (times (sin (times 4 x-vals)) (exp (divide x-vals 3))))
(plot ((lambda (x) (times (sin (times 4 x)) (divide 1 (plus 1 (times x x))))) x-vals))
(plot (times (sin (times 4 x-vals)) (exp (divide x-vals 3))))
```

This will set the plot screen to have three plots in the top row, one in the middle row and two on the bottom row, and show some sample data in those plots.

Try some more complicated box matrices with nested sub-boxes, such as:

```(define boxl '( (2 1) (1 3) (1 (1 1)) 1 ((1 2) 1 1)) )
(boxl->plot-listD boxl)
```

and then make various plots in it (there are 16 plots in this box list).

## Numerical analysis support

Gnudl provides a large library (actually it's pretty small right now) of numerical routines that can be applied to data or to functions. More routines can be added by programming them in C or scheme, but in this tutorial I only describe the use of some analysis routines that we provide with guile.

• To look at some of what can be done with the discrete fourier transform, try the following:
```(define v (span -5 5 200))
(define scv (plus (plus (sin v) (sin (times 7 v))) (plus (cos v) (times (sin v) (cos v)))))
(define scv-hat (dft scv 1))
(define scv-hat-hat (dft scv-hat -1))
(p-multi 2 2)
(plot scv)
(plot scv-hat)
(plot scv-hat-hat)
```
(there is something weird here).

## Operations on vector data

You have noticed how arithmetic operations and transcendental functions can all be applied to vector data as well as single numbers.

There two more operations which make vector manipulatio powerful and flexible: the where operator and subscripting with a list of indices.

• The procedure `(where vec condition?)` returns a list of indices for which `(condition? vec[i])` is true. For example, try:
```(define v #(1 10 2 4 12 39 0.8 -5 22.9))
(where v (lambda (z) (> z 2.5)))
; -> (1 3 4 5 8)
```
This tells us that the entries `v, v, v, v, v` are greater than 2.5.
• The primitive scheme procedure `vector-ref` has been enhanced in gnudl so that it will take a list or a vector of indices as an argument. This allows the `where` operator to become truly powerful. Continuing where the previous example left off:
```(define v #(1 10 2 4 12 39 0.8 -5 22.9))
(define index-list (where v (lambda (z) (> z 2.5))))
(vector-ref v index-list)
; -> #(10 4 12 39 22.9)
```
• Here's a more interesting application:
```(p-multi 2 2)
(define pi 3.141592654)
(define v (span -7 7 1000))
(define sv (sin v))
(define chopped-ind-list (where sv (lambda (z) (< z 0.7))))
(define new-v (vector-ref v chopped-ind-list))
(define new-sv (vector-ref sv chopped-ind-list))
(plot new-v new-sv)

(define gap-ind-list (where v (lambda (z) (or (< z (- pi)) (> z (/ pi 2))))))
(plot (vector-ref sv gap-ind-list))
```

## Saving postscript files and printing

Gnudl has a command `(ps-snapshot plot-list file-name)` for saving postscript

## Special plotting commands

Apart from the standard "x-y plotting" possibilities, gnudl also allows you to splatter arbitrary shapes onto into a plot rectangle. In this mode the coordinates of the objects you draw always range from (0, 0) to (1, 1).

```(p-multi 3 3)
(add-rect 0 0 0.5 0.5 'blue)
(add-rectR 0 0.5 0.6 0.6 'red)  ; the R means you refresh after drawing
(add-segmentR 0 0 1 1 'green)
(add-boxR 0.3 0.3 0.4 0.4 'purple)
```

Another example shows the use of bar charts:

```(p-multi 1 10)
(bar-chart-flat (span 0 20 20)) ; all rectangles are the same height
(bar-chart (span 0 20 20))      ; height is proportional to the value
(bar-chart-flat (sin (span 0 200 200)))
(bar-chart (span -10 10 200))
(bar-chart (times 30 (sin (span -10 10 200))))
(bar-chart (times 30 (sin (span -10 10 200))) 'red)
;; now do some bar charts of histograms
(define b (span -2 4 2000))
(define esb (times (exp (divide b (- 2))) (sin (times b 8))))
(define hesb500 (histogram esb 500))
(bar-chart (cdr hesb500))     ; the histogram puts the actual data in the cdr
(bar-chart (cdr hesb500) 'blue)
(define hesb250 (histogram esb 250))
(bar-chart (cdr hesb250))     ; the histogram puts the actual data in the cdr
(bar-chart (cdr hesb250) 'blue)
```

## The Cellular Automata package

Mark Galassi wrote a package which allows some displaying of cellular automata as well as displaying results from his ga_ca project. Take a look at the file `ca.scm` to see how special-plot and other constructs are used together to make vignettes of many types of data.