1 INTRODUCTION

 1.1 The VAL, VEC and NUM Facilities
 1.2 Propagation of Bad Data
 1.3 The STATUS Argument

This document describes version 1.0 of the PRIMDAT package, which is a collection of Fortran functions and subroutines providing support for “primitive data processing”. Routines from this package may be used to perform arithmetic, mathematical operations, type conversion and inter-comparison of any of the primitive numerical data types supported by the Starlink Hierarchical Data System HDS (SUN/92).

It provides:

Note that only the numerical HDS data types (_BYTE, _UBYTE, _WORD, _UWORD, _INTEGER, _REAL & _DOUBLE) are supported at present. There is currently no provision for the non-numerical _LOGICAL and _CHAR types, nor for any other Fortran (or VAX Fortran) types such as COMPLEX. The CHR facility should be used for processing character data and for converting between character and numerical data types.

Note added March 2004: This manual refers throughout to VAX floats. The package was ported to Unix in 1991, and accordingly most of the values now defined by it are those appropriate for IEEE floats instead; the manual has not been updated to match.

1.1 The VAL, VEC and NUM Facilities

The routines in this package have names of the form <fac >_ <name >, where <fac > is a three character facility name and <name > specifies the operation which the routine performs.

The routines are divided into three facilities as follows:

<fac >

Facility provides…



VAL

Arithmetic, mathematical functions and type conversion on single (scalar) values. Handling of numerical errors and bad value propagation are incorporated.

VEC

Arithmetic, mathematical functions and type conversion on vectorised arrays, allowing more efficient processing of large numbers of data. Handling of numerical errors and bad value propagation are incorporated.

NUM

Lower level routines for arithmetic, mathematical functions, type conversion and inter-comparison of single numbers. Operations are performed without protection against numerical errors and without regard for bad values.

Note that a distinction is drawn between three classes of primitive data, which differ in their interpretation and in the algorithms best suited to processing them:

Italics are used throughout this document to refer to values, vectorised arrays and numbers when it is important to emphasise the particular meaning (and the implied processing rules) described here.

1.2 Propagation of Bad Data

The handling of numerical errors by the VAL_ and VEC_ routines1 depends on the generation, recognition and propagation of bad values in the data, and also on the presence of an integer STATUS argument carried by each routine.

Bad values are a set of special numerical constants (one for each data type) which are defined by Starlink to be used for flagging “bad” or “undefined” data. The philosophy and conventions surrounding their use are described in SGP/38. The Starlink “bad constants” which specify these values have symbolic names2 of the form:

  VAL__BAD<T>

where <T > is one of the data type codes in Table 1 (also see section 5.1). Bad values may be set explicitly by assigning the value of one of these constants to a variable. They are also set by VAL_ and VEC_ routines when numerical errors occur — implying that the result of the attempted operation is undefined.






Type Code <T >
HDS Type
Fortran Type




UB _UBYTE (unsigned byte) BYTE
B _BYTE (byte) BYTE
UW _UWORD (unsigned word) INTEGER2
W _WORD (word) INTEGER2
I _INTEGER (integer) INTEGER
R _REAL (real) REAL
D _DOUBLE (double precision) DOUBLE PRECISION





Table 1: The data type codes used in constants and routine names, and the HDS and VAX Fortran types to which they correspond.

Recognition of bad values involves comparing them for equality with the appropriate “bad constant”, and may be used to control subsequent processing. Most frequently, this control takes the form of “propagation” — i.e. the outcome of any operation attempted on a bad operand is itself bad; so that the bad value is “propagated” to the result. After a sequence of such operations, the resulting bad values make it possible to identify all those results which have been rendered invalid by errors occurring en route.

The VAL_ and VEC_ routines have the ability to recognise and propagate bad values in this manner (the precise processing rules are described in sections 2.2 & 3.2). In some circumstances, however, appreciable amounts of processing time can be saved if it is known in advance that bad values are not present and that their recognition is not necessary. Also, it is occasionally necessary to disable bad value recognition so that the numerical values specified by the “bad constants” may themselves be processed as if they were valid data.

Because of this, recognition and propagation of bad values by the VAL_ and VEC_ routines is controlled by a logical value BAD, which appears at the start of each routine’s argument list. If BAD is set .TRUE., then bad input arguments are recognised and propagated to the result. Conversely, if BAD is set .FALSE., then input argument values are interpreted literally (there is no bad value recognition), although bad values may still be generated on output if numerical errors occur. Most of the routines execute more efficiently if BAD is .FALSE. (Appendix A).

It is up to the calling routine to ensure that the BAD argument has an appropriate logical value when VAL_ and VEC_ routines are invoked. This value will often depend on whether numerical errors have occurred in previous stages of processing, so each routine also carries a STATUS argument which may be used to detect the occurrence of such errors.

1.3 The STATUS Argument

Each VAL_ and VEC_ routine takes a standard integer STATUS variable as its final argument. In normal use, this STATUS variable should be set to SAI__OK when the routine is invoked, otherwise it will return immediately without action.3

On exit, the STATUS value will still be set to SAI__OK unless a numerical error has occurred, in which case it will be set to an appropriate error code (Appendix B). PRIMDAT error codes may be tested to detect when a particular numerical error has occurred, and may also be used to report these errors (using the ADAM ERR_ routines for instance).

Note that routines in this package do not report errors themselves. This is partly an efficiency consideration. In many circumstances, the automatic generation of a bad value will itself be an adequate response to a numerical error and, in such cases, the STATUS variable may simply be reset to SAI__OK and processing can continue.

1The NUM_ functions do not have a built-in error handling capability and are not discussed here.

2These symbolic constants are defined in the include file PRM_PAR.

3In the case of the VAL_ functions, a bad function result will be returned.