NCL expressions overview

Properties of expressions

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.

Multi-dimensional arrays and expressions

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: 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.

Scalar values and expressions

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.

Expressions and missing values

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.

Types of expressions

Algebraic

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

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.

Arrays

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.

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

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 $