Pure functions may be used in expressions in `FORALL` statements and
constructs, unlike general functions.
Several examples of this are given below.

! This statement function is pure since it does not reference
! any other functions
REAL myexp
myexp(x) = 1 + x + x*x/2.0 + x*x*x/6.0
FORALL ( i = 1:n ) a(i) = myexp( a(i+1) )
...
! Intrinsic functions are always pure
FORALL ( i = 1:n ) a(i,i) = log( abs( a(i,i) ) )
Because a *forall-assignment*
may be an array assignment, the pure function can have an array
result.
Such functions may be particularly helpful for performing row-wise or
column-wise operations on an array.
The next example illustrates this.

INTERFACE
PURE FUNCTION f(x)
REAL, DIMENSION(3) :: f,
REAL, DIMENSION(3), INTENT(IN) :: x
END FUNCTION f
END INTERFACE
REAL v (3,10,10)
...
FORALL (i=1:10, j=1:10) v(:,i,j) = f(v(:,i,j))
A limited form of MIMD
parallelism can be obtained by means of branches within the pure procedure
that depend on arguments associated with array elements or their
subscripts when the function is called from a `FORALL`.
This may sometimes provide an alternative to using
sequences of masked `FORALL` or `WHERE` statements with their
potential synchronization overhead.
The next example suggests how this may be done.

REAL PURE FUNCTION f (x, i) REAL, INTENT(IN) :: x ! associated with array element INTEGER, INTENT(IN) :: i ! associated with array subscript IF (x > 0.0) THEN ! content-based conditional f = x*x ELSE IF (i==1 .OR. i==n) THEN ! subscript-based conditional f = 0.0 ELSE f = x ENDIF END FUNCTION

...

REAL a(n)
INTEGER i
...
FORALL (i=1:n) a(i) = f( a(i), i)
Because pure procedures have no constraints on their internal control
flow (except that they may not use the `STOP` statement), they also
provide a means for encapsulating more complex operations than could
otherwise be nested within a `FORALL`.
For example, the fragment below performs an iterative algorithm on
every element of an array.
Note that different amounts of computation may be required for
different inputs.
Some machines may not be able to take advantage of this flexibility.

PURE INTEGER FUNCTION iter(x) COMPLEX, INTENT(IN) :: x COMPLEX xtmp INTEGER i i = 0 xtmp = -x DO WHILE (ABS(xtmp).LT.2.0 .AND. i.LT.1000) xtmp = xtmp * xtmp - x i = i + 1 END DO iter = i END FUNCTION

... FORALL (i=1:n, j=1:m) ix(i,j) = iter(CMPLX(a+i*da,b+j*db))

Thu Dec 8 16:17:11 CST 1994