To: J3 J3/21-143
From: Steve Lionel
Subject: Pseudo-subscripts in intrinsic function descriptions
Date: 2021-June-05
Reference: 21-007r1
Introduction
------------
The descriptions of the result value for many intrinsic functions use
a pseudo-subscript notation. For example, consider this from EOSHIFT:
"Result Value. Element (s1, s2, . . . , sn) of the result has the value
ARRAY (s1, s2, . . . , sDIM-1, sDIM + sh, sDIM+1, . . . , sn) where sh
is SHIFT or SHIFT (s1, s2, . . . , sDIM-1, sDIM+1, . . . , sn) provided
the inequality LBOUND (ARRAY, DIM) <= sDIM + sh <= UBOUND (ARRAY, DIM)
holds and is otherwise BOUNDARY or BOUNDARY (s1, s2, . . . , sDIM-1,
sDIM+1, . . . , sn)."
A casual reader of such text might think that ARRAY(s1), SHIFT(s1) and
BOUNDARY(s1) all refer to the same value of s1, which would then imply
that the bounds (not just the shape) of each array must be the same. This
is not the case. Rather, these are pseudo-subscripts meant to specify an
element ordering independent of lower bound. This notation is used in
the descriptions of ALL, ANY, COUNT, CSHIFT, EOSHIFT, IALL, IANY, IPARITY,
MAXLOC, MAXVAL, MINLOC, MINVAL, NORM2, PARITY, PRODUCT, REDUCE, SPREAD,
and SUM.
Consider this example, which uses CSHIFT:
integer :: v(7:12) = [1,2,3,4,5,6]
integer :: m(-2:0,4:6) = reshape([1,4,7,2,5,8,3,6,9],[3,3])
integer :: b(3,3)
integer :: s(7:9) = [-1,1,0]
integer :: i
print '(6I2)', cshift(v,2)
b = cshift(m,shift=s,dim=2)
do i=1,3
print '(3I2)',b(i,:)
end do
end
The compilers I tried all got this right, indicating that implementors,
at least, understood the intent, but the question was raised in a
discussion forum and some additional explanatory text might be useful
to readers.
In the process of investigation, it was discovered that the description of
CSHIFT fails to use pseudo-subscripts consistently, where it has:
"Case (i): If ARRAY has rank one, element i of the result is ARRAY (1 +
MODULO (i + SHIFT - 1, SIZE (ARRAY)))."
The first instance of "1" (in "ARRAY (1 + ...") should be changed to
be the lower bound of ARRAY.
Edits for both items are proposed.
Edits to 21-007r1
-----------------
[355:16+], 16.9.1p4+ (Specifications of the standard intrinsic procedures)
After paragraph 4, insert a new paragraph:
"The result values of some functions are described using pseudo-subscripts
(\textit(s_1) to \textit(s_n)) of the argument array(s). These should be
interpreted as if the lower bounds of the arrays were all equal to one."
[380:14-15] 19.9.68p5 (CSHIFT)
Replace:
"Case (i): If ARRAY has rank one, element i of the result is ARRAY (1 +
MODULO (i + SHIFT - 1, SIZE 15 (ARRAY)))."
with:
"Case (i): If ARRAY has rank one, element i of the result is ARRAY
(LBOUND(ARRAY,1) + MODULO (i + SHIFT - 1, SIZE (ARRAY)))
--END--