rslt ← {⍺←⊢} (new ##.at sel) old ⍝ Prefix-friendly @. [new] items replace [sel]ected items of [old] to produce [rslt]. Suggested by Aaron Hsu and Roger Hui, this model extends Dyalog's primitive @ operator with "prefix agreement" for both right-operand [sel]ection and left op- erand [new] values. In this model: the shape of a boolean selection mask can be any prefix of the shape of [old]: ¯¯¯¯¯ ¯¯¯¯¯ lcase at{1 0 1} 3 4⍴⎕A ⍝ vector (1 0 1) selection of matrix rows abcd ¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯ EFGH ijkl the shape of the [new] values can be any prefix of the shape of the selection: ¯¯¯¯¯ ¯¯¯¯¯ 'XY'at 1 3 ⊢3 4⍴'*' ⍝ vector 'XY' substitution of matrix rows XXXX ¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯ **** YYYY In detail: Selection right operand [sel] ----------------------------- 0. Nested choose/reach selection: behaves the same as for primitive operator @. at(2 2↑⍳⍴mat) ⍝ selects top-left corner of mat 1. Numeric scalar/vector: selects major cells, along the first axis of [old]. at(2×⍳⌊(≢A)÷2) ⍝ selects alternate major cells of array A The selection, to which left operand [new] is applied, has shape (U,V), where U is ≢⍵⍵ and V is 1↓⍴⍵. With the above alternate major cells example applied to an array of shape 10 20 30, the selection will have shape 5 20 30. 2. Function returning a bool mask of rank R: selects from the R-frame of [old]. at{3 4⍴0 1 1} ⍝ selects from the 3 4-frame of (say) a 3 4 5 6-array ¹ The selection, to which left operand [new] is applied, has shape U,V; U←+/,S; V←(⍴⍴S)↓⍴⍵; S←⍵⍵ ⍵ ⍝ where ";" means "where" ² With the above¹ example applied to an array of shape 3 4 5 6, the selection will be of shape: (+/,3 4⍴0 1 1),5 6 → 8 5 6. ²(muse: Historical note: Prior to the adoption of diamond (⋄) as a left-to-right statement separ- ator, Sigma APL used semicolon as a right-to-left separator. Diamond eventually triumphed because: "people read APL from left to right". This observation, applied to statement order, could have been motivated by the procedural mindset "first do this, then do this, then ..." in which we were all steeped at the time. Conversely, reading Sigma code from left to right now has a declarative feel if we read ";" as "where": x+x; x←4 ⍝ x plus x, where x denotes 4. ) ¯¯¯¯¯ Substitution left operand [new] ------------------------------- 1. If left operand [new] is an array, it is extended to fit the selection, as follows. 2. If the left operand is a function, it is applied to the selection, and its result [new] is extended to fit the selection, as follows. If [new] is of shape U and the selection is of shape (U,V) (where V can be ⍬), [new] is replicated along ≢V axes to fit the selection: ext ← new ∘.⊣ V⍴0 ⍝ new values extended to fit selection The selected values of [old] are substituted with the extended array items to produce [rslt]. A possible conformability indulgence ------------------------------------ Classic indexed assignment ignores unit (length=1) axes when checking conform- ability: M←3 4⍴⎕A ⍝ 3 4-matrix M[,2;] ← 1 4⍴'abcd' ⍝ 1 4-matrix replacement of 1 4-selection M[,2;] ← 'ijkl' ⍝ 4-vector replacement of 1 4-selection [at] could indulge its [new] array in similar fashion by ignoring any <1>s in the shape vector of the [sel]ection. This would mean that a single row matrix selection could be replaced with a _vector_: 'ijkl'at{0 1 0} M ⍝ vector at 1-row matrix selection ··· ¯¯¯¯¯¯ ¯¯¯¯¯¯ This would be achieved by changing the conformability code in the model from: ext ← new ∘.⊣ V⍴0 ⍝ new values extended to fit selection to: ext ← new ∘.⊣ (V~1)⍴0 ⍝ new values extended to fit selection ¯¯¯ Examples: ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ Selection conformability: 1 at {1 0 1} 3 4 5⍴0 ⍝ vector right operand 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 at {3 4⍴1 0} 3 4 5⍴0 ⍝ matrix right operand 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 at {3 4 5⍴1 0} 3 4 5⍴0 ⍝ rank-3 right operand 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 at {1} 3 4 5⍴0 ⍝ scalar right operand 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝⍝ Substitution conformability: 1 at {1 0 1} 3 4 5⍴0 ⍝ scalar left operand 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 at {1 0 1} 3 4 5⍴0 ⍝ vector left operand 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 (2 4⍴⍳8) at {1 0 1} 3 4 5⍴0 ⍝ matrix left operand 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 5 5 6 6 6 6 6 7 7 7 7 7 8 8 8 8 8 (2 4 5⍴⍳40) at {1 0 1} 3 4 5⍴0 ⍝ rank-3 left operand 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 See also: sam select Back to: contents Back to: Workspaces