https://aplwiki.com/api.php?action=feedcontributions&user=Hou32hou&feedformat=atomAPL Wiki - User contributions [en-gb]2024-03-28T10:03:37ZUser contributionsMediaWiki 1.38.2https://aplwiki.com/index.php?title=Scan&diff=7333Scan2021-09-09T12:47:08Z<p>Hou32hou: Created page with "{{Built-in|Scan|<nowiki>\</nowiki>}} is a monadic operator which takes a dyadic functions and produce a monadic function (<source lang=apl inline>\</source>). ==..."</p>
<hr />
<div>{{Built-in|Scan|<nowiki>\</nowiki>}} is a [[monadic operator]] which takes a [[dyadic function]]s and produce a [[monadic function]] (<source lang=apl inline>\</source>).<br />
<br />
== Explanation ==<br />
[[Scan]] is similar to [[Reduce]], however all the intermediate results will be retained. That being said, unlike [[Reduce]], [[Scan]] does not reduce the number of elements, i.e. performing [[Scan]] over a 10-elements [[array]] will produce a 10-elements [[array]]. <br />
<br />
== Examples ==<br />
<source lang=apl><br />
+\⍳5 ⍝ plus-scan over range of integer from 1 to 5<br />
1 3 6 10 15<br />
</source><br />
<br />
== Applications ==<br />
Removing disconnected trailing 1s from a [[boolean mask]]:<br />
<source lang=apl><br />
mask←1 1 1 1 0 1 1 0 0 1<br />
mask<br />
1 1 1 1 0 1 1 0 0 1<br />
∧\mask ⍝ and-scan mask<br />
1 1 1 1 0 0 0 0 0 0<br />
</source><br />
{{APL built-ins}}[[Category:Primitive operators]][[Category:Composition operators]]</div>Hou32houhttps://aplwiki.com/index.php?title=Over&diff=7332Over2021-09-09T12:35:29Z<p>Hou32hou: </p>
<hr />
<div>{{Built-in|Over|<nowiki>⍥</nowiki>}} is a [[dyadic operator]] which takes two [[function]]s and produce a [[function]] (<source lang=apl inline>⍥</source>).<br />
<br />
== Explanation ==<br />
When the resulting function is used [[monadic]]ally, it is the same as [[Atop]].<br />
{|<br />
|<source lang=apl> (g ⍥ h) ⍵</source>|| {{←→}} ||<source lang=apl>g (h ⍵)</source><br />
|}<br />
When the resulting function is used [[dyadic]]ally, then it forms an [[Over]] expression (which is the true purpose of this operator).<br />
{|<br />
|<source lang=apl>⍺ (g ⍥ h) ⍵</source>|| {{←→}} ||<source lang=apl>(h ⍺) g (h ⍵)</source><br />
|}<br />
<br />
== Examples ==<br />
<source lang=apl><br />
x←1 2 3<br />
y←4 5 6<br />
x +⍥(⌈/) y ⍝ add the max of x and max of y<br />
9<br />
⍝ same as<br />
(⌈/x)+⌈/y<br />
9<br />
</source><br />
{{APL built-ins}}[[Category:Primitive operators]][[Category:Composition operators]]</div>Hou32houhttps://aplwiki.com/index.php?title=Over&diff=7331Over2021-09-09T12:33:26Z<p>Hou32hou: Created page with "{{Built-in|Over|<nowiki>⍥</nowiki>}} is a dyadic operator which takes two functions and produce a function (<source lang=apl inline>⍥</source>). == Explanati..."</p>
<hr />
<div>{{Built-in|Over|<nowiki>⍥</nowiki>}} is a [[dyadic operator]] which takes two [[function]]s and produce a [[function]] (<source lang=apl inline>⍥</source>).<br />
<br />
== Explanation ==<br />
When the resulting function is used [[monadic]]ally, it is the same as [[Atop]].<br />
{|<br />
|<source lang=apl> (g ⍥ h) ⍵</source>|| {{←→}} ||<source lang=apl>g (h ⍵)</source><br />
|}<br />
When the resulting function is used [[dyadic]]ally, then it forms an [[Over]] expression (which is the true purpose of this operator).<br />
{|<br />
|<source lang=apl>⍺ (g ⍥ h) ⍵</source>|| {{←→}} ||<source lang=apl>(h ⍺) g (h ⍵)</source><br />
|}<br />
<br />
== Examples ==<br />
<source lang=apl><br />
x←1 2 3<br />
y←4 5 6<br />
x +⍥(⌈/) y ⍝ add the max of x and max of y<br />
9<br />
⍝ same as<br />
(⌈/x)+⌈/y<br />
9<br />
</source></div>Hou32houhttps://aplwiki.com/index.php?title=Commute&diff=7324Commute2021-09-08T03:18:11Z<p>Hou32hou: </p>
<hr />
<div>{{Built-in|Commute|⍨}} is a [[monadic operator]] that takes a [[dyadic function]] as operand and modifies how the argument(s) of its derived functions are used. If the derived function is used monadically, the argument is also used as left argument. This usage is also known as '''Self''' or, more informally, '''Selfie'''. If the derived function is used dyadically, the arguments are swapped. This usage is also known as '''Swap'''. The [[glyph]] is also used for [[Commute]].<br />
<br />
== Examples ==<br />
<br />
This decrements from the vector:<br />
<source lang=apl><br />
1 -⍨ 1 2 3<br />
0 1 2<br />
</source><br />
{{Works in|[[Dyalog APL]], [[dzaima/APL]], [[NARS2000]]}}<br />
Double:<br />
<source lang=apl><br />
+⍨1 2 3<br />
2 4 6<br />
</source><br />
{{Works in|[[Dyalog APL]], [[dzaima/APL]], [[NARS2000]]}}<br />
<br />
[[Commute]] can be used to emulate a <source lang=apl inline>f g h</source> [[Fork]] when combined with [[Compose]] (note the following code is not workable APL, but a series of evaluations):<br />
<source lang=apl><br />
g⍨∘f⍨∘h⍨ x <br />
x g⍨∘f⍨∘h x ⍝ the last ⍨ is being used monadically, i.e. Selfie<br />
x g⍨∘f⍨ h x<br />
(h x) g⍨∘f x ⍝ the last ⍨ is being used dyadically, i.e. Swap<br />
(h x) g⍨ (f x) <br />
(f x) g (h x) ⍝ the last ⍨ is being used dyadically, i.e. Swap<br />
</source><br />
<br />
== External links ==<br />
<br />
=== Lessons ===<br />
<br />
* [https://chat.stackexchange.com/rooms/52405/conversation/lesson-3-some-apl-operators-----#40900200 APL Cultivation]<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/latest/index.htm#Language/Primitive%20Operators/Commute.htm Dyalog]<br />
<br />
{{APL built-ins}}[[Category:Primitive operators]][[Category:Composition operators]]</div>Hou32houhttps://aplwiki.com/index.php?title=Commute&diff=7323Commute2021-09-08T03:17:17Z<p>Hou32hou: Added fork emulation</p>
<hr />
<div>{{Built-in|Commute|⍨}} is a [[monadic operator]] that takes a [[dyadic function]] as operand and modifies how the argument(s) of its derived functions are used. If the derived function is used monadically, the argument is also used as left argument. This usage is also known as '''Self''' or, more informally, '''Selfie'''. If the derived function is used dyadically, the arguments are swapped. This usage is also known as '''Swap'''. The [[glyph]] is also used for [[Commute]].<br />
<br />
== Examples ==<br />
<br />
This decrements from the vector:<br />
<source lang=apl><br />
1 -⍨ 1 2 3<br />
0 1 2<br />
</source><br />
{{Works in|[[Dyalog APL]], [[dzaima/APL]], [[NARS2000]]}}<br />
Double:<br />
<source lang=apl><br />
+⍨1 2 3<br />
2 4 6<br />
</source><br />
{{Works in|[[Dyalog APL]], [[dzaima/APL]], [[NARS2000]]}}<br />
<br />
[[Commute]] can be used to emulate a <source lang=apl inline>f g h</source> [[Fork]] when combined with [[Compose]]:<br />
<source lang=apl><br />
g⍨∘f⍨∘h⍨ x <br />
x g⍨∘f⍨∘h x ⍝ the last ⍨ is being used monadically, i.e. Selfie<br />
x g⍨∘f⍨ h x<br />
(h x) g⍨∘f x ⍝ the last ⍨ is being used dyadically, i.e. Swap<br />
(h x) g⍨ (f x) <br />
(f x) g (h x) the last ⍨ is being used dyadically, i.e. Swap<br />
</source><br />
<br />
== External links ==<br />
<br />
=== Lessons ===<br />
<br />
* [https://chat.stackexchange.com/rooms/52405/conversation/lesson-3-some-apl-operators-----#40900200 APL Cultivation]<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/latest/index.htm#Language/Primitive%20Operators/Commute.htm Dyalog]<br />
<br />
{{APL built-ins}}[[Category:Primitive operators]][[Category:Composition operators]]</div>Hou32houhttps://aplwiki.com/index.php?title=Beside&diff=7315Beside2021-09-06T10:18:07Z<p>Hou32hou: /* Examples */ should be monadic</p>
<hr />
<div>{{Built-in|Beside|∘}}, '''Compose''' or '''After''' is a [[primitive operator]]. It shares the glyph <source lang=apl inline>∘</source> with [[Bind]]. Called [[Dyadic function|dyadically]] with function operands <source lang=apl inline>f</source> and <source lang=apl inline>g</source>, it uses <source lang=apl inline>g</source> [[Monadic function|monadically]] to pre-processes the right argument before applying <source lang=apl inline>f</source> to the given left argument and pre-processed right argument. Called [[Monadic function|monadically]] with operands <source lang=apl inline>f</source> and <source lang=apl inline>g</source>, it applies <source lang=apl inline>f</source> to the result of applying <source lang=apl inline>g</source> to the argument.<br />
<br />
In usage, <source lang=apl inline>X f∘g Y</source> is equivalent to <source lang=apl inline>X f g Y</source>, and <source lang=apl inline>f∘g Y</source> is equivalent to <source lang=apl inline>f g Y</source>. Thus, beside can be defined as the [[dop]] <source lang=apl inline>{⍺←⊢ ⋄ ⍺ ⍺⍺ ⍵⍵ ⍵}</source>.<br />
<br />
== Examples ==<br />
When used [[monadic]]ally, <source lang=apl inline>f∘g</source> behaves the same as an [[atop]]:<br />
<br />
<source lang=apl><br />
-∘÷ 2 <br />
¯0.5<br />
⍝ same as<br />
-(÷2)<br />
¯0.5<br />
</source><br />
<br />
When used [[dyadic]]ally, <source lang=apl inline>f∘g</source> forms a dyadic [[hook]]:<br />
<br />
<source lang=apl><br />
'oy'≡∘⌽'yo'<br />
1<br />
⍝ same as<br />
'oy'≡⌽'yo'<br />
1<br />
</source><br />
<br />
When used monadically with [[Commute]], <source lang=apl inline>f∘g</source> forms a monadic [[hook]]:<br />
<source lang=apl><br />
≡∘⌽⍨'UwU'<br />
1<br />
⍝ same as this, because operators are left-associative, unlike functions which are right-associative<br />
(≡∘⌽)⍨'UwU'<br />
1<br />
⍝ same as<br />
'UwU'≡⌽'UwU'<br />
1<br />
</source><br />
<br />
== External links ==<br />
<br />
=== Lessons ===<br />
<br />
* [https://chat.stackexchange.com/rooms/52405/conversation/lesson-4-more-apl-operators--#41029677 APL Cultivation]<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/18.0/#Language/Primitive%20Operators/Beside.htm Dyalog]<br />
<br />
{{APL built-ins}}[[Category:Primitive operators]][[Category:Composition operators]]</div>Hou32houhttps://aplwiki.com/index.php?title=Beside&diff=7312Beside2021-09-06T09:03:15Z<p>Hou32hou: /* Examples */</p>
<hr />
<div>{{Built-in|Beside|∘}}, '''Compose''' or '''After''' is a [[primitive operator]]. It shares the glyph <source lang=apl inline>∘</source> with [[Bind]]. Called [[Dyadic function|dyadically]] with function operands <source lang=apl inline>f</source> and <source lang=apl inline>g</source>, it uses <source lang=apl inline>g</source> [[Monadic function|monadically]] to pre-processes the right argument before applying <source lang=apl inline>f</source> to the given left argument and pre-processed right argument. Called [[Monadic function|monadically]] with operands <source lang=apl inline>f</source> and <source lang=apl inline>g</source>, it applies <source lang=apl inline>f</source> to the result of applying <source lang=apl inline>g</source> to the argument.<br />
<br />
In usage, <source lang=apl inline>X f∘g Y</source> is equivalent to <source lang=apl inline>X f g Y</source>, and <source lang=apl inline>f∘g Y</source> is equivalent to <source lang=apl inline>f g Y</source>. Thus, beside can be defined as the [[dop]] <source lang=apl inline>{⍺←⊢ ⋄ ⍺ ⍺⍺ ⍵⍵ ⍵}</source>.<br />
<br />
== Examples ==<br />
When use [[monadic]]ally, <source lang=apl inline>f∘g</source> behaves the same as [https://en.wikipedia.org/wiki/Function_composition function compositian].<br />
<br />
<source lang=apl><br />
-∘÷ 2 <br />
¯0.5<br />
⍝ same as<br />
-(÷2)<br />
¯0.5<br />
</source><br />
<br />
When use [[dyadic]]ally, <br />
<br />
<source lang=apl><br />
'oy'≡∘⌽'yo'<br />
1<br />
⍝ same as<br />
'oy'≡⌽'yo'<br />
1<br />
</source><br />
<br />
When used with [[Commute]], <source lang=apl inline>f∘g</source> forms a [[Hook]].<br />
<source lang=apl><br />
≡∘⌽⍨'UwU'<br />
1<br />
⍝ same as this, because operator is left-associative, unlike functions which is right-associative<br />
'UwU'(≡∘⌽)⍨'UwU'<br />
1<br />
⍝ same as<br />
'UwU'≡⌽'UwU'<br />
1<br />
</source><br />
<br />
== External links ==<br />
<br />
=== Lessons ===<br />
<br />
* [https://chat.stackexchange.com/rooms/52405/conversation/lesson-4-more-apl-operators--#41029677 APL Cultivation]<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/18.0/#Language/Primitive%20Operators/Beside.htm Dyalog]<br />
<br />
{{APL built-ins}}[[Category:Primitive operators]][[Category:Composition operators]]</div>Hou32houhttps://aplwiki.com/index.php?title=Beside&diff=7311Beside2021-09-06T09:01:24Z<p>Hou32hou: fix the example related to hook</p>
<hr />
<div>{{Built-in|Beside|∘}}, '''Compose''' or '''After''' is a [[primitive operator]]. It shares the glyph <source lang=apl inline>∘</source> with [[Bind]]. Called [[Dyadic function|dyadically]] with function operands <source lang=apl inline>f</source> and <source lang=apl inline>g</source>, it uses <source lang=apl inline>g</source> [[Monadic function|monadically]] to pre-processes the right argument before applying <source lang=apl inline>f</source> to the given left argument and pre-processed right argument. Called [[Monadic function|monadically]] with operands <source lang=apl inline>f</source> and <source lang=apl inline>g</source>, it applies <source lang=apl inline>f</source> to the result of applying <source lang=apl inline>g</source> to the argument.<br />
<br />
In usage, <source lang=apl inline>X f∘g Y</source> is equivalent to <source lang=apl inline>X f g Y</source>, and <source lang=apl inline>f∘g Y</source> is equivalent to <source lang=apl inline>f g Y</source>. Thus, beside can be defined as the [[dop]] <source lang=apl inline>{⍺←⊢ ⋄ ⍺ ⍺⍺ ⍵⍵ ⍵}</source>.<br />
<br />
== Examples ==<br />
When use [[monadic]]ally, <source lang=apl inline>f∘g</source> behaves the same as [https://en.wikipedia.org/wiki/Function_composition function compositian].<br />
<br />
<source lang=apl><br />
-∘÷ 2 <br />
¯0.5<br />
⍝ same as<br />
-(÷2)<br />
¯0.5<br />
</source><br />
<br />
When use [[dyadic]]ally, <br />
<br />
<source lang=apl><br />
'oy'≡∘⌽'yo'<br />
1<br />
⍝ same as<br />
'oy'≡⌽'yo'<br />
1<br />
</source><br />
<br />
When used with [[Commute]], <source lang=apl inline>f∘g</source> forms a [[Hook]].<br />
<source lang=apl><br />
≡∘⌽⍨'UwU'<br />
1<br />
⍝ same as<br />
'UwU'≡⌽'UwU'<br />
1<br />
</source><br />
<br />
== External links ==<br />
<br />
=== Lessons ===<br />
<br />
* [https://chat.stackexchange.com/rooms/52405/conversation/lesson-4-more-apl-operators--#41029677 APL Cultivation]<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/18.0/#Language/Primitive%20Operators/Beside.htm Dyalog]<br />
<br />
{{APL built-ins}}[[Category:Primitive operators]][[Category:Composition operators]]</div>Hou32houhttps://aplwiki.com/index.php?title=Beside&diff=7310Beside2021-09-06T08:54:27Z<p>Hou32hou: Added examples</p>
<hr />
<div>{{Built-in|Beside|∘}}, '''Compose''' or '''After''' is a [[primitive operator]]. It shares the glyph <source lang=apl inline>∘</source> with [[Bind]]. Called [[Dyadic function|dyadically]] with function operands <source lang=apl inline>f</source> and <source lang=apl inline>g</source>, it uses <source lang=apl inline>g</source> [[Monadic function|monadically]] to pre-processes the right argument before applying <source lang=apl inline>f</source> to the given left argument and pre-processed right argument. Called [[Monadic function|monadically]] with operands <source lang=apl inline>f</source> and <source lang=apl inline>g</source>, it applies <source lang=apl inline>f</source> to the result of applying <source lang=apl inline>g</source> to the argument.<br />
<br />
In usage, <source lang=apl inline>X f∘g Y</source> is equivalent to <source lang=apl inline>X f g Y</source>, and <source lang=apl inline>f∘g Y</source> is equivalent to <source lang=apl inline>f g Y</source>. Thus, beside can be defined as the [[dop]] <source lang=apl inline>{⍺←⊢ ⋄ ⍺ ⍺⍺ ⍵⍵ ⍵}</source>.<br />
<br />
== Examples ==<br />
When use [[monadic]]ally, <source lang=apl inline>f∘g</source> behaves the same as [https://en.wikipedia.org/wiki/Function_composition function compositian].<br />
<br />
<source lang=apl><br />
-∘÷ 2 <br />
¯0.5<br />
⍝ same as<br />
-(÷2)<br />
¯0.5<br />
</source><br />
<br />
When use [[dyadic]]ally, <source lang=apl inline>f∘g</source> forms a [[Hook]].<br />
<br />
<source lang=apl><br />
'oy'≡∘⌽'yo'<br />
1<br />
⍝ same as<br />
'oy'≡⌽'yo'<br />
1<br />
</source><br />
<br />
== External links ==<br />
<br />
=== Lessons ===<br />
<br />
* [https://chat.stackexchange.com/rooms/52405/conversation/lesson-4-more-apl-operators--#41029677 APL Cultivation]<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/18.0/#Language/Primitive%20Operators/Beside.htm Dyalog]<br />
<br />
{{APL built-ins}}[[Category:Primitive operators]][[Category:Composition operators]]</div>Hou32houhttps://aplwiki.com/index.php?title=Inner_Product&diff=7307Inner Product2021-09-06T02:30:53Z<p>Hou32hou: /* Examples */</p>
<hr />
<div>{{Built-in|Inner Product|<nowiki>.</nowiki>}}, is a [[dyadic operator]], which will produce a [[dyadic function]] when applied with two [[dyadic function]]s. In APL, the inner product is a generalisation of the [https://en.wikipedia.org/wiki/Matrix_multiplication matrix product], which allows not only addition-multiplication, but any [[dyadic function]]s given.<br />
<br />
== Examples ==<br />
<source lang=apl><br />
x ← 1 2 3<br />
y ← 4 5 6<br />
x ,.(↓,) y ⍝ visualizing inner product<br />
┌─────────────┐<br />
│┌───┬───┬───┐│<br />
││1 4│2 5│3 6││<br />
│└───┴───┴───┘│<br />
└─────────────┘<br />
x+.×y ⍝ matrix multiplication<br />
32 <br />
</source><br />
<br />
Note that for inner product between N-dimensional arrays, their dimension must be compatible with each other. <br />
<br />
For example, when applying inner-product to a 2D array, the column count of the left array must match with the row count of the right array, otherwise we will get an error.<br />
<source lang=apl><br />
⎕ ← x ← 2 3⍴⍳10<br />
1 2 3<br />
4 5 6<br />
⎕ ← y ← 4 2⍴⍳10<br />
1 2<br />
3 4<br />
5 6<br />
7 8 <br />
x+.×y <br />
LENGTH ERROR<br />
x+.×y<br />
∧<br />
⎕ ← y ← 3 2⍴⍳10 ⍝ reshape y to be compatible with x<br />
x+.×y<br />
22 28<br />
49 64<br />
</source></div>Hou32houhttps://aplwiki.com/index.php?title=Inner_Product&diff=7306Inner Product2021-09-06T02:28:11Z<p>Hou32hou: Created page with "{{Built-in|Inner Product|<nowiki>.</nowiki>}}, is a dyadic operator, which will produce a dyadic function when applied with two dyadic functions. In APL, the inner..."</p>
<hr />
<div>{{Built-in|Inner Product|<nowiki>.</nowiki>}}, is a [[dyadic operator]], which will produce a [[dyadic function]] when applied with two [[dyadic function]]s. In APL, the inner product is a generalisation of the [https://en.wikipedia.org/wiki/Matrix_multiplication matrix product], which allows not only addition-multiplication, but any [[dyadic function]]s given.<br />
<br />
== Examples ==<br />
<source lang=apl><br />
x ← 1 2 3<br />
y ← 4 5 6<br />
x ,.(↓,) y ⍝ visualizing inner product<br />
┌─────────────┐<br />
│┌───┬───┬───┐│<br />
││1 4│2 5│3 6││<br />
│└───┴───┴───┘│<br />
└─────────────┘<br />
x+.×y ⍝ matrix multiplication<br />
32 <br />
</source><br />
<br />
Note that for inner product between N-dimensional arrays, their dimension must be compatible with each other. <br />
<br />
For example, when applying inner-product to a 2D array, the column count of the left array must match with the row count of the right array, otherwise we will get an error.<br />
<source lang=apl><br />
x ← 2 3⍴⍳10<br />
y ← 4 2⍴⍳19<br />
x+.×y <br />
LENGTH ERROR<br />
x+.×y<br />
∧<br />
y ← 3 2⍴⍳10 ⍝ reshape y to be compatible with x<br />
x+.×y<br />
22 28<br />
49 64<br />
</source></div>Hou32houhttps://aplwiki.com/index.php?title=Outer_Product&diff=7305Outer Product2021-09-06T02:14:27Z<p>Hou32hou: remove reference to matrix multiplication, that should be for Inner Product instead</p>
<hr />
<div>{{Built-in|Outer Product|<nowiki>∘.</nowiki>}}, or '''Table''' is a [[monadic operator]], which will produce a [[dyadic function]] when applied with a [[dyadic function]]. In short, outer product allows you to apply a given function on each element of the left array with each element of the right array. Basically, a shortcut for constructing nested [https://en.wikipedia.org/wiki/For_loop for loop]s.<br />
<br />
=== Syntax ===<br />
By right, a [[monadic operator]] should be a single [[glyph]], and the operand should be on the left. However, for [[backwards compatibility|historical reasons]], the outer product operator is not only a [[bi-glyph]] denoted as <source lang=apl inline>∘.</source>, the operand also appears on the right instead.<br />
<br />
Notably, this syntactical inconsistency is resolved in [[J]] and [[BQN]], where the outer product operator, called Table, and denoted <source lang=j inline>/</source> and <code>⌜</code> respectively, abide by the usual operator syntax.<br />
<br />
=== Examples ===<br />
<source lang=apl><br />
x ← 1 2 3<br />
y ← 4 5 6<br />
x ∘., y ⍝ visualizing outer product<br />
┌───┬───┬───┐<br />
│1 4│1 5│1 6│<br />
├───┼───┼───┤<br />
│2 4│2 5│2 6│<br />
├───┼───┼───┤<br />
│3 4│3 5│3 6│<br />
└───┴───┴───┘<br />
<br />
⍝ works for multi-dimensional arrays as well<br />
y←2 3 ⍴ 'abcdef'<br />
x←2 2 ⍴ ⍳4<br />
x∘.,y <br />
┌───┬───┬───┐<br />
│1 a│1 b│1 c│<br />
├───┼───┼───┤<br />
│1 d│1 e│1 f│<br />
└───┴───┴───┘<br />
┌───┬───┬───┐<br />
│2 a│2 b│2 c│<br />
├───┼───┼───┤<br />
│2 d│2 e│2 f│<br />
└───┴───┴───┘<br />
<br />
┌───┬───┬───┐<br />
│3 a│3 b│3 c│<br />
├───┼───┼───┤<br />
│3 d│3 e│3 f│<br />
└───┴───┴───┘<br />
┌───┬───┬───┐<br />
│4 a│4 b│4 c│<br />
├───┼───┼───┤<br />
│4 d│4 e│4 f│<br />
└───┴───┴───┘<br />
<br />
</source><br />
<br />
=== Applications ===<br />
Outer product is useful for solving problems that intuitively requires a [https://en.wikipedia.org/wiki/Time_complexity#Polynomial_time polynomial time] algorithm. <br />
However, this also indicates that such an algorithm might not be the fastest solution.<br />
<br />
For example, suppose we want to find duplicated elements in an non-[[nested array]]. Intuitively speaking, the easiest way to solve this problem is to compare each element of the array with all other elements, which is exactly what an outer product does.<br />
<source lang=apl><br />
x ← 1 2 3 2<br />
⎕ ← matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
1 0 0 0<br />
0 1 0 1<br />
0 0 1 0<br />
0 1 0 1<br />
⎕ ← count ← +/matrix ⍝ get the number of occurence of each element<br />
1 2 1 2<br />
⎕ ← indices ← count ≥ 2 ⍝ get the indices of elements which occured more than once<br />
0 1 0 1<br />
⎕ ← duplicated ← ∪ indices/x <br />
2<br />
<br />
∪((+/x∘.=x)≥2)/x ⍝ everything above in one line<br />
2<br />
(⊢∪⍤/⍨2≤(+/∘.=⍨)) x ⍝ point-free/tacit version<br />
2<br />
</source><br />
Using similar techniques, we can define a function that generates prime numbers by using an outer product of [[Residue]].<br />
<source lang=apl><br />
primes ← {x←1↓⍳⍵ ⋄ (2>+⌿0=x∘.|x)/x}<br />
primes 10<br />
2 3 5 7<br />
primes 20<br />
2 3 5 7 11 13 17 19<br />
</source> <br />
Again, using outer product might not yield the fastest solution. There are faster solutions such as [https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes].<br />
== External links ==<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/latest/#Language/Primitive%20Operators/Outer%20Product.htm Dyalog]<br />
* [https://microapl.com/apl_help/ch_020_020_890.htm APLX]<br />
* J [https://www.jsoftware.com/help/dictionary/d420.htm Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/slash#dyadic NuVoc]<br />
<br />
{{APL built-ins}}[[Category:Primitive operators]]</div>Hou32houhttps://aplwiki.com/index.php?title=Outer_Product&diff=7297Outer Product2021-09-05T09:58:40Z<p>Hou32hou: Added header</p>
<hr />
<div>{{Built-in|Outer Product|<nowiki>∘.</nowiki>}}, or '''Table''' is a [[monadic operator]], which will produce a [[dyadic function]] when applied with a [[dyadic function]]. In APL, the outer product is a generalisation of the [https://en.wikipedia.org/wiki/Matrix_multiplication matrix product], which allows not only multiplication, but any [[dyadic function]] given. In short, outer product allows you to apply a given function on each element of the left array with each element of the right array. Basically, a shortcut for constructing nested [https://en.wikipedia.org/wiki/For_loop for loop]s.<br />
<br />
=== Syntax ===<br />
By right, a [[monadic operator]] should be a monograph (i.e. consist of only one character), and the operand should be on the left. However, due to [[legacy reason]], the outer product operator is not only a [[diagraph]] denoted as <source lang=apl inline>∘.</source>, the operand also appears on the right instead.<br />
<br />
Notably, this syntactical inconsistency is resolved in [[BQN]], where the outer product operator <source lang=bqn inline>⌜</source> abides with the usual operator syntax. Also note that it is called table in BQN.<br />
<br />
=== Examples ===<br />
<source lang=apl><br />
x ← 1 2 3<br />
y ← 4 5 6<br />
x ∘., y ⍝ visualizing outer product<br />
┌───┬───┬───┐<br />
│1 4│1 5│1 6│<br />
├───┼───┼───┤<br />
│2 4│2 5│2 6│<br />
├───┼───┼───┤<br />
│3 4│3 5│3 6│<br />
└───┴───┴───┘<br />
x ∘.× y ⍝ matrix multiplication<br />
4 5 6<br />
8 10 12<br />
12 15 18<br />
<br />
⍝ works for multi-dimensional array as well<br />
y←2 3 ⍴ 'abcdef'<br />
x←2 2 ⍴ ⍳4<br />
x∘.,y <br />
┌───┬───┬───┐<br />
│1 a│1 b│1 c│<br />
├───┼───┼───┤<br />
│1 d│1 e│1 f│<br />
└───┴───┴───┘<br />
┌───┬───┬───┐<br />
│2 a│2 b│2 c│<br />
├───┼───┼───┤<br />
│2 d│2 e│2 f│<br />
└───┴───┴───┘<br />
<br />
┌───┬───┬───┐<br />
│3 a│3 b│3 c│<br />
├───┼───┼───┤<br />
│3 d│3 e│3 f│<br />
└───┴───┴───┘<br />
┌───┬───┬───┐<br />
│4 a│4 b│4 c│<br />
├───┼───┼───┤<br />
│4 d│4 e│4 f│<br />
└───┴───┴───┘<br />
<br />
</source><br />
<br />
=== Applications ===<br />
Outer product is useful for solving problems that intuitively requires a [https://en.wikipedia.org/wiki/Time_complexity#Polynomial_time polynomial time] algorithm. <br />
However, this also indicates that such algorithm might not be the fastest solution.<br />
<br />
For example, suppose we want to find duplicated elements in an non-[[nested array]]. Intuitively speaking, the easiest way to solve this problem is to compare each element of the array with all other elements, which is exactly what an outer product does.<br />
<source lang=apl><br />
x ← 1 2 3 2<br />
⎕ ← matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
1 0 0 0<br />
0 1 0 1<br />
0 0 1 0<br />
0 1 0 1<br />
⎕ ← count ← +/matrix ⍝ get the number of occurence of each element<br />
1 2 1 2<br />
⎕ ← indices ← count ≥ 2 ⍝ get the indices of elements which occured more than once<br />
0 1 0 1<br />
⎕ ← duplicated ← ∪ indices/x <br />
2<br />
<br />
∪((+/x∘.=x)≥2)/x ⍝ everything above in one line<br />
2 (∪((2≤(+/∘.=⍨))(/⍨⍨)⊢)) x ⍝ point-free/tacit version<br />
2<br />
</source><br />
''Note: due to [[function-operator overloading]]'', to use [[replicate]] in a [[fork]], we have to use the workaround <source lang=apl inline>/⍨⍨</source>.<br />
<br />
Using similar techniques, we can define a function that generate prime numbers by using an outer product of [[Residue]].<br />
<source lang=apl><br />
primes ← {x←1↓⍳⍵ ⋄ (2>+⌿0=x∘.|x)/x}<br />
primes 10<br />
2 3 5 7<br />
primes 20<br />
2 3 5 7 11 13 17 19<br />
</source> <br />
Again, using outer product might not yield the fastest solution. There are faster solutions such as [https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes].</div>Hou32houhttps://aplwiki.com/index.php?title=Outer_Product&diff=7296Outer Product2021-09-05T09:44:59Z<p>Hou32hou: </p>
<hr />
<div>== Outer Product ==<br />
Outer product is a [[monadic operator]], which will produce a [[dyadic function]] when applied with a [[dyadic function]]. In APL, the outer product is a generalisation of the [https://en.wikipedia.org/wiki/Matrix_multiplication matrix product], which allows not only multiplication, but any [[dyadic function]] given. In short, outer product allows you to apply a given function on each element of the left array with each element of the right array. Basically, a shortcut for constructing nested [https://en.wikipedia.org/wiki/For_loop for loop]s.<br />
<br />
=== Syntax ===<br />
By right, a [[monadic operator]] should be a monograph (i.e. consist of only one character), and the operand should be on the left. However, due to [[legacy reason]], the outer product operator is not only a [[diagraph]] denoted as <source lang=apl inline>∘.</source>, the operand also appears on the right instead.<br />
<br />
Notably, this syntactical inconsistency is resolved in [[BQN]], where the outer product operator <source lang=bqn inline>⌜</source> abides with the usual operator syntax. Also note that it is called table in BQN.<br />
<br />
=== Examples ===<br />
<source lang=apl><br />
x ← 1 2 3<br />
y ← 4 5 6<br />
x ∘., y ⍝ visualizing outer product<br />
┌───┬───┬───┐<br />
│1 4│1 5│1 6│<br />
├───┼───┼───┤<br />
│2 4│2 5│2 6│<br />
├───┼───┼───┤<br />
│3 4│3 5│3 6│<br />
└───┴───┴───┘<br />
x ∘.× y ⍝ matrix multiplication<br />
4 5 6<br />
8 10 12<br />
12 15 18<br />
<br />
⍝ works for multi-dimensional array as well<br />
y←2 3 ⍴ 'abcdef'<br />
x←2 2 ⍴ ⍳4<br />
x∘.,y <br />
┌───┬───┬───┐<br />
│1 a│1 b│1 c│<br />
├───┼───┼───┤<br />
│1 d│1 e│1 f│<br />
└───┴───┴───┘<br />
┌───┬───┬───┐<br />
│2 a│2 b│2 c│<br />
├───┼───┼───┤<br />
│2 d│2 e│2 f│<br />
└───┴───┴───┘<br />
<br />
┌───┬───┬───┐<br />
│3 a│3 b│3 c│<br />
├───┼───┼───┤<br />
│3 d│3 e│3 f│<br />
└───┴───┴───┘<br />
┌───┬───┬───┐<br />
│4 a│4 b│4 c│<br />
├───┼───┼───┤<br />
│4 d│4 e│4 f│<br />
└───┴───┴───┘<br />
<br />
</source><br />
<br />
=== Applications ===<br />
Outer product is useful for solving problems that intuitively requires a [https://en.wikipedia.org/wiki/Time_complexity#Polynomial_time polynomial time] algorithm. <br />
However, this also indicates that such algorithm might not be the fastest solution.<br />
<br />
For example, suppose we want to find duplicated elements in an non-[[nested array]]. Intuitively speaking, the easiest way to solve this problem is to compare each element of the array with all other elements, which is exactly what an outer product does.<br />
<source lang=apl><br />
x ← 1 2 3 2<br />
⎕ ← matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
1 0 0 0<br />
0 1 0 1<br />
0 0 1 0<br />
0 1 0 1<br />
⎕ ← count ← +/matrix ⍝ get the number of occurence of each element<br />
1 2 1 2<br />
⎕ ← indices ← count ≥ 2 ⍝ get the indices of elements which occured more than once<br />
0 1 0 1<br />
⎕ ← duplicated ← ∪ indices/x <br />
2<br />
<br />
∪((+/x∘.=x)≥2)/x ⍝ everything above in one line<br />
2 (∪((2≤(+/∘.=⍨))(/⍨⍨)⊢)) x ⍝ point-free/tacit version<br />
2<br />
</source><br />
''Note: due to [[function-operator overloading]]'', to use [[replicate]] in a [[fork]], we have to use the workaround <source lang=apl inline>/⍨⍨</source>.<br />
<br />
Using similar techniques, we can define a function that generate prime numbers by using an outer product of [[Residue]].<br />
<source lang=apl><br />
primes ← {x←1↓⍳⍵ ⋄ (2>+⌿0=x∘.|x)/x}<br />
primes 10<br />
2 3 5 7<br />
primes 20<br />
2 3 5 7 11 13 17 19<br />
</source> <br />
Again, using outer product might not yield the fastest solution. There are faster solutions such as [https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes].</div>Hou32houhttps://aplwiki.com/index.php?title=Outer_Product&diff=7295Outer Product2021-09-05T09:38:05Z<p>Hou32hou: </p>
<hr />
<div>== Outer Product ==<br />
Outer product is a [[monadic operator]], which will produce a [[dyadic function]] when applied with a [[dyadic function]]. In APL, the outer product is a generalisation of the [https://en.wikipedia.org/wiki/Matrix_multiplication matrix product], which allows not only multiplication, but any [[dyadic function]] given. In short, outer product allows you to apply a given function for each element from the left array with each element to the right array.<br />
<br />
=== Syntax ===<br />
By right, a [[monadic operator]] should be a monograph (i.e. consist of only one character), and the operand should be on the left. However, due to [[legacy reason]], the outer product operator is not only a [[diagraph]] denoted as <source lang=apl inline>∘.</source>, the operand also appears on the right.<br />
<br />
Notably, this syntactical inconsistency is resolved in [[BQN]], where the outer product operator <source lang=bqn inline>⌜</source> abides with the usual operator syntax. Also note that it is called table in BQN.<br />
<br />
=== Examples ===<br />
<source lang=apl><br />
x ← 1 2 3<br />
y ← 4 5 6<br />
x ∘., y ⍝ visualizing outer product<br />
┌───┬───┬───┐<br />
│1 4│1 5│1 6│<br />
├───┼───┼───┤<br />
│2 4│2 5│2 6│<br />
├───┼───┼───┤<br />
│3 4│3 5│3 6│<br />
└───┴───┴───┘<br />
x ∘.× y ⍝ matrix multiplication<br />
4 5 6<br />
8 10 12<br />
12 15 18<br />
<br />
⍝ works for multi-dimensional array as well<br />
y←2 3 ⍴ 'abcdef'<br />
x←2 2 ⍴ ⍳4<br />
x∘.,y <br />
┌───┬───┬───┐<br />
│1 a│1 b│1 c│<br />
├───┼───┼───┤<br />
│1 d│1 e│1 f│<br />
└───┴───┴───┘<br />
┌───┬───┬───┐<br />
│2 a│2 b│2 c│<br />
├───┼───┼───┤<br />
│2 d│2 e│2 f│<br />
└───┴───┴───┘<br />
<br />
┌───┬───┬───┐<br />
│3 a│3 b│3 c│<br />
├───┼───┼───┤<br />
│3 d│3 e│3 f│<br />
└───┴───┴───┘<br />
┌───┬───┬───┐<br />
│4 a│4 b│4 c│<br />
├───┼───┼───┤<br />
│4 d│4 e│4 f│<br />
└───┴───┴───┘<br />
<br />
</source><br />
<br />
=== Applications ===<br />
Outer product is useful for solving problems that intuitively requires a [https://en.wikipedia.org/wiki/Time_complexity#Polynomial_time polynomial time] algorithm. <br />
However, this also indicates that such algorithm might not be the fastest solution.<br />
<br />
For example, suppose we want to find duplicated elements in an non-[[nested array]]. Intuitively speaking, the easiest way to solve this problem is to compare each element of the array with all other elements, which is exactly what an outer product does.<br />
<source lang=apl><br />
x ← 1 2 3 2<br />
⎕ ← matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
1 0 0 0<br />
0 1 0 1<br />
0 0 1 0<br />
0 1 0 1<br />
⎕ ← count ← +/matrix ⍝ get the number of occurence of each element<br />
1 2 1 2<br />
⎕ ← indices ← count ≥ 2 ⍝ get the indices of elements which occured more than once<br />
0 1 0 1<br />
⎕ ← duplicated ← ∪ indices/x <br />
2<br />
<br />
∪((+/x∘.=x)≥2)/x ⍝ everything above in one line<br />
2 (∪((2≤(+/∘.=⍨))(/⍨⍨)⊢)) x ⍝ point-free/tacit version<br />
2<br />
</source><br />
''Note: due to [[function-operator overloading]]'', to use [[replicate]] in a [[fork]], we have to use the workaround <source lang=apl inline>/⍨⍨</source>.<br />
<br />
Using similar techniques, we can define a function that generate prime numbers by using an outer product of [[Residue]].<br />
<source lang=apl><br />
primes ← {x←1↓⍳⍵ ⋄ (2>+⌿0=x∘.|x)/x}<br />
primes 10<br />
2 3 5 7<br />
primes 20<br />
2 3 5 7 11 13 17 19<br />
</source> <br />
Again, using outer product might not yield the fastest solution. There are faster solutions such as [https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes].</div>Hou32houhttps://aplwiki.com/index.php?title=Outer_Product&diff=7294Outer Product2021-09-05T09:29:50Z<p>Hou32hou: remove duplicated code</p>
<hr />
<div>== Outer Product ==<br />
<br />
Outer product is a [[monadic operator]], which will produce a [[dyadic function]] when applied with a [[dyadic function]]. In APL, the outer product is a generalisation of the [https://en.wikipedia.org/wiki/Matrix_multiplication matrix product], which allows not only multiplication, but any [[dyadic function]] given.<br />
<br />
=== Syntax ===<br />
By right, a [[monadic operator]] should be a monograph (i.e. consist of only one character), and the operand should be on the left. However, due to [[legacy reason]], the outer product operator is not only a [[diagraph]] denoted as <source lang=apl inline>∘.</source>, the operand also appears on the right.<br />
<br />
Notably, this syntactical inconsistency is resolved in [[BQN]], where the outer product operator <source lang=bqn inline>⌜</source> abides with the usual operator syntax. Also note that it is called table in BQN.<br />
<br />
=== Examples ===<br />
<source lang=apl><br />
x ← 1 2 3<br />
y ← 4 5 6<br />
x ∘., y ⍝ visualizing outer product<br />
┌───┬───┬───┐<br />
│1 4│1 5│1 6│<br />
├───┼───┼───┤<br />
│2 4│2 5│2 6│<br />
├───┼───┼───┤<br />
│3 4│3 5│3 6│<br />
└───┴───┴───┘<br />
x ∘.× y ⍝ matrix multiplication<br />
4 5 6<br />
8 10 12<br />
12 15 18<br />
</source><br />
<br />
=== Applications ===<br />
Outer product is useful for solving problems that intuitively requires a [https://en.wikipedia.org/wiki/Time_complexity#Polynomial_time polynomial time] algorithm. <br />
However, this also indicates that such algorithm might not be the fastest solution.<br />
<br />
For example, suppose we want to find duplicated elements in an non-[[nested array]]. Intuitively speaking, the easiest way to solve this problem is to compare each element of the array with all other elements, which is exactly what an outer product does.<br />
<source lang=apl><br />
x ← 1 2 3 2<br />
⎕ ← matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
1 0 0 0<br />
0 1 0 1<br />
0 0 1 0<br />
0 1 0 1<br />
⎕ ← count ← +/matrix ⍝ get the number of occurence of each element<br />
1 2 1 2<br />
⎕ ← indices ← count ≥ 2 ⍝ get the indices of elements which occured more than once<br />
0 1 0 1<br />
⎕ ← duplicated ← ∪ indices/x <br />
2<br />
<br />
∪((+/x∘.=x)≥2)/x ⍝ everything above in one line<br />
2 (∪((2≤(+/∘.=⍨))(/⍨⍨)⊢)) x ⍝ point-free/tacit version<br />
2<br />
</source><br />
''Note: due to [[function-operator overloading]]'', to use [[replicate]] in a [[fork]], we have to use the workaround <source lang=apl inline>/⍨⍨</source>.<br />
<br />
Using similar techniques, we can define a function that generate prime numbers by using an outer product of [[Residue]].<br />
<source lang=apl><br />
primes ← {x←1↓⍳⍵ ⋄ (2>+⌿0=x∘.|x)/x}<br />
primes 10<br />
2 3 5 7<br />
primes 20<br />
2 3 5 7 11 13 17 19<br />
</source> <br />
Again, using outer product might not yield the fastest solution. There are faster solutions such as [https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes].</div>Hou32houhttps://aplwiki.com/index.php?title=Outer_Product&diff=7293Outer Product2021-09-05T09:20:06Z<p>Hou32hou: Added prime number example</p>
<hr />
<div>== Outer Product ==<br />
<br />
Outer product is a [[monadic operator]], which will produce a [[dyadic function]] when applied with a [[dyadic function]]. In APL, the outer product is a generalisation of the [https://en.wikipedia.org/wiki/Matrix_multiplication matrix product], which allows not only multiplication, but any [[dyadic function]] given.<br />
<br />
=== Syntax ===<br />
By right, a [[monadic operator]] should be a monograph (i.e. consist of only one character), and the operand should be on the left. However, due to [[legacy reason]], the outer product operator is not only a [[diagraph]] denoted as <source lang=apl inline>∘.</source>, the operand also appears on the right.<br />
<br />
Notably, this syntactical inconsistency is resolved in [[BQN]], where the outer product operator <source lang=bqn inline>⌜</source> abides with the usual operator syntax. Also note that it is called table in BQN.<br />
<br />
=== Examples ===<br />
<source lang=apl><br />
x ← 1 2 3<br />
y ← 4 5 6<br />
x ∘., y ⍝ visualizing outer product<br />
┌───┬───┬───┐<br />
│1 4│1 5│1 6│<br />
├───┼───┼───┤<br />
│2 4│2 5│2 6│<br />
├───┼───┼───┤<br />
│3 4│3 5│3 6│<br />
└───┴───┴───┘<br />
x ∘.× y ⍝ matrix multiplication<br />
4 5 6<br />
8 10 12<br />
12 15 18<br />
</source><br />
<br />
=== Applications ===<br />
Outer product is useful for solving problems that intuitively requires a [https://en.wikipedia.org/wiki/Time_complexity#Polynomial_time polynomial time] algorithm. <br />
However, this also indicates that such algorithm might not be the fastest solution.<br />
<br />
For example, suppose we want to find duplicated elements in an non-[[nested array]]. Intuitively speaking, the easiest way to solve this problem is to compare each element of the array with all other elements, which is exactly what an outer product does.<br />
<source lang=apl><br />
x ← 1 2 3 2<br />
matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
count ← +/matrix ⍝ get the number of occurence of each element<br />
x ← 1 2 3 2<br />
⎕ ← matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
1 0 0 0<br />
0 1 0 1<br />
0 0 1 0<br />
0 1 0 1<br />
⎕ ← count ← +/matrix ⍝ get the number of occurence of each element<br />
1 2 1 2<br />
⎕ ← indices ← count ≥ 2 ⍝ get the indices of elements which occured more than once<br />
0 1 0 1<br />
⎕ ← duplicated ← ∪ indices/x <br />
2<br />
<br />
∪((+/x∘.=x)≥2)/x ⍝ everything above in one line<br />
2 (∪((2≤(+/∘.=⍨))(/⍨⍨)⊢)) x ⍝ point-free/tacit version<br />
2<br />
</source><br />
''Note: due to [[function-operator overloading]]'', to use [[replicate]] in a [[fork]], we have to use the workaround <source lang=apl inline>/⍨⍨</source>.<br />
<br />
Using similar techniques, we can define a function that generate prime numbers by using an outer product of [[Residue]].<br />
<source lang=apl><br />
primes ← {x←1↓⍳⍵ ⋄ (2>+⌿0=x∘.|x)/x}<br />
primes 10<br />
2 3 5 7<br />
primes 20<br />
2 3 5 7 11 13 17 19<br />
</source> <br />
Again, using outer product might not yield the fastest solution. There are faster solutions such as [https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes Sieve of Eratosthenes].</div>Hou32houhttps://aplwiki.com/index.php?title=Outer_Product&diff=7292Outer Product2021-09-05T09:04:28Z<p>Hou32hou: /* Application */ Added tacit version of dedup</p>
<hr />
<div>== Outer Product ==<br />
<br />
Outer product is a [[monadic operator]], which will produce a [[dyadic function]] when applied with a [[dyadic function]]. In APL, the outer product is a generalisation of the [https://en.wikipedia.org/wiki/Matrix_multiplication matrix product], which allows not only multiplication, but any [[dyadic function]] given.<br />
<br />
=== Syntax ===<br />
By right, a [[monadic operator]] should be a monograph (i.e. consist of only one character), and the operand should be on the left. However, due to [[legacy reason]], the outer product operator is not only a [[diagraph]] denoted as <source lang=apl inline>∘.</source>, the operand also appears on the right.<br />
<br />
Notably, this syntactical inconsistency is resolved in [[BQN]], where the outer product operator <source lang=bqn inline>⌜</source> abides with the usual operator syntax. Also note that it is called table in BQN.<br />
<br />
=== Examples ===<br />
<source lang=apl><br />
x ← 1 2 3<br />
y ← 4 5 6<br />
x ∘., y ⍝ visualizing outer product<br />
┌───┬───┬───┐<br />
│1 4│1 5│1 6│<br />
├───┼───┼───┤<br />
│2 4│2 5│2 6│<br />
├───┼───┼───┤<br />
│3 4│3 5│3 6│<br />
└───┴───┴───┘<br />
x ∘.× y ⍝ matrix multiplication<br />
4 5 6<br />
8 10 12<br />
12 15 18<br />
</source><br />
<br />
=== Applications ===<br />
Outer product is useful for solving problems that intuitively requires a [https://en.wikipedia.org/wiki/Time_complexity#Polynomial_time polynomial time] algorithm. <br />
However, this also indicates that such algorithm might not be the fastest solution.<br />
<br />
For example, suppose we want to find duplicated elements in an non-[[nested array]]. Intuitively speaking, the easiest way to solve this problem is to compare each element of the array with all other elements, which is exactly what an outer product does.<br />
<source lang=apl><br />
x ← 1 2 3 2<br />
matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
count ← +/matrix ⍝ get the number of occurence of each element<br />
x ← 1 2 3 2<br />
⎕ ← matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
1 0 0 0<br />
0 1 0 1<br />
0 0 1 0<br />
0 1 0 1<br />
⎕ ← count ← +/matrix ⍝ get the number of occurence of each element<br />
1 2 1 2<br />
⎕ ← indices ← count ≥ 2 ⍝ get the indices of elements which occured more than once<br />
0 1 0 1<br />
⎕ ← duplicated ← ∪ indices/x <br />
2<br />
<br />
∪((+/x∘.=x)≥2)/x ⍝ everything above in one line<br />
2 (∪((2≤(+/∘.=⍨))(/⍨⍨)⊢)) x ⍝ point-free/tacit version<br />
2<br />
</source><br />
''Note: due to [[function-operator overloading]]'', to use [[replicate]] in a [[fork]], we have to use the workaround <source lang=apl inline>/⍨⍨</source>.</div>Hou32houhttps://aplwiki.com/index.php?title=Outer_Product&diff=7291Outer Product2021-09-05T08:46:48Z<p>Hou32hou: Added the Outer Product wiki page</p>
<hr />
<div>== Outer Product ==<br />
<br />
Outer product is a [[monadic operator]], which will produce a [[dyadic function]] when applied with a [[dyadic function]]. In APL, the outer product is a generalisation of the [https://en.wikipedia.org/wiki/Matrix_multiplication matrix product], which allows not only multiplication, but any [[dyadic function]] given.<br />
<br />
=== Syntax ===<br />
By right, a [[monadic operator]] should be a monograph (i.e. consist of only one character), and the operand should be on the left. However, due to [[legacy reason]], the outer product operator is not only a [[diagraph]] denoted as <source lang=apl inline>∘.</source>, the operand also appears on the right.<br />
<br />
Notably, this syntactical inconsistency is resolved in [[BQN]], where the outer product operator <source lang=bqn inline>⌜</source> abides with the usual operator syntax. Also note that it is called table in BQN.<br />
<br />
=== Examples ===<br />
<source lang=apl><br />
x ← 1 2 3<br />
y ← 4 5 6<br />
x ∘., y ⍝ visualizing outer product<br />
┌───┬───┬───┐<br />
│1 4│1 5│1 6│<br />
├───┼───┼───┤<br />
│2 4│2 5│2 6│<br />
├───┼───┼───┤<br />
│3 4│3 5│3 6│<br />
└───┴───┴───┘<br />
x ∘.× y ⍝ matrix multiplication<br />
4 5 6<br />
8 10 12<br />
12 15 18<br />
</source><br />
<br />
=== Application ===<br />
Outer product is useful for solving problems that intuitively requires a [https://en.wikipedia.org/wiki/Time_complexity#Polynomial_time polynomial time] algorithm. <br />
However, this also indicates that such algorithm might not be the fastest solution.<br />
<br />
For example, suppose we want to find duplicated elements in an non-[[nested array]]. Intuitively speaking, the easiest way to solve this problem is to compare each element of the array with all other elements, which is exactly what an outer product does.<br />
<source lang=apl><br />
x ← 1 2 3 2<br />
matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
count ← +/matrix ⍝ get the number of occurence of each element<br />
x ← 1 2 3 2<br />
⎕ ← matrix ← x∘.=x ⍝ compare elements with each other using equal<br />
1 0 0 0<br />
0 1 0 1<br />
0 0 1 0<br />
0 1 0 1<br />
⎕ ← count ← +/matrix ⍝ get the number of occurence of each element<br />
1 2 1 2<br />
⎕ ← indices ← count ≥ 2 ⍝ get the indices of elements which occured more than once<br />
0 1 0 1<br />
⎕ ← duplicated ← ∪ indices/x <br />
2<br />
<br />
∪((+/x∘.=x)≥2)/x ⍝ everything above in one line<br />
2<br />
</source></div>Hou32houhttps://aplwiki.com/index.php?title=John_Scholes%27_Conway%27s_Game_of_Life&diff=7290John Scholes' Conway's Game of Life2021-09-05T07:50:52Z<p>Hou32hou: Added references to Index Origin</p>
<hr />
<div>Perhaps the most famous APL video is [[John Scholes]] explaining his own implementation of [[Conway's Game of Life]] in [[Dyalog APL]].<ref>[[John Scholes|Scholes, John]]. [https://www.youtube.com/watch?v=a9xAKttWgP4 "Conway's Game of Life in APL"]. 2009-01-26.</ref> In the video, Scholes develops the following [[dfn]] one step at a time:<br />
<source lang=apl><br />
life ← {⊃1 ⍵ ∨.∧ 3 4 = +/ +⌿ ¯1 0 1 ∘.⊖ ¯1 0 1 ⌽¨ ⊂⍵}<br />
</source><br />
<br />
Scholes also published notes<ref>[[John Scholes|Scholes, John]]. [http://dfns.dyalog.com/n_life.htm life] in the [[dfns workspace]].</ref> on the Game of Life, including alternate implementations, in his [[dfns workspace]]. The workspace includes a function which differs in a few small details.<br />
<source lang=apl><br />
Life←{↑1 ⍵∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵}<br />
</source><br />
<br />
In this page we will break down the function <source lang=apl inline>Life</source> to see how each part operates. If you're completely new to APL, you probably won't understand all of it right away—consider also reading some [[Simple examples]] or APL [[introductions]]. However, you should be able to follow the general ideas. Bear in mind that APL evaluates expressions from [[Evaluation order|right to left]] unless you use parentheses.<br />
<br />
The code here is written for [[Dyalog APL]]. It also works in [[ngn/apl]], and other [[Nested array theory|nested]] array languages allow similar implementations: see [[#Translations]].<br />
<br />
In 2021, Conor Hoekstra remade the video with additional explanations.<ref>Hoekstra, Conor. [https://www.youtube.com/watch?v=pMslgySQ8nc APL + Game of Life = ❤️] in the [https://www.youtube.com/channel/UC1kBxkk2bcG78YBX7LMl9pQ code_report YouTube channel]. 2021-04-25.</ref><br />
<br />
== The Glider ==<br />
<br />
One interesting pattern that occurs in Life is a [[wikipedia:Glider (Conway's Life)|Glider]]:<br />
<source lang=apl><br />
glider←3 3⍴1 1 1 1 0 0 0 1 0<br />
glider<br />
1 1 1<br />
1 0 0<br />
0 1 0<br />
</source><br />
<br />
To see how the Glider evolves over the generations, we need to give it some space to move around. The Game of Life takes place on an infinite two-dimensional grid, but that might be a bit large for our computer! Let's start the Glider off in the bottom right-hand corner of a 10 x 10 grid:<br />
<source lang=apl><br />
grid←¯10 ¯10↑glider<br />
grid<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 1 1 1<br />
0 0 0 0 0 0 0 1 0 0<br />
0 0 0 0 0 0 0 0 1 0<br />
</source><br />
<br />
After one generation the pattern becomes:<br />
<source lang=apl><br />
Life grid<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 0 0<br />
0 0 0 0 0 0 0 0 1 0<br />
0 0 0 0 0 0 0 1 1 0<br />
0 0 0 0 0 0 0 1 0 1<br />
0 0 0 0 0 0 0 0 0 0<br />
</source><br />
<br />
The Glider has slightly changed shape and also moved up and to the left.<br />
<br />
=== Visualising it ===<br />
<br />
To make the pattern easier to see, we can use [[Bracket indexing|indexing]] to place a <source lang=apl inline>⌺</source> symbol where there's a cell and a <source lang=apl inline>·</source> otherwise, for example (note that <source lang=apl inline>⎕IO</source> is [[Index Origin]]):<br />
<source lang=apl><br />
Show←{'·⌺'[⎕IO+⍵]}<br />
Show grid<br />
··········<br />
··········<br />
··········<br />
··········<br />
··········<br />
··········<br />
··········<br />
·······⌺⌺⌺<br />
·······⌺··<br />
········⌺·<br />
</source><br />
<br />
Here's how the Glider evolves over the first ten generations, computed using the [[Power operator]] for iteration:<br />
<source lang=apl><br />
Show¨{Life⍣⍵⊢grid}¨0,⍳9<br />
┌──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐<br />
│··········│··········│··········│··········│··········│··········│··········│··········│··········│··········│<br />
│··········│··········│··········│··········│··········│··········│··········│··········│··········│··········│<br />
│··········│··········│··········│··········│··········│··········│··········│··········│··········│··········│<br />
│··········│··········│··········│··········│··········│··········│··········│··········│··········│··········│<br />
│··········│··········│··········│··········│··········│··········│··········│··········│··········│······⌺···│<br />
│··········│··········│··········│··········│··········│·······⌺··│······⌺⌺··│······⌺⌺··│·····⌺⌺⌺··│·····⌺⌺···│<br />
│··········│········⌺·│·······⌺⌺·│·······⌺⌺·│······⌺⌺⌺·│······⌺⌺··│······⌺·⌺·│·····⌺⌺···│·····⌺····│·····⌺·⌺··│<br />
│·······⌺⌺⌺│·······⌺⌺·│·······⌺·⌺│······⌺⌺··│······⌺···│······⌺·⌺·│······⌺···│·······⌺··│······⌺···│··········│<br />
│·······⌺··│·······⌺·⌺│·······⌺··│········⌺·│·······⌺··│··········│··········│··········│··········│··········│<br />
│········⌺·│··········│··········│··········│··········│··········│··········│··········│··········│··········│<br />
└──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘<br />
</source><br />
<br />
== How it works ==<br />
To compute a new generation in the Game of Life we first need to find out how many neighbours each live cell has. To keep things simple let's consider the following 5-by-5 grid:<br />
<br />
<source lang=apl><br />
currentGeneration←5 5⍴0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 0 0<br />
currentGeneration<br />
0 0 0 0 0<br />
0 0 1 1 0<br />
0 1 1 0 0<br />
0 0 1 0 0<br />
0 0 0 0 0<br />
</source><br />
=== Rotation ===<br />
If we rotate each row of the grid one place left by using APL's [[Rotate]] function <source lang=apl inline>⌽</source>, each element is replaced by its right-hand neighbour. In other words, the new grid will have a 1 for all cells whose right-hand neighbour was 1:<br />
<br />
<source lang=apl><br />
1⌽currentGeneration<br />
0 0 0 0 0<br />
0 1 1 0 0<br />
1 1 0 0 0<br />
0 1 0 0 0<br />
0 0 0 0 0<br />
</source><br />
<br />
Similarly we can rotate right to find the left-hand neighbour by using <source lang=apl inline>¯1⌽currentGeneration</source>. By using APL's [[Outer Product]] operator <source lang=apl inline>∘.</source> together with the Rotate function we can get a set of three grids containing the left-hand neighbour, the original grid, and the right-hand neighbour:<br />
<br />
<source lang=apl><br />
¯1 0 1∘.⌽⊂currentGeneration<br />
┌─────────┬─────────┬─────────┐<br />
│0 0 0 0 0│0 0 0 0 0│0 0 0 0 0│<br />
│0 0 0 1 1│0 0 1 1 0│0 1 1 0 0│<br />
│0 0 1 1 0│0 1 1 0 0│1 1 0 0 0│<br />
│0 0 0 1 0│0 0 1 0 0│0 1 0 0 0│<br />
│0 0 0 0 0│0 0 0 0 0│0 0 0 0 0│<br />
└─────────┴─────────┴─────────┘<br />
</source><br />
<br />
Here <source lang=apl inline>currentGeneration</source> must be [[enclose]]d before applying the outer product so that it is treated as a single [[element]] rather than rotating each of its Boolean elements (which would have no effect).<br />
<br />
=== Extending to two dimensions ===<br />
Now we can use a similar trick but rotate up and down by using APL's First Axis Rotate function <source lang=apl inline>⊖</source>. Used with an Outer Product this gives us a series of 9 grids:<br />
<br />
<source lang=apl><br />
¯1 0 1∘.⊖¯1 0 1∘.⌽⊂currentGeneration<br />
┌─────────┬─────────┬─────────┐<br />
│0 0 0 0 0│0 0 0 0 0│0 0 0 0 0│<br />
│0 0 0 0 0│0 0 0 0 0│0 0 0 0 0│<br />
│0 0 0 1 1│0 0 1 1 0│0 1 1 0 0│<br />
│0 0 1 1 0│0 1 1 0 0│1 1 0 0 0│<br />
│0 0 0 1 0│0 0 1 0 0│0 1 0 0 0│<br />
├─────────┼─────────┼─────────┤<br />
│0 0 0 0 0│0 0 0 0 0│0 0 0 0 0│<br />
│0 0 0 1 1│0 0 1 1 0│0 1 1 0 0│<br />
│0 0 1 1 0│0 1 1 0 0│1 1 0 0 0│<br />
│0 0 0 1 0│0 0 1 0 0│0 1 0 0 0│<br />
│0 0 0 0 0│0 0 0 0 0│0 0 0 0 0│<br />
├─────────┼─────────┼─────────┤<br />
│0 0 0 1 1│0 0 1 1 0│0 1 1 0 0│<br />
│0 0 1 1 0│0 1 1 0 0│1 1 0 0 0│<br />
│0 0 0 1 0│0 0 1 0 0│0 1 0 0 0│<br />
│0 0 0 0 0│0 0 0 0 0│0 0 0 0 0│<br />
│0 0 0 0 0│0 0 0 0 0│0 0 0 0 0│<br />
└─────────┴─────────┴─────────┘<br />
</source><br />
<br />
The grid in the centre is our original grid, and the others give the neighbours above, below, left, right and diagonally.<br />
=== Summing it up ===<br />
Now we can find out how many neighbours each cell in the original grid has by summing ([[Plus]] [[Reduce]]) the corresponding elements in each of the 9 grids. We sum all the grids at once by [[ravel]]ling the [[shape]] <source lang=apl inline>3 3</source> [[matrix]] of grids to obtain a 9-element [[vector]]; otherwise [[Reduce]] would only allow us to sum rows or columns. Here APL's representation of [[Boolean]]s as numbers is advantageous, since otherwise counting the number of true values would require converting them to numbers or using conditional logic. For a live cell the sum is 1 more than the number of neighbours—for example, a 4 in the result means a cell has three neighbours. For a dead cell the result is just the number of neighbours:<br />
<br />
<source lang=apl><br />
+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂currentGeneration<br />
┌─────────┐<br />
│0 1 2 2 1│<br />
│1 3 4 3 1│<br />
│1 4 5 4 1│<br />
│1 3 3 2 0│<br />
│0 1 1 1 0│<br />
└─────────┘<br />
</source><br />
<br />
For a cell to exist in the next generation, one of two rules must be met:<br />
<br />
* Any live cell with two neighbours lives, unchanged, to the next generation<br />
* Any cell, live or dead, with exactly three neighbours is live in the next generation<br />
<br />
This means that all cells which might be live in the next generation will have a sum of 3 (from the first rule) or 3 or 4 (from the second rule).<br />
<br />
So we're interested in cells with a sum of 3 or 4. We can find these cells with a simple application of [[Equal to]], relying on [[pervasion]] and [[scalar extension]] to distribute the data properly. The result of the last step was a [[scalar]] containing one grid; when paired with the [[vector]] <source lang=apl inline>3 4</source> it is extended to give two grids. Within each grid 3 and 4 are compared with every element by scalar extension again. If the right argument were a flat array rather than being [[enclose]]d, we could obtain a similar, but flat, result using another [[Outer Product]].<br />
<br />
<source lang=apl><br />
3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂currentGeneration<br />
┌─────────┬─────────┐<br />
│0 0 0 0 0│0 0 0 0 0│<br />
│0 1 0 1 0│0 0 1 0 0│<br />
│0 0 0 0 0│0 1 0 1 0│<br />
│0 1 1 0 0│0 0 0 0 0│<br />
│0 0 0 0 0│0 0 0 0 0│<br />
└─────────┴─────────┘<br />
</source><br />
<br />
The next step is best understood by first considering the two scores 4 and 3 separately.<br />
<br />
(a) A score of 4 corresponds either to a live cell with three neighbours or a dead cell with four neighbours. Only in the former case do we get a cell in the next generation - i.e. we get a cell if the score is 4 ''and'' the cell is currently live. Here we're using APL's [[And]] function, <source lang=apl inline>∧</source><br />
<source lang=apl><br />
(⊂currentGeneration)∧4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂currentGeneration<br />
┌─────────┐<br />
│0 0 0 0 0│<br />
│0 0 1 0 0│<br />
│0 1 0 0 0│<br />
│0 0 0 0 0│<br />
│0 0 0 0 0│<br />
└─────────┘<br />
</source><br />
<br />
(b) A score of three corresponds either to a live cell with two neighbours or a dead cell with three neighbours. In either case we get a cell in the next generation:<br />
<source lang=apl><br />
3=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂currentGeneration<br />
┌─────────┐<br />
│0 0 0 0 0│<br />
│0 1 0 1 0│<br />
│0 0 0 0 0│<br />
│0 1 1 0 0│<br />
│0 0 0 0 0│<br />
└─────────┘<br />
</source><br />
<br />
We can write this slightly redundantly by ''and''-ing with 1 (meaning "''and'' the cell is alive or dead") for reasons which will become apparent shortly:<br />
<source lang=apl><br />
1∧3=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂currentGeneration<br />
┌─────────┐<br />
│0 0 0 0 0│<br />
│0 1 0 1 0│<br />
│0 0 0 0 0│<br />
│0 1 1 0 0│<br />
│0 0 0 0 0│<br />
└─────────┘<br />
</source><br />
<br />
So the next step is to say that a cell is live if either test (a) ''or'' test (b) is met. We need to use APL's [[Or]] function, <source lang=apl inline>∨</source>. We could write this rather long-windedly as:<br />
<source lang=apl><br />
(1∧3=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂currentGeneration)∨(⊂currentGeneration)∧4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂currentGeneration<br />
┌─────────┐<br />
│0 0 0 0 0│<br />
│0 1 1 1 0│<br />
│0 1 0 0 0│<br />
│0 1 1 0 0│<br />
│0 0 0 0 0│<br />
└─────────┘<br />
</source><br />
<br />
=== Refactoring ===<br />
But we can take advantage of APL's [[Inner Product]] operator to do the ''and'' operations of each test and then ''or'' the result - the <source lang=apl inline>∨.∧</source> in the following:<br />
<br />
<source lang=apl><br />
1 currentGeneration∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂currentGeneration<br />
┌─────────┐<br />
│0 0 0 0 0│<br />
│0 1 1 1 0│<br />
│0 1 0 0 0│<br />
│0 1 1 0 0│<br />
│0 0 0 0 0│<br />
└─────────┘<br />
</source><br />
<br />
The final expression ends with a bit of housekeeping using [[Mix]] (<source lang=apl inline>↑</source>) to turn the result back into a simple array (it's currently nested).<br />
<br />
== Translations ==<br />
<br />
=== GNU APL ===<br />
<br />
In [[GNU APL]] the [[Inner Product]] <source lang=apl inline>∨.∧</source> results in a twice-[[enclose]]d matrix, rather than once-enclosed as in [[Dyalog APL]]. This can be fixed either by [[mix]]ing twice, or by using a [[Reduce|reduction]] instead of an inner product.<br />
<source lang=apl><br />
Life←{↑↑1 ⍵∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵}<br />
Life←{↑∨/1 ⍵∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵}<br />
</source><br />
<br />
=== dzaima/APL ===<br />
<br />
In [[dzaima/APL]] the [[Reduce|reduction]] <source lang=apl inline>+/</source> [[mix]]es its result, which defeats our use of [[scalar extension]] causing a [[LENGTH ERROR]]. Because the sum has only one (matrix) result, enclosing it corrects this issue.<br />
<source lang=apl><br />
Life←{↑1 ⍵∨.∧3 4=⊂+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵}<br />
</source><br />
The computation of our example <source lang=apl inline>grid</source> also fails, because dzaima's [[Take]] does not allow overtaking. Instead we can insert the glider into a matrix of zeros using [[structural Under]]:<br />
<source lang=apl><br />
grid ← ¯10 ¯10↑glider ⍝ DomainError<br />
grid ← glider⍢(¯3 ¯3∘↑) 10 10⍴0 ⍝ This works<br />
</source><br />
<br />
=== Ruby ===<br />
<br />
Github user zverok has translated Scholes' dfn to [[wikipedia:Ruby (programming language)|Ruby]] by first creating an <source lang=ruby inline>apl</source> module to implement parts of APL. The code is shown [https://github.com/zverok/ruby_as_apl on Github] and explained [https://zverok.github.io/blog/2020-05-16-ruby-as-apl.html on zverok's blog].<br />
<br />
== Performance ==<br />
<br />
Although it uses [[nested]] arrays to organize the computation, Scholes' Game of Life implementation can still be a fairly fast algorithm on medium and large matrices, competitive with straightforward C implementations. This is because the [[simple]] arrays stored in the outer nested array all have the same size as the argument. There are only nine of these arrays, so the overhead associated with nesting is constant and small. Until they are summed, these arrays are [[Boolean]], allowing them to be stored in a packed representation and [[rotate]]d quickly ([[Roger Hui]] states that the Game of Life motivated some improvements to Boolean functions in [[Dyalog APL 13.2|Dyalog 13.2]] and [[Dyalog APL 14.0|14.0]]<ref>[[Morten Kromberg]] and [[Roger Hui]]. D11: [https://dyalog.tv/Dyalog13/?v=84t87EO5ZEE Primitive Performance] at [[Dyalog '13]] ([https://www.dyalog.com/uploads/conference/dyalog13/presentations/D11_Primitive_Performance/perfscript1.htm#2 script]). 2013-10.</ref>). When adding them, recent versions of Dyalog APL use [[vector instructions]], enabling many numbers to be added at once.<br />
<br />
The following code times how long it takes to perform 1000 iterations of the Game of Life on a shape <source lang=apl inline>1000 1000</source> array. This computation performs a billion cell updates, so the total time in seconds is equal to the time taken per update in nanoseconds.<br />
<source lang=apl><br />
)copy dfns cmpx<br />
b←1=?1e3 1e3⍴2<br />
1 cmpx 'Life⍣1000 ⊢b'<br />
</source><br />
The timings below were taken with various versions of [[Dyalog APL]] on an Intel Kaby Lake i7. The largest change appears in 17.0, when [[Boolean]]-integer [[addition]] was implemented using vector instructions (on this processor, AVX2).<br />
{|class=wikitable<br />
! Version !! Time (s)<br />
|-<br />
| [[Dyalog APL 15.0|15.0]] || 14.0<br />
|-<br />
| [[Dyalog APL 16.0|16.0]] || 13.5<br />
|-<br />
| [[Dyalog APL 17.0|17.0]] || 1.32<br />
|-<br />
| [[Dyalog APL 17.1|17.1]] || 1.31<br />
|-<br />
| [[Dyalog APL 18.0|18.0]] (pre-release) || 0.75<br />
|}<br />
<br />
== References ==<br />
<references /><br />
[[Category:Examples]][[Category:Dyalog APL examples]]</div>Hou32houhttps://aplwiki.com/index.php?title=Mix&diff=7286Mix2021-09-04T06:43:16Z<p>Hou32hou: fix the longest common prefix error</p>
<hr />
<div>{| class=vertical-navbox style="float:right; font-size:500%; margin:0 1ex;"<br />
|<code>↑</code> <code>⊃</code> <code>></code><br />
|}<br />
'''Mix''' (<code>↑</code> or <code>⊃</code> in [[Nested array model|nested]] APLs; '''Disclose''' or '''Open''' <code>></code> in [[Flat array model|flat]] array languages) is a [[primitive function|primitive]] [[monadic function]] which reduces the [[depth]] of its [[argument]] by combining all its [[element]] arrays into a single array. The [[shape]] of its result is then the shape of the argument followed by the common shape of the argument elements. Depending on the definition of Mix, the elements may be required to share the same shape, or they may be extended in shape (with [[fill element]]s) or rank to fit a common shape. In all APLs Mix allows a [[simple array]] argument, and returns it unchanged. Mix is a left inverse to both [[Enclose]] and [[Split]], while the function [[First]], which is identical to Mix on [[scalar]]s, is a left inverse to [[Enclose]] only.<br />
<br />
== History ==<br />
<br />
Early experiments in array nesting usually defined a primitive to extract the contents of a nested [[scalar]], but did not always specify how it should behave on an array. [[Jim Brown]]'s "A Generalization of APL",<ref>[[Jim Brown]]. [http://www.softwarepreservation.org/projects/apl/Books/AGENERALIZATIONOFAPL "A Generalization of APL"] (Ph.D. thesis). 1971.</ref> which would become [[APL2]], defined such a primitive, "reveal", while stating that it "may be undefined" on non-scalar arrays.<br />
<br />
Mix (<source lang=apl inline>↑</source>) was first introduced by [[NARS]] in 1981.<ref>Carl M. Cheney. [http://www.sudleyplace.com/APL/Nested%20Arrays%20System.pdf ''APL*PLUS Nested Arrays System''] ([[NARS]] reference manual). [[STSC]]. 1981.</ref> It required all elements to have matching shape, and allowed a [[Function axis|specified axis]] to define where in the result array their axes would be placed. In the same year, [[SHARP APL]] introduced the concept of a [[box]]ed array, along with the function Disclose (<source lang=apl inline>></source>).<ref>[[Ken Iverson]]. SATN-41: [https://www.jsoftware.com/papers/satn41.htm Composition and Enclosure]. [[IPSA]]. 1981-06-20.</ref> In SHARP, Disclose was simply defined to be the inverse of Enclose, but given [[function rank]] 0 so that it would disclose each box in an argument and combine the results. Based on SHARP's definition of [[Rank (operator)|Rank]], the arrays to be combined were required to have the same [[shape]], and because of its [[flat array model]], they also had to have the same type (numeric, character, or boxed), as otherwise the result array would not be representable.<br />
<br />
[[APL2]], released in 1984, used the same name Disclose as SHARP APL but introduced the glyph [[Right Shoe]] (<source lang=apl inline>⊃</source>). It shared NARS's [[function axis]] definition, but extended the function to allow argument elements with different [[shape]]s as long as they had the same [[rank]]. Arrays with different shapes would be padded using [[fill element]]s as with [[Take]] to bring them to a common shape large enough to contain every element.<br />
<br />
A further extension was introduced as a consequence of [[J]]'s definition of the [[Rank operator]]. In J, result arrays in a function applied with rank can have different [[rank]]s, and results with lower rank are brought to a common rank by adding leading 1s to the shape. This change was taken up by [[Dyalog APL]] in [[Dyalog APL 14.0|version 14.0]], which introduced [[Rank (operator)|Rank]] following J's definition, in order to make Mix and Rank consistent. However, Dyalog differs from J in that it permits [[mixed array]]s, so while in J an array containing a mix of numbers, characters, and boxes cannot be mixed, in Dyalog any array at all can be mixed.<br />
<br />
== Language support ==<br />
<br />
Mix is only available in languages which allow nesting, either by [[box]]es or [[nested array]]s, so it is not present in early APLs such as [[APL\360]] and [[APL.SV]].<br />
<br />
{|class=wikitable<br />
! Languages !! Name !! [[Glyph]] !! Requirements !! NARS-style [[function axis]] !! APL2-style [[function axis]]<br />
|-<br />
| [[NARS]] || Mix || <code>↑</code> || [[Shape]] || {{Yes}} || {{No}}<br />
|-<br />
| [[SHARP APL]], [[A+]] || Disclose || <code>></code> || [[Shape]] and type || {{No}} || {{No}}<br />
|-<br />
| [[APL2]], [[APLX]] || Disclose || <code>⊃</code> || [[Rank]] || {{No}} || {{Yes}}<br />
|-<br />
| [[NARS2000]] || Disclose || <code>⊃</code> || None || {{No}} || {{No}}<br />
|-<br />
| [[Dyalog APL]] || Mix || <code>↑</code> or <code>⊃</code> ([[Migration level|ML]]) || None || {{Yes}} || {{Yes}}<br />
|-<br />
| [[J]] || Open || <code>></code> || Type || {{No}} || {{No}}<br />
|-<br />
| [[ngn/apl]] || Mix || <code>↑</code> || None || {{No}} || {{No}}<br />
|-<br />
| [[dzaima/APL]] || Merge || <code>↑</code> || [[Rank]] || {{No}} || {{No}}<br />
|-<br />
| [[BQN]] || Merge || <code>></code> || [[Shape]] || {{No}} || {{No}}<br />
|}<br />
<br />
== Examples ==<br />
<br />
<source lang="apl"><br />
x ← (0 1 2) (3 4 5) (9 9)<br />
⍴x ⍝ x is a nested array, i.e. array of array<br />
3<br />
↑x<br />
0 1 2<br />
3 4 5<br />
9 9 0 ⍝ note that 0 is automatically added at the back due to auto-padding<br />
⍴↑x ⍝ ↑x is a non-nested 2-d array<br />
3 3<br />
</source><br />
<br />
Example application, to find the longest common prefix:<br />
<source lang="apl"><br />
lcp←{(+/^\(^/⊃=⊢)¨↓⍉↑⍵)↑⊃⍵}<br />
lcp 'flowers' 'flow' 'flip'<br />
fl<br />
lcp 'choco' 'choky' 'chom'<br />
cho <br />
</source><br />
<br />
== External links ==<br />
<br />
=== Lessons ===<br />
<br />
* [https://chat.stackexchange.com/transcript/52405?m=41304486#41304486 APL Cultivation]<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/18.0/#Language/Primitive%20Functions/Mix.htm Dyalog]<br />
* [http://microapl.com/apl_help/ch_020_020_600.htm APLX]<br />
* [[J]] [https://www.jsoftware.com/help/dictionary/d020.htm dictionary], [https://code.jsoftware.com/wiki/Vocabulary/gt NuVoc]<br />
* [https://mlochbaum.github.io/BQN/doc/couple.html BQN]<br />
<br />
== References ==<br />
<references/><br />
<br />
{{APL built-ins}}[[Category:Primitive functions]]</div>Hou32houhttps://aplwiki.com/index.php?title=Mix&diff=7285Mix2021-09-04T06:15:43Z<p>Hou32hou: Added examples</p>
<hr />
<div>{| class=vertical-navbox style="float:right; font-size:500%; margin:0 1ex;"<br />
|<code>↑</code> <code>⊃</code> <code>></code><br />
|}<br />
'''Mix''' (<code>↑</code> or <code>⊃</code> in [[Nested array model|nested]] APLs; '''Disclose''' or '''Open''' <code>></code> in [[Flat array model|flat]] array languages) is a [[primitive function|primitive]] [[monadic function]] which reduces the [[depth]] of its [[argument]] by combining all its [[element]] arrays into a single array. The [[shape]] of its result is then the shape of the argument followed by the common shape of the argument elements. Depending on the definition of Mix, the elements may be required to share the same shape, or they may be extended in shape (with [[fill element]]s) or rank to fit a common shape. In all APLs Mix allows a [[simple array]] argument, and returns it unchanged. Mix is a left inverse to both [[Enclose]] and [[Split]], while the function [[First]], which is identical to Mix on [[scalar]]s, is a left inverse to [[Enclose]] only.<br />
<br />
== History ==<br />
<br />
Early experiments in array nesting usually defined a primitive to extract the contents of a nested [[scalar]], but did not always specify how it should behave on an array. [[Jim Brown]]'s "A Generalization of APL",<ref>[[Jim Brown]]. [http://www.softwarepreservation.org/projects/apl/Books/AGENERALIZATIONOFAPL "A Generalization of APL"] (Ph.D. thesis). 1971.</ref> which would become [[APL2]], defined such a primitive, "reveal", while stating that it "may be undefined" on non-scalar arrays.<br />
<br />
Mix (<source lang=apl inline>↑</source>) was first introduced by [[NARS]] in 1981.<ref>Carl M. Cheney. [http://www.sudleyplace.com/APL/Nested%20Arrays%20System.pdf ''APL*PLUS Nested Arrays System''] ([[NARS]] reference manual). [[STSC]]. 1981.</ref> It required all elements to have matching shape, and allowed a [[Function axis|specified axis]] to define where in the result array their axes would be placed. In the same year, [[SHARP APL]] introduced the concept of a [[box]]ed array, along with the function Disclose (<source lang=apl inline>></source>).<ref>[[Ken Iverson]]. SATN-41: [https://www.jsoftware.com/papers/satn41.htm Composition and Enclosure]. [[IPSA]]. 1981-06-20.</ref> In SHARP, Disclose was simply defined to be the inverse of Enclose, but given [[function rank]] 0 so that it would disclose each box in an argument and combine the results. Based on SHARP's definition of [[Rank (operator)|Rank]], the arrays to be combined were required to have the same [[shape]], and because of its [[flat array model]], they also had to have the same type (numeric, character, or boxed), as otherwise the result array would not be representable.<br />
<br />
[[APL2]], released in 1984, used the same name Disclose as SHARP APL but introduced the glyph [[Right Shoe]] (<source lang=apl inline>⊃</source>). It shared NARS's [[function axis]] definition, but extended the function to allow argument elements with different [[shape]]s as long as they had the same [[rank]]. Arrays with different shapes would be padded using [[fill element]]s as with [[Take]] to bring them to a common shape large enough to contain every element.<br />
<br />
A further extension was introduced as a consequence of [[J]]'s definition of the [[Rank operator]]. In J, result arrays in a function applied with rank can have different [[rank]]s, and results with lower rank are brought to a common rank by adding leading 1s to the shape. This change was taken up by [[Dyalog APL]] in [[Dyalog APL 14.0|version 14.0]], which introduced [[Rank (operator)|Rank]] following J's definition, in order to make Mix and Rank consistent. However, Dyalog differs from J in that it permits [[mixed array]]s, so while in J an array containing a mix of numbers, characters, and boxes cannot be mixed, in Dyalog any array at all can be mixed.<br />
<br />
== Language support ==<br />
<br />
Mix is only available in languages which allow nesting, either by [[box]]es or [[nested array]]s, so it is not present in early APLs such as [[APL\360]] and [[APL.SV]].<br />
<br />
{|class=wikitable<br />
! Languages !! Name !! [[Glyph]] !! Requirements !! NARS-style [[function axis]] !! APL2-style [[function axis]]<br />
|-<br />
| [[NARS]] || Mix || <code>↑</code> || [[Shape]] || {{Yes}} || {{No}}<br />
|-<br />
| [[SHARP APL]], [[A+]] || Disclose || <code>></code> || [[Shape]] and type || {{No}} || {{No}}<br />
|-<br />
| [[APL2]], [[APLX]] || Disclose || <code>⊃</code> || [[Rank]] || {{No}} || {{Yes}}<br />
|-<br />
| [[NARS2000]] || Disclose || <code>⊃</code> || None || {{No}} || {{No}}<br />
|-<br />
| [[Dyalog APL]] || Mix || <code>↑</code> or <code>⊃</code> ([[Migration level|ML]]) || None || {{Yes}} || {{Yes}}<br />
|-<br />
| [[J]] || Open || <code>></code> || Type || {{No}} || {{No}}<br />
|-<br />
| [[ngn/apl]] || Mix || <code>↑</code> || None || {{No}} || {{No}}<br />
|-<br />
| [[dzaima/APL]] || Merge || <code>↑</code> || [[Rank]] || {{No}} || {{No}}<br />
|-<br />
| [[BQN]] || Merge || <code>></code> || [[Shape]] || {{No}} || {{No}}<br />
|}<br />
<br />
== Examples ==<br />
<br />
<source lang="apl"><br />
x ← (0 1 2) (3 4 5) (9 9)<br />
⍴x ⍝ x is a nested array, i.e. array of array<br />
3<br />
↑x<br />
0 1 2<br />
3 4 5<br />
9 9 0 ⍝ note that 0 is automatically added at the back due to auto-padding<br />
⍴↑x ⍝ ↑x is a non-nested 2-d array<br />
3 3<br />
</source><br />
<br />
Example application, to find the longest common prefix:<br />
<source lang="apl"><br />
lcp←{(+/(^/⊃=⊢)¨↓⍉↑⍵)↑⊃⍵}<br />
lcp 'flowers' 'flow' 'flip'<br />
fl<br />
lcp 'choco' 'choky' 'chom'<br />
cho <br />
</source><br />
<br />
== External links ==<br />
<br />
=== Lessons ===<br />
<br />
* [https://chat.stackexchange.com/transcript/52405?m=41304486#41304486 APL Cultivation]<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/18.0/#Language/Primitive%20Functions/Mix.htm Dyalog]<br />
* [http://microapl.com/apl_help/ch_020_020_600.htm APLX]<br />
* [[J]] [https://www.jsoftware.com/help/dictionary/d020.htm dictionary], [https://code.jsoftware.com/wiki/Vocabulary/gt NuVoc]<br />
* [https://mlochbaum.github.io/BQN/doc/couple.html BQN]<br />
<br />
== References ==<br />
<references/><br />
<br />
{{APL built-ins}}[[Category:Primitive functions]]</div>Hou32houhttps://aplwiki.com/index.php?title=Each&diff=7284Each2021-09-03T13:04:31Z<p>Hou32hou: Added the reverse example provided by Adam</p>
<hr />
<div>{{Built-in|Each|¨}} is a [[primitive operator|primitive]] [[monadic operator]] which applies its [[operand]] to each [[element]] of the [[argument]]s, and returns an array whose elements are the results. If two arguments are given, their elements are matched using [[conformability]] rules.<br />
<br />
Each is defined only in [[Nested array model|nested]] APLs. Some [[Flat array model|flat]] APLs obtain analogous functionality by using an [[Under]] operator with [[close composition]] along with the [[Function rank|rank]]-0 function [[Disclose]] (or Unbox). In [[SHARP APL]] this is written <source lang=apl inline>f¨></source>. In [[J]] it is <source lang=j inline>f&.></source>.<br />
<br />
Each differs from the [[Rank operator]] with rank 0 in that the operand arguments and results are not [[enclose]]d. As the [[elements]] of a nested array they need not be [[scalar]].<br />
<br />
For example,<br />
<br />
<source lang=apl><br />
1,1 2 3 ⍝ join 1 with 1 2 3<br />
1 1 2 3<br />
1,¨1 2 3 ⍝ join 1 with each element of 1 2 3<br />
┌───┬───┬───┐<br />
│1 1│1 2│1 3│<br />
└───┴───┴───┘<br />
<br />
x←'abc' 'def' 'ghi'<br />
⌽x ⍝ reverse x<br />
┌───┬───┬───┐<br />
│ghi│def│abc│<br />
└───┴───┴───┘<br />
⌽¨x ⍝ reverse each element of x<br />
┌───┬───┬───┐<br />
│cba│fed│ihg│<br />
└───┴───┴───┘<br />
</source><br />
<br />
The Each operator has no effect on [[scalar function]]s, since these functions already map over each array element. <br />
<br />
For example, both expressions below have the same meaning, since <source lang=apl inline>+</source> is a scalar function.<br />
<source lang=apl><br />
1 + 1 2 3 4<br />
2 3 4 5<br />
1 +¨ 1 2 3 4<br />
2 3 4 5<br />
</source><br />
<br />
== External links ==<br />
<br />
=== Lessons ===<br />
<br />
* [https://chat.stackexchange.com/rooms/52405/conversation/lesson-3-some-apl-operators-----#message-40899092 APL Cultivation]<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/latest/index.htm#Language/Primitive%20Operators/Each%20with%20Monadic%20Operand.htm Dyalog] (monadic operand), [https://help.dyalog.com/latest/index.htm#Language/Primitive%20Operators/Each%20with%20Dyadic%20Operand.htm Dyalog] (dyadic operand)<br />
* [http://microapl.com/apl_help/ch_020_020_900.htm APLX]<br />
<br />
{{APL built-ins}}[[Category:Primitive operators]]</div>Hou32houhttps://aplwiki.com/index.php?title=Each&diff=7281Each2021-09-03T09:42:34Z<p>Hou32hou: Added examples</p>
<hr />
<div>{{Built-in|Each|¨}} is a [[primitive operator|primitive]] [[monadic operator]] which applies its [[operand]] to each [[element]] of the [[argument]]s, and returns an array whose elements are the results. If two arguments are given, their elements are matched using [[conformability]] rules.<br />
<br />
Each is defined only in [[Nested array model|nested]] APLs. Some [[Flat array model|flat]] APLs obtain analogous functionality by using an [[Under]] operator with [[close composition]] along with the [[Function rank|rank]]-0 function [[Disclose]] (or Unbox). In [[SHARP APL]] this is written <source lang=apl inline>f¨></source>. In [[J]] it is <source lang=j inline>f&.></source>.<br />
<br />
Each differs from the [[Rank operator]] with rank 0 in that the operand arguments and results are not [[enclose]]d. As the [[elements]] of a nested array they need not be [[scalar]].<br />
<br />
For example,<br />
<br />
<source lang=apl><br />
1,1 2 3 ⍝ join 1 with 1 2 3<br />
1 1 2 3<br />
1,¨1 2 3<br />
┌───┬───┬───┐<br />
│1 1│1 2│1 3│ ⍝ join 1 with each element of 1 2 3<br />
└───┴───┴───┘<br />
</source><br />
<br />
Note that this operator has no effect on [https://mastering.dyalog.com/Appendices.html#scalar-functions scalar functions], since these functions map to each array elements by default. <br />
<br />
For example, both expression below has the same meaning, since + is a scalar function.<br />
<source lang=apl><br />
1 + 1 2 3 4<br />
2 3 4 5<br />
1 +¨ 1 2 3 4<br />
2 3 4 5<br />
</source><br />
<br />
== External links ==<br />
<br />
=== Lessons ===<br />
<br />
* [https://chat.stackexchange.com/rooms/52405/conversation/lesson-3-some-apl-operators-----#message-40899092 APL Cultivation]<br />
<br />
=== Documentation ===<br />
<br />
* [https://help.dyalog.com/latest/index.htm#Language/Primitive%20Operators/Each%20with%20Monadic%20Operand.htm Dyalog] (monadic operand), [https://help.dyalog.com/latest/index.htm#Language/Primitive%20Operators/Each%20with%20Dyadic%20Operand.htm Dyalog] (dyadic operand)<br />
* [http://microapl.com/apl_help/ch_020_020_900.htm APLX]<br />
<br />
{{APL built-ins}}[[Category:Primitive operators]]</div>Hou32hou