NCL expressions overview
The results of expressions are values. Anything like functions, constant
values, and variable references are expressions.
Expressions can also be nested by using algebraic operators to string together expressions. Expressions are grouped into
subsets. There are algebraic expressions that take numeric operands and produce numeric results. There are
logical expressions that take any type of operand and produce logical results.
There are functions that can produce any type of value and can produce variables. Finally there are
arrays that group one or more expressions into a multi-dimensional value.
NCL's algebra, like Fortran 90, supports operations on entire arrays
rather than single scalar values like C and PASCAL.
For array operations to work, both operands must have the same number
of dimensions and same size dimensions, otherwise an
error condition occurs. Furthermore, the data types of each operand must be
equivalent, or one operand must be
coercible to
the type of the other operand.
The following is an example of two entire arrays being multiplied together
in a single expression; note that a is integer and b is
float:
;
; Define two [2]x[2] arrays
;
a = (/ (/ 1, 2 /), (/ 3, 4 /) /)
b = (/ (/ .1, .01 /), (/ .001, .0001 /) /)
;
; Multiplication of two [2]x[2] arrays
;
c = a * b
print(c)
Variable: c
Type: float
Total Size: 16 bytes
4 values
Number of Dimensions: 2
Dimensions and sizes: [2] x [2]
Coordinates:
(0,0) 0.1
(0,1) 0.02
(1,0) 0.003
(1,1) 0.0004
The above example illustrates how multi-dimensional arrays are handled in NCL expressions. The above statement c = a * b is equivalent
to looping through both dimensions of a and b, multiplying each element and assigning it to the respective element in c. The following
code segment is equivalent to the above example. This shows how NCL's
syntax saves a lot of typing.
dims = dimsizes(a)
c = new(dims,float)
do i = 0,dims(0) - 1
do j = 0, dims(1) - 1
c(i,j) = a(i,j) * b(i,j)
end do
end do
Scalar values are special cases when considering array operations. When
scalar values appear in an expression with
a multi-dimensional value, the scalar value is applied to each element
of the multi-dimensional value. For example, each element in an
entire array can be doubled by multiplying the array by the scalar
value 2. The following example shows this.
a = (/ (/ 1, 2 /), (/ 3, 4 /) /)
;
; Multiplication of an entire array by a single scalar
;
b = a * 2
print(b)
Variable: b
Type: float
Total Size: 16 bytes
4 values
Number of Dimensions: 2
Dimensions and sizes: [2] x [2]
Coordinates:
(0,0) 2
(0,1) 4
(1,0) 6
(1,1) 8
Missing values were discussed in the
variables section
of this document. There it was noted that the
"_FillValue" attribute is a special attribute that allows for specific elements
of an array to be tagged as missing. When any NCL expression is being
evaluated, NCL ignores elements that are equal to the value
of the "_FillValue" attribute for each variable. When a missing value is
ignored, the result of the expression will contain a missing
value at the corresponding array index. If more than one term in an
expression contains a missing value and the values are not equal,
the missing value of the value of the left-most term in the expression
containing a missing value is used in the output. The following
example illustrates this.
;
; Assign three variables values and missing values. Each variable's
; missing value is different.
;
a = (/1, 2, -99/)
a@_FillValue = -99
b = (/4, -999, 5/)
b@_FillValue = -999
c = (/-9999, 7, 8/)
c@_FillValue = -9999
;
; Assignment to variable d of an expression containing all
; three variables with different missing values.
;
d = a * b * c
;
; Assignment to variable of an expression containing two
; variables with different missing values.
e = b * c
;
; Results of first assignment. Note resulting missing value.
;
print(d)
Variable: d
Type: integer
Total Size: 12 bytes
3 values
Number of Dimensions: 1
Dimensions and sizes: [3]
Coordinates:
Number Of Attributes: 1
_FillValue : -99
(0) -99
(1) -99
(2) -99
;
; Results of second assignment. Note resulting missing value.
;
print(e)
Variable: e
Type: integer
Total Size: 12 bytes
3 values
Number of Dimensions: 1
Dimensions and sizes: [3]
Coordinates:
Number Of Attributes: 1
_FillValue : -999
(0) -999
(1) -999
(2) 40
Algebraic expressions operate on arrays of basic numeric types. There are nine
main algebraic operators: multiply, divide, exponent, plus, minus, modulus,
less than selection, greater than selection, and negative.
All of the operators except negative take two operands. Also,
in general, both operands should be the same type. If they are not, NCL
attempts to coerce them to identical types. If this fails, a type mismatch
error is generated. Additionally, either the operands must have the same number
of dimensions and dimension sizes, or one operand can be a scalar value. The
operators operate on the entire array of data.
The following is a list of the operator characters. The operators are listed
in order of precedence: the first one has the highest precedence. The
precedence rules can be circumvented by using parentheses '( )'
around expressions that should be computed first.
- Negative
^ Exponent
* Multiply
/ Divide
% Modulus
# Matrix multiply
+ Plus
- Minus
< Less than selection
> Greater than selection
Negative -
The negative operator negates the value of its operand. The
operand can be any numeric type. If it is an array, each element
of the array is negated.
Exponent ^
The left operand is "raised" to the power of the right
operand. If the left operand is negative, then the right
side must be positive and greater-than-or-equal to 1.0. Currently, NCL doesn't support imaginary
numbers; it generates an error in this situation. The
result type of this operator is always a floating point number
unless double precision values are used.
Multiply *
Multiplies left operand by right operand.
No special conditions or restrictions.
Divide /
Divides left operand by right operand. When both
operands are integer types, the result is an integer type.
Therefore, the decimal remainder is truncated.
Matrix Multiply #
The operands must be one or two dimensional arrays. Higher
dimensionality is not supported. This operand computes the
dot product of two single dimension arrays. For 2 D arrays
the 1st dimension of the left operand must be the same
size as the 0th dimension of the right. The output dimensionality
will be the [0th dimension of the left] x [1st dimension of the right].
Modulus %
The result is the integer remainder of integer division. Both
operands must be integer types.
Plus +
Adds left operand to right operand. No special
conditions or restrictions. If the operands are
strings, then the strings are concatenated.
Minus -
Subtracts right operand from left operand. No special
conditions or restrictions.
Less-than selection <
For arrays, the less-than selection operator selects all values
in the left operand that are less than the corresponding
value in the right operand. If the value of the left
side is greater than or equal to the corresponding value of
the right side, then the right side value is placed
in the result. For a scalar and an array, the same selection
rules apply, but the scalar is compared against each value in
the array operand.
Greater-than selection >
For arrays, the greater-than selection operator selects all values
in the left operand that are greater than the corresponding
value in the right operand. If the value of the left
side is less than or equal to the corresponding value of
the right side, then the right side value is placed
in the result. For a scalar and an array, the same selection
rules apply, but the scalar is compared against each value in
the array operand.
Logical expressions are formed by relational operators. There are ten relational
operators: less-than-or-equal, greater-than-or-equal, less-than, greater-than,
equal, not-equal, and, or, exclusive-or, not. All of these operators
yield logical values, in other words arrays of True, False or missing values.
And, or, exclusive-or, and not require logical operands, and the rest accept any type.
All of the logical operators function similar to algebraic operators
with respect to operations
between arrays and arrays, arrays and scalars, and scalars and scalars. For
array operands, each corresponding element is compared, and the result is an
array of logical values or missing values, the size and dimensionality of the operands. A single scalar can be
compared against each element in an array. The result is an array of logical
values the size of the array operand. Finally, when two scalars are compared,
the result is a scalar logical value.
The following is a list of the logical operators ordered by their precedence.
.le. Less-than-or-equal
.lt. Less-than
.ge. Greater-than-or-equal
.gt. Greater-than
.ne. Not-equal
.eq. Equal
.and. And
.xor. Exclusive-or
.or. Or
.not. Not
Less-than-or-equal .le.
Returns True if the left operand is less than or equal
to the right operand.
Less-than .lt.
Returns True if the left operand is less than the right operand.
Greater-than-or-equal .ge.
Returns True if the left operand is greater than or equal to
the right operand.
Greater-than .gt.
Returns True if the left operand is greater than the right operand.
Not-equal .ne.
Returns True if the left operand is not equal to the right operand.
And .and.
Requires both operands to be logical types. Returns True if
and only if both operands are True.
Or .or.
Requires both operands to be logical types. Returns True if
either operand is True.
Exclusive-or .xor.
Requires both operands to be logical types. Returns True if
one of the operands is True and the other is False.
Not .not.
Takes a single operand which must be logical. Returns True if
the operand is False; returns False if the operand is True.
An array expression combines either scalar values or other arrays into
a single array result. An array expression is made up of expressions separated
by commas ',' and enclosed in '(/' and '/)' (called
array designator characters). Arrays can be made
up of any of the basic types as well as graphical objects. Currently, arrays
of files are not supported. Each element separated by commas must have the
same dimensionality as the rest of the elements in the array expression. If
the types are not the same, the coercion rules are used to convert all of
the array elements to the same type. If this fails, an error message is
generated.
The following are examples of array expressions.
(/ 1, 2, 3, 4, 5 /)
(/ (/ 1, 2, 3 /)^2, (/ 4, 5, 6 /)^3,(/ 7, 8, 9 /)^4 /)
(/ a - b, b + c, c / d /)
If a single variable is enclosed in array designator characters
'(/' and '/)', only the
variable's value is referenced and not its associated attributes, dimension
names, and coordinates. The array designator characters are useful in performing
value only assignment.
Functions are expressions because they return a value. Functions do not
necessarily have to always return the same type or size array every time
they are called. Functions are called by referencing their name and providing
an argument list. Arguments can be any type, including files. They can also
be constant values, variables, or subsections of variables.
Functions can be defined to restrict parameters to be specific types,
to have specific numbers of dimensions, and to have specific dimension
sizes. If a parameter must be a certain type, then the coercion rules
are applied to it.
One very important thing to
note is that all parameters are passed by reference in NCL, meaning a change
of a value in a variable within the function changes the value of the parameter.
However, if a parameter is coerced before the function is called, changes within the
function will not be reflected in the parameter, because
coercion can only be applied in a single direction. A warning message is given in this
instance.
Expression results can also be passed to functions as
parameters. However, since expression results are not referenced by a
variable, there is no way that changes made to the parameter can be
passed out from the function, unless it is returned by the function.
Reference Manual Control Panel
NG4.1 Home, Index, Examples, Glossary, Feedback, Ref Contents, Ref WhereAmI?
$Revision: 1.22 $ $Date: 1998/12/23 18:39:18 $