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