Errors in Units and Dimensions

Units and Dimensions

There are two possible approaches to the analysis of units and dimensions:

• Static analysis
• Dynamic analysis at run-time

Static Analysis of Units and Dimensions

Suppose we have a statement in a program:

r = SQRT( x**2 + y**2 )

It is then possible, by static analysis, to infer that x, y and r have the same units and dimensions. If subsequently we find

a = x * y

we now know that a has dimensons of x**2. In this way, inferences may be propagated through the code. If two inferences conflict, the object to which they apply must be dimensionless. This can be reported. It may be untrue and if so, an error has occurred.

Note that this system of inference does not depend on any prior definition of the units of the variables. It is, of course, possible to provide users with a means to specify units, but it is not necessary to do so. For large programs the labour involved would be prohibitive.

There are three obvious complications. The first is that the same variable may be used to hold data for very different objects. This is overcome by a "life" analysis. Each assignment of a variable begins a life. If the program flow is such that two different lives can reach the left-hand-side of the same expression, the lives are the same. They must have the same units and dimensions. If this can never occur, the lives are different and no inference may be propagated between them. In the analysis, the symbols are replaced by symbol lives. The issue is explored in detail in Farrimond B.T and Collins J. 2007, "Dimensional Inference Using Symbol Lives", Paper presented at the 2007 International Conference: Software Engineering Theory and Practice, Orlando Florida

The second complication is that arrays may not be homogenous. One of the dimensions of a single array may contain several different measures of, for example, a medical patient, and these may have different units and dimensions. This is less common in modern code because users will use components of derived types for the different quantities, but it will happen.

The third complication is the use of sub-programs. Some of these will be generic mathematical functions which may be applied to different quantities. Many of the inferences here will provide relationships between the units and dimensions of the arguments and interface variables.

Dynamic, Run-time, Analysis

Suppose that we replace every real and complex object in a program by an object of a derived type, an emulated real or complex number. Let every emulated number have a component which is the index of its units and dimensions. As the program runs, the relationships between these units and dimensions components is inferred. Whenever an inference requires that a quantity is dimensionless, a report is recorded.

This procedure has the advantages that no assumption need be made about array dimensions. Every single element of an array is tagged separately. There is no problem in handling sub-programs. The specific object passed into a sub-program is tracked. The instrumented code will run very slowly, but hopefully we do not need to run very many times.

Progress in fpt

Progress in the first, static, approach has been:

• The analysis of variable lives: This is now mature, and is used in many of the analyses made by fpt.
• Propagation of inferences: This is under development. It is not trivial. An experimental command is available.

Progress in the dynamic approach has been:

• fpt can now replace all real and complex variables by derived types. All of the arithmetic, relational and intrinsic overloads are available to handle these. The procedure was used in the study Collins J. 2017, Testing the Numerical Precisions Required to Execute Real World Programs", IJSEA Vol 8, No 2, March 2017.
• The original implementation of emulated real and complex numbers used derived types which contained only one component, which was of the type of the emulated object. When the emulated numbers have additional type components it will be necessary to change the I/O statements in the code. This is not a major task but it has yet to be done.
• A preliminary verson of the run-time inference code has been developed, but this requires further work.