J3/13-329r2 To: J3 From: Malcolm Cohen Subject: UK-08 - Generalized reduction intrinsic Date: 2013 October 17 Requirements and rationale -------------------------- See N1975. Specification -------------- Add an intrinsic function that reduces an array by a user-defined operation. Similarly to the other reduction intrinsic functions, (a) reduction of a single dimension shall be provided, and (b) use of a logical mask array shall be supported. The array to be reduced may be of any intrinsic or derived type. The result for reduction of a single element shall be that element. The result for reduction of zero elements shall be specifiable, and if not specified this result shall be processor dependent. The user-defined operation should be mathematically associative but need not be computationally associative. In order to facilitate reduction of arrays of such things as quaternions and matrices, commutativity will not be required; in this, REDUCE will be different from CO_REDUCE. When more than two elements are being reduced, the operation may be associatively applied to elements and intermediate results in any order that does not commute (swap) operands. For users who require evaluation in strict array element order, we could add an ORDERED=.TRUE. argument with that effect; to be most effective the actual argument should be required to be constant. However, we do not think that this case warrants the extra complication (and therefore it is not part of the specifications). Syntax ------ REDUCE ( ARRAY, OPERATION, DIM [, MASK ] [, IDENTITY]) or REDUCE ( ARRAY, OPERATION [, MASK ] [, IDENTITY]) The OPERATION function shall be pure, but need not be elemental. Edits (relative to 10-007r1) ---------------------------- [intro] Add a new extension description "The new intrinsic function REDUCE performs user-specified array reductions." [322] Add at the appropriate place in Table 3.1: "REDUCE & ( ARRAY, OPERATION, DIM [, MASK ] [, IDENTITY]) or ( ARRAY, OPERATION [, MASK] [, IDENTITY]) & T & General reduction of array \\". {NB: The line breaks here are immaterial, "&" indicates tab to the next column, "\\" means end of that row.} [382:2+] Add new subclause following 13.7.138: "13.7.138a REDUCE ( ARRAY, OPERATION, DIM [, MASK ] [, IDENTITY]) or REDUCE ( ARRAY, OPERATION [, MASK] [, IDENTITY]) <> General reduction of array. <> Transformational function. <> ARRAY shall be an array of any type. OPERATION shall be a pure function with two arguments of the same type and type parameters as ARRAY. Its result shall have the same type and type parameters as ARRAY. The arguments and result shall not be polymorphic. OPERATION should implement a mathematically associative operation. It need not be commutative. DIM shall be an integer scalar with a value in the range 1 <= DIM <= , where is the rank of ARRAY. MASK (optional) shall be of type logical and shall be conformable with ARRAY. IDENTITY (optional) shall be scalar with the same type and type parameters as ARRAY. <> The result is of the same type and kind type parameter as ARRAY. It is scalar if DIM does not appear; otherwise, the result has rank -1 and shape [d_1, d_2, ... , d_DIM-1, d_DIM+1, ... , d_n] where [d_1, d_2, ... , d_n] is the shape of ARRAY. <> Case (i): The result of REDUCE (ARRAY, OPERATION) over the sequence of values in ARRAY is the result of an iterative process. While the sequence has more than one element, each iteration involves the execution of r = OPERATION(x,y) for adjacent x and y in the sequence, and the subsequent replacement of x and y with r. The process continues until the sequence has only one element which is the value of the reduction. If the initial sequence is empty, the result has the value IDENTITY if IDENTITY is present, and is processor dependent otherwise. If OPERATION is not computationally associative, the value of the result is processor dependent. Case (ii): The result of REDUCE (ARRAY, OPERATION, MASK = MASK) is as for Case (i) except that the initial sequence is only those elements of ARRAY for which the corresponding elements of MASK is true. Case (iii): If ARRAY has rank one, REDUCE (ARRAY, OPERATION, DIM = DIM [, MASK = MASK]) has a value equal to that of REDUCE (ARRAY, OPERATION [,MASK = MASK]). Otherwise, the value of element (s_1, s_2, ... , s_DIM-1, s_DIM+1, ... , s_n) of REDUCE (ARRAY, OPERATION, DIM = DIM [ , MASK = MASK]) is equal to REDUCE (ARRAY (s_1, s_2, ... , s_DIM-1, :, s_DIM+1, ... ,s_n), OPERATION [, MASK=MASK(s_1, s_2, ... , s_DIM-1, :, s_DIM+1, ... , s_n)]). <> The following examples all use the function MY_MULT, which returns the product of its two integer arguments. Case (i): The value of REDUCE ([1, 2, 3], MY_MULT) is 6. Case (ii): REDUCE (C, MY_MULT, MASK= C > 0, IDENTITY=1) forms the product of the positive elements of C. Case (iii): If B is the array 1 3 5 2 4 6 REDUCE (B, MY_MULT, DIM = 1) is [2, 12, 30] and REDUCE (B, MY_MULT, DIM = 2) is [15, 48]." ===END===