Arrays

Table of Contents

  1. Introduction
  2. Vectors
  3. Matrices
  4. Higher Rank Arrays
  5. Grids
  6. Strings

Introduction

NAP stores data in NAOs. A NAO is essentially an object based on the concept of an n-dimensional array. The number of dimensions is called the rank. A scalar is simply an array of rank 0.

Dimensions can have names and coordinate variables (CVs). A CV maps a subscript to another variable such as a physical dimension (e.g. time). Arrays with CVs are called grids.

NAP provides powerful and efficient facilities for processing arrays, including:

Vectors

An array with exactly one dimension is called a vector.

NAP array constants are enclosed in braces "{}". The following example doubles a vector containing four elements:

% [nap "2 * {3.4 -0.1 _ 7}"]
6.8 -0.2 _ 14
Note that an underscore ("_") represents a missing element.

The ordinary scalar arithmetic operators and functions are applied to arrays in an elemental fashion, as shown by:

% [nap "{1 _ 4 -6} + {2 0 -9 _}"]
3 _ -5 _
% [nap "sqrt(-{1 _ 9 -6} + 10)"]
3 _ 1 4

The function sum has the functionality of the mathematical "Σ". When applied to a vector it returns the sum of the elements (ignoring any that are missing), as shown by:

% [nap "sum{1 _ 9 -6 3}"]
7

The following example applies the concatenation operator "//" to vectors and scalars:

% [nap "{1 _ 9} // 7 // {-3 8}"]
1 _ 9 7 -3 8

The operators ".." and "..." generate arithmetic progression (AP) vectors. For example:

% [nap "3 .. 7"]
3 4 5 6 7
% [nap "7 .. 3"]
7 6 5 4 3
% [nap "0 .. 10 ... 2.5"]; # From 0 to 10 with step of 2.5
0 2.5 5 7.5 10
% [nap "5 ... 0 .. 10"]; # 5 elements from 0 to 10
0 2.5 5 7.5 10

An index specifies a position within an array, commencing from 0. If two operands (representing NAOs) are adjacent then NAP treats the right operand as the index of the left operand. For example:

% nap "abc = {4 9 8 2}"
::NAP::283-283
% [nap "abc(2)"]
8
% [nap "abc 0"]; # parentheses not needed
4
% [nap "abc{2 0 3 2 1}"]; # vector index
8 4 2 8 9

Some computer languages allow indexed variable names on the left of the assignment operator "=". So one might expect to be able to modify element 2 of abc as follows:

% nap "abc(2) = 5"
abc(2) = 5
       ^
syntax error, unexpected '=', expecting $end
Error at line 1768 of file napParse.tab.c

NAP does not allow indexed variable names on the left of the assignment operator "=". However the "set value" OOC method does provide a way to modify elements of a NAO. Element 2 of abc can be changed to 5 as follows:

% $abc set value 5 2
% $abc
4 9 5 2

The following examples show how several elements (or the entire array) can be changed using a single OOC:

% $abc set value "{13 11}" "{0 2}"
% $abc
13 9 11 2
% $abc set value -3
% $abc
-3 -3 -3 -3
% $abc set value "{13 11}"
% $abc
13 11 13 11

The default OOC displays only the first six elements, as in:

% [nap "1 .. 9"]
1 2 3 4 5 6 ..

The "value" OOC method displays all elements, as in:

% [nap "1 .. 9"] value
1 2 3 4 5 6 7 8 9

Matrices

An array with exactly two dimensions is called a matrix.

A matrix constant has two levels of braces, as in:

% [nap "{{2 4 8}{0 -1 9}}"] all
::NAP::298-298  i32  MissingValue: -2147483648  References: 0
Dimension 0   Size: 2      Name: (NULL)    Coordinate-variable: (NULL)
Dimension 1   Size: 3      Name: (NULL)    Coordinate-variable: (NULL)
Value:
 2  4  8
 0 -1  9

It is often convenient to use a separate line for each row, as in:

% nap "mat = {
{2 1.5 7}
{0  -2 1.1}
}"
::NAP::301-301
% $mat all
::NAP::301-301  f64  MissingValue: NaN  References: 1
Dimension 0   Size: 2      Name: (NULL)    Coordinate-variable: (NULL)
Dimension 1   Size: 3      Name: (NULL)    Coordinate-variable: (NULL)
Value:
 2.0  1.5  7.0
 0.0 -2.0  1.1

The function "sum" gives column and row sums, as in:

% [nap "sum(mat)"]
2 -0.5 8.1
% [nap "sum(mat, 1)"]
10.5 -0.9

Matrices (and higher rank arrays) can be indexed using either cross-product indexing or full indexing. A cross-product index of a matrix has the form "rows, columns", where rows and columns are scalars or vectors. Here are two examples of cross-product indexing:

% [nap "mat(0,2)"]
7
% [nap "mat(0 .. 1, {0 2})"]
2.0 7.0
0.0 1.1

A full index of a matrix is an array with two columns corresponding to row and column. Here are two examples of full indexing:

% [nap "mat{0 2}"]
7
% [nap "mat{{0 2}{0 0}{1 3}}"]
7 2 0

The function "transpose" swaps the row and column dimensions. E.g.

% $mat
 2.0  1.5  7.0
 0.0 -2.0  1.1
% [nap "transpose mat"]
 2.0  0.0
 1.5 -2.0
 7.0  1.1

The function "reshape" uses the elements of the first argument (recycled if necessary) to produce an array whose shape is specified by the second argument. If there is only one argument then this is reshaped to a vector with the same number of elements. E.g.

% [nap "reshape(mat, {3 4})"]
 2.0  1.5  7.0  0.0
-2.0  1.1  2.0  1.5
 7.0  0.0 -2.0  1.1
% [nap "reshape mat"]
2 1.5 7 0 -2 1.1
% [nap "reshape(9, {2 5})"]
9 9 9 9 9
9 9 9 9 9

The concatenation operator "//" can be applied to matrices. For example:

nap "m33 = {{4 6 8}{3 5 9}{0 4 1}}"
::NAP::14-14
% $m33
4 6 8
3 5 9
0 4 1
% $mat
 2.0  1.5  7.0
 0.0 -2.0  1.1
% [nap "m33 // mat"]
 4.0  6.0  8.0
 3.0  5.0  9.0
 0.0  4.0  1.0
 2.0  1.5  7.0
 0.0 -2.0  1.1

The laminate operator "///" joins its operands over a new dimension. The following example creates a matrix from two vectors:

% [nap "{9 3 5} /// {1 7 2}"]
9 3 5
1 7 2
% [nap "{9 3 5} // {1 7 2}"]; # Note difference
9 3 5 1 7 2

Higher Rank Arrays

A NAO can have up to 32 dimensions. The following example creates a 3-dimensional array, sums it along each dimension, then extracts an element using cross-product indexing.
% nap "a3D = reshape(0 .. 99, {2 3 4})"
::NAP::47-47
% $a3D 
 0  1  2  3
 4  5  6  7
 8  9 10 11

12 13 14 15
16 17 18 19
20 21 22 23
% [nap "sum(a3D)"]
12 14 16 18
20 22 24 26
28 30 32 34
% [nap "sum(a3D, 1)"]
 6 22 38
54 70 86
% [nap "sum(a3D, 2)"]
12 15 18 21
48 51 54 57
% [nap "a3D(0,2,1)"]
9

Grids

Grids are arrays with coordinate variables (CVs). Dimensions often correspond to physical dimensions such as time and length. A CV maps a subscript to another variable, which is typically a physical dimension such as time.

The following example creates a NAO corresponding to the grid described in Missing Data. Note how the "set coo" OOC method is used to attach the CVs and name the dimensions.

% nap "latitude = {30 25 10 -10}"
::NAP::74-74
% nap "longitude = {30 40 60 65 75}"
::NAP::76-76
% nap "grid2d = {
{15 17 10  _ 21}
{16 14 18 18 19}
{ _ 11 12 11  _}
{10  9  _ 12 11}
}"
::NAP::78-78
% $grid2d set coo latitude longitude
% $grid2d all
::NAP::78-78  i32  MissingValue: -2147483648  References: 1
Dimension 0   Size: 4      Name: latitude  Coordinate-variable:
::NAP::74-74
Dimension 1   Size: 5      Name: longitude  Coordinate-variable:
::NAP::76-76
Value:
15 17 10  _ 21
16 14 18 18 19
 _ 11 12 11  _
10  9  _ 12 11

Grids can be indexed using indirect indexing, which is indexing via CVs. Continuing the above example, let us extract the value corresponding to a latitude of 25 and a longitude of 75:

% [nap "grid2d(@25, @75)"]; # indirect indexing
19
% [nap "grid2d(1, 4)"]; # direct indexing
19

NAP allows fractional subscripts, which correspond to interpolated values. The following produces a value corresponding to row 0.5 (27.5°N) and column 1.5 (50°E):

% [nap "grid2d(0.5, 1.5)"]; # direct indexing
14.75
% [nap "grid2d(@27.5, @50)"]; # indirect indexing
14.75
% expr (17+10+14+18) * 0.25; # check arithmetic
14.75

Strings

String constants are enclosed in apostrophes "''" or grave accents "``" and generate character vectors. For example:
% nap "message = 'hello world'"
::NAP::329-329
% $message all
::NAP::329-329  c8  MissingValue: (NULL)  References: 1
Dimension 0   Size: 11     Name: (NULL)    Coordinate-variable: (NULL)
Value:
hello world
% [nap "`don't`"]
don't

The following example uses the library function "gets_matrix" to read the text file "abc.txt" into a NAO referenced by "in".

% nap "in = gets_matrix('abc.txt')"
::NAP::349-349
% $in all
::NAP::349-349  f64  MissingValue: NaN  References: 1
Dimension 0   Size: 2      Name: (NULL)    Coordinate-variable: (NULL)
Dimension 1   Size: 3      Name: (NULL)    Coordinate-variable: (NULL)
Value:
 2  9 -3
 0 12  7
Author: Harvey Davies       © 2002, CSIRO Australia.       Legal Notice and Disclaimer
CVS Version Details: $Id: array.html,v 1.1 2004/11/05 06:25:54 dav480 Exp $