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:
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
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
% 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 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
''" 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