Transpose: Difference between revisions
(→Issues) 
m (Text replacement  "</source>" to "</syntaxhighlight>") 

Line 20:  Line 20:  
⍉1 2 3 ⍝ Unaffected  ⍉1 2 3 ⍝ Unaffected  
1 2 3  1 2 3  
</  </syntaxhighlight>  
=== Dyadic usage ===  === Dyadic usage ===  
{ class=wikitable style="width:50%;float:right"  { class=wikitable style="width:50%;float:right"  
{{quote  "Dyadic transpose, <source lang=apl inline>x⍉y</  {{quote  "Dyadic transpose, <source lang=apl inline>x⍉y</syntaxhighlight>, is probably one of the last primitives to be mastered for an APLer, but is actually straightforward to describe."<ref>[[Roger Hui]]. [https://forums.dyalog.com/viewtopic.php?f=30&t=1648 ''dyadic transpose, a personal history'']. Dyalog Forums. 22 May 2020.</ref>}}  
}  }  
For [[dyadic]] usage, the left argument X must be a [[vector]] whose length equals the [[rank]] of the right argument Y, and the elements must form a range so that <source lang=apl inline>∧/X∊⍳(1⎕IO)+⌈/X</  For [[dyadic]] usage, the left argument X must be a [[vector]] whose length equals the [[rank]] of the right argument Y, and the elements must form a range so that <source lang=apl inline>∧/X∊⍳(1⎕IO)+⌈/X</syntaxhighlight> is satisfied.  
If all values in X are unique (X forms a [[permutation]] over the axes of Y), the axes are reordered by X so that Nth element of X specifies the new position for the Nth axis of Y. This means that, given a multidimensional [[index]] V of an element in the resulting array, <source lang=apl inline>V⌷X⍉Y</  If all values in X are unique (X forms a [[permutation]] over the axes of Y), the axes are reordered by X so that Nth element of X specifies the new position for the Nth axis of Y. This means that, given a multidimensional [[index]] V of an element in the resulting array, <source lang=apl inline>V⌷X⍉Y</syntaxhighlight> corresponds to <source lang=apl inline>V[X]⍉Y</syntaxhighlight>.  
<source lang=apl>  <source lang=apl>  
Line 39:  Line 39:  
1 2 3[X]⌷Y ⍝ or Y[3;1;2]  1 2 3[X]⌷Y ⍝ or Y[3;1;2]  
P  P  
</  </syntaxhighlight>  
When X contains duplicates, the result has rank <source lang=apl inline>(1⎕IO)+⌈/X</  When X contains duplicates, the result has rank <source lang=apl inline>(1⎕IO)+⌈/X</syntaxhighlight>. For the axes of Y that map to the same resulting axis, only the elements where the indices are equal over those axes are collected. This has the effect of extracting diagonal elements. If the axes are of unequal length, the resulting axis has the length of the shortest of them. This operation can be modeled as computing the resulting shape <source lang=apl inline>(⍴Y)⌊.+(⌊/⍬)×X∘.≠(1⎕IO)+⍳⌈/X</syntaxhighlight>, then [[Index Generatorcreating the array of its multidimensional indices]] <source lang=apl inline>⍳</syntaxhighlight>, then modify each index and fetch the corresponding elements of Y <source lang=apl inline>{⍵[X]⌷Y}¨</syntaxhighlight>.  
<source lang=apl>  <source lang=apl>  
Line 53:  Line 53:  
(X⍉Y)≡{⍵[X]⌷Y}¨⍳(⍴Y)⌊.+(⌊/⍬)×X∘.≠(1⎕IO)+⍳⌈/X  (X⍉Y)≡{⍵[X]⌷Y}¨⍳(⍴Y)⌊.+(⌊/⍬)×X∘.≠(1⎕IO)+⍳⌈/X  
1  1  
</  </syntaxhighlight>{{Works in[[Dyalog APL]]}}  
== Issues ==  == Issues ==  
A common mistake in employing dyadic transpose is the "intuitive" interpretation of the left argument as if gives the order in which you want to select dimensions of the right argument for the result. In fact, it gives the new position of each of the dimensions. It is possible to convert between these two representations by "inverting" the permutation with monadic [[GradeGrade Up]] (<source lang=apl inline>⍋</  A common mistake in employing dyadic transpose is the "intuitive" interpretation of the left argument as if gives the order in which you want to select dimensions of the right argument for the result. In fact, it gives the new position of each of the dimensions. It is possible to convert between these two representations by "inverting" the permutation with monadic [[GradeGrade Up]] (<source lang=apl inline>⍋</syntaxhighlight>).  
The reason for the design of <source lang=apl inline>⍉</  The reason for the design of <source lang=apl inline>⍉</syntaxhighlight> being as it is, is that it allows you to select diagonals by giving one or more dimensions equal mapping, whereas simply selecting dimensions from the right would not allow that. It is therefore the more complete of the two options.<ref>[[Morten Kromberg]]. Message {{M57439754}}ff. [[APL Orchard]]. 25 Mar 2021.</ref>  
== External links ==  == External links == 
Revision as of 10:31, 11 September 2022
⍉

Transpose (⍉
) is an ambivalent primitive function which reorders the axes of the right argument array. The name Transpose comes from the fact that monadic application to a matrix yields its transpose. The dyadic usage is sometimes called Rearrange Axes, which better reflects the behavior of the function.
Examples
Monadic usage
Monadic Transpose reverses the axes of the right argument. When applied to a matrix, the result is its transpose. Scalar and vector arguments are unaffected.
<source lang=apl>
3 3⍴⍳9
1 2 3 4 5 6 7 8 9
⍉3 3⍴⍳9 ⍝ Transpose of a matrix
1 4 7 2 5 8 3 6 9
⍴⍉3 4 5⍴⎕A ⍝ The first axis goes last, the last axis comes first
5 4 3
⍉1 2 3 ⍝ Unaffected
1 2 3 </syntaxhighlight>
Dyadic usage

For dyadic usage, the left argument X must be a vector whose length equals the rank of the right argument Y, and the elements must form a range so that <source lang=apl inline>∧/X∊⍳(1⎕IO)+⌈/X</syntaxhighlight> is satisfied.
If all values in X are unique (X forms a permutation over the axes of Y), the axes are reordered by X so that Nth element of X specifies the new position for the Nth axis of Y. This means that, given a multidimensional index V of an element in the resulting array, <source lang=apl inline>V⌷X⍉Y</syntaxhighlight> corresponds to <source lang=apl inline>V[X]⍉Y</syntaxhighlight>.
<source lang=apl>
X←3 1 2 Y←3 4 5⍴⎕A ⍴X⍉Y ⍝ First axis goes to third (X[1] is 3), second goes to first (X[2] is 1), etc.
4 5 3
1 2 3⌷X⍉Y ⍝ or (X⍉Y)[1;2;3]
P
1 2 3[X]⌷Y ⍝ or Y[3;1;2]
P </syntaxhighlight>
When X contains duplicates, the result has rank <source lang=apl inline>(1⎕IO)+⌈/X</syntaxhighlight>. For the axes of Y that map to the same resulting axis, only the elements where the indices are equal over those axes are collected. This has the effect of extracting diagonal elements. If the axes are of unequal length, the resulting axis has the length of the shortest of them. This operation can be modeled as computing the resulting shape <source lang=apl inline>(⍴Y)⌊.+(⌊/⍬)×X∘.≠(1⎕IO)+⍳⌈/X</syntaxhighlight>, then creating the array of its multidimensional indices <source lang=apl inline>⍳</syntaxhighlight>, then modify each index and fetch the corresponding elements of Y <source lang=apl inline>{⍵[X]⌷Y}¨</syntaxhighlight>.
<source lang=apl>
1 1⍉3 4⍴⎕A ⍝ Extract diagonal from 3×4 matrix
AEI
Y←?3 4 5 6 7⍴100 X←3 2 3 1 2 ⍝ Left arg maps 5dimensional Y to 3 dimensions ⍴X⍉Y ⍝ Resulting shape is ⌊/¨6(4 7)(3 5)
6 4 3
(X⍉Y)≡{⍵[X]⌷Y}¨⍳(⍴Y)⌊.+(⌊/⍬)×X∘.≠(1⎕IO)+⍳⌈/X
1
</syntaxhighlight>
Issues
A common mistake in employing dyadic transpose is the "intuitive" interpretation of the left argument as if gives the order in which you want to select dimensions of the right argument for the result. In fact, it gives the new position of each of the dimensions. It is possible to convert between these two representations by "inverting" the permutation with monadic Grade Up (<source lang=apl inline>⍋</syntaxhighlight>).
The reason for the design of <source lang=apl inline>⍉</syntaxhighlight> being as it is, is that it allows you to select diagonals by giving one or more dimensions equal mapping, whereas simply selecting dimensions from the right would not allow that. It is therefore the more complete of the two options.^{[2]}
External links
Tutorials
Documentation
References
 ↑ Roger Hui. dyadic transpose, a personal history. Dyalog Forums. 22 May 2020.
 ↑ Morten Kromberg. Message 57439754ff. APL Orchard. 25 Mar 2021.