Next: , Previous: Creating a grid, Up: Top


3 Operations

3.1 Summary of defined operations

There are many operations that are common to all grid structured data. They transform or compose grids to make new grids.

3.2 General elementwise operations

There are two more general functions map-grid and map-n-grids on which the above functions are defined. They will provide the basis for any elementwise mapping of one (for the former) or several (for the latter) grids into a destination grid.

3.2.1 map-grid

Although this function has other uses, it can be used to create a grid using a function of the index values. For example, in the file gsd/grid/tests/grids.lisp is a function index-fill-decadal that multiplies increasing powers of ten by each argument in succession, and adds the result. The array *array-3-4-double-float* is created with this function:

     (defparameter *array-3-4-double-float*
       (map-grid :source 'index-fill-decadal :source-dims '(3 4)))

which gives

     *array-3-4-double-float*
     #2A((0.0d0 1.0d0 2.0d0 3.0d0)
         (10.0d0 11.0d0 12.0d0 13.0d0)
         (20.0d0 21.0d0 22.0d0 23.0d0))

(see also the function 'test-grid-double-float).

Take the square root of every element of an array:

     (map-grid :source #m((0.0d0 1.0d0 2.0d0) (10.0d0 11.0d0 12.0d0) (20.0d0 21.0d0 22.0d0)) :element-function 'sqrt)

3.2.2 map-n-grids

This is a more general form of map-grid which can take multiple source grids, instead of only one. For example, combine arrays a and b as a+2b:

     (map-n-grids :sources `((,#31m(1 2 3) nil) (,#31m(9 8 7) nil))
                  :combination-function (lambda (a b) (+ a (* 2 b))))

3.3 Creation functions

In addition to the techniques for creating grids described above, the functions make-grid and make-foreign-array are defined. The functions map-grid and map-n-grids can be used to create grids from functions of indices.

3.3.1 make-grid

This is used for making any kind of grid with the same value for each element, or with literally specified values. The first argument is a specification, which has the form ((grid-type dimensions) element-type). The keyword arguments are :initial-element or :initial-contents. For example,

     (make-foreign-array 'double-float :dimensions 3 :initial-element 77.0d0)
     #m(77.0d0 77.0d0 77.0d0)
     (make-grid '((foreign-array 3) double-float) :initial-element 77.0d0)
     #m(77.0d0 77.0d0 77.0d0)

3.3.2 make-foreign-array

This function can be used instead of make-grid to make a foreign-array; the first argument is the element-type and the :dimensions are supplied in a keyword argument, for example,

3.3.3 Mapping functions

Make a foreign vector with each element the square root of its index:

     (map-grid :source 'sqrt :destination-specification '((foreign-array 6) double-float))

3.4 AFFI

extrude will transform an AFFI into one that will make it appear that the grid has an extra dimension. This is useful in e.g. map-n-grids.

3.5 Composition functions

3.5.1 drop

Define the CL array on double float elements:

     (test-grid-double-float 'array '(5 1))
     #2A((0.0d0) (10.0d0) (20.0d0) (30.0d0) (40.0d0))

to reduce this to a vector (one dimensional array),

     (drop (test-grid-double-float 'array '(5 1)))
     #(0.0d0 10.0d0 20.0d0 30.0d0 40.0d0)

3.5.2 row

Select the second row from the matrix above:

     (row (test-grid-double-float 'array '(3 4)) 1)
     #(10.0d0 11.0d0 12.0d0 13.0d0)

3.5.3 column

The first column of the above array is

     (column (test-grid-double-float 'array '(3 4)) 0)
     #(0.0d0 10.0d0 20.0d0)

3.5.4 subgrid

The 2 by 2 block starting at index 1,2 in the previous matrix is

     (subgrid (test-grid-double-float 'array '(3 4)) '(2 2) '(1 2))
     #2A((12.0d0 13.0d0) (22.0d0 23.0d0))

3.5.5 transpose

The transpose of the above array is

     (transpose (test-grid-double-float 'array '(3 4)))
     #2A((0.0d0 10.0d0 20.0d0)
         (1.0d0 11.0d0 21.0d0)
         (2.0d0 12.0d0 22.0d0)
         (3.0d0 13.0d0 23.0d0))

3.5.6 diagonal

The diagonal is the collection of elements where there are two indices equal, or differ by a fixed amount. For a matrix (two dimensional array), this would be for example:

     (diagonal (test-grid-double-float 'array '(3 4)))
     #(0.0d0 11.0d0 22.0d0)

The superdiagonal is accessible with the same function,

     (diagonal (test-grid-double-float 'array '(3 4)) :offset 1)
     #(1.0d0 12.0d0 23.0d0)

as is the subdiagonal,

     (diagonal (test-grid-double-float 'array '(3 4)) :offset -1)
     #(10.0d0 21.0d0)

3.5.7 concatenate-grids

This function is used to join two grids on an axis whose dimensions are the same on the other axes. For example, join two matrices by adjoining their columns, all of the same length:

     (map-grid :source (offset-ifd 0.5d0) :source-dims '(3 4))
     #2A((0.5d0 1.5d0 2.5d0 3.5d0)
         (10.5d0 11.5d0 12.5d0 13.5d0)
         (20.5d0 21.5d0 22.5d0 23.5d0))
     (map-grid :source (offset-ifd 0.1d0) :source-dims '(3 2))
     #2A((0.1d0 1.1d0) (10.1d0 11.1d0) (20.1d0 21.1d0))
     (concatenate-grids ** * :axis 1)
     #2A((0.5d0 1.5d0 2.5d0 3.5d0 0.1d0 1.1d0)
         (10.5d0 11.5d0 12.5d0 13.5d0 10.1d0 11.1d0)
         (20.5d0 21.5d0 22.5d0 23.5d0 20.1d0 21.1d0))

3.5.8 slice

A slice is a subgrid.

     (slice (test-grid-double-float 'array '(3 4)) '(1 (:range 0 2)) :drop nil)
     #2A((10.0d0 11.0d0 12.0d0))

3.5.9 Vector products

cross, inner, euclidean, norm, normalize.

3.6 Iteration

Extensions to the iterate system are provided in the grid-iterate-extension system which will automatically load if asdf-system-connnections, iterate, and the grid system are loaded.