1

edit

Jump to navigation
Jump to search

m

changed a 2 to a 4

No edit summary |
DanielAjoy (talk | contribs) m (changed a 2 to a 4) |
||

(13 intermediate revisions by 2 users not shown) | |||

Line 1: | Line 1: | ||

{{Built-in|Inner Product|<nowiki>.</nowiki>}} | {{Built-in|Inner Product|<nowiki>.</nowiki>}} is a [[dyadic operator]] that produces a [[dyadic function]] when applied with two dyadic functions. It's a generalisation of the [[wikipedia:Matrix multiplication|matrix product]], allowing not just addition-multiplication, but any [[dyadic function]]s given as [[operand]]s. | ||

== Examples == | == Examples == | ||

Line 25: | Line 25: | ||

</source> | </source> | ||

The [[shape]]s of the arguments must be compatible with each other: The last [[axis]] of the left argument must have the same length as the first axis of the right argument, or formally, for <source lang=apl inline>X f.g Y</source> it must be that <source lang=apl inline>(¯1↑⍴X)≡(1↑⍴Y)</source>. Although this rule differs from [[conformability]], the arguments may also be subject to [[scalar extension|scalar]] or [[singleton extension]]. The shape of the result is <source lang=apl inline>(¯1↓⍴X),(1↓⍴Y)</source>. | |||

For example, when applying inner product on two [[matrix|matrices]], the number of columns in the left array must match with number of rows in the right array, otherwise we will get an error. | For example, when applying inner product on two [[matrix|matrices]], the number of columns in the left array must match with number of rows in the right array, otherwise we will get an error. | ||

Line 46: | Line 46: | ||

49 64 | 49 64 | ||

</source> | </source> | ||

== History == | |||

Inner product appeared in early [[Iverson Notation]] as <math>^f_g</math> and applied even to non-[[scalar function]]s, like [[Compress]], Iverson bringing:<ref>[[Ken Iverson]]. [[A Programming Language]]. §1.11 ''The language''.</ref> | |||

:<math> | |||

\begin{align} | |||

\text{For example, if}\\ | |||

\boldsymbol{A}&=\begin{pmatrix} | |||

1&3&2&0\\ | |||

2&1&0&1\\ | |||

4&0&0&2\\ | |||

\end{pmatrix} | |||

\qquad\text{and}\qquad | |||

\boldsymbol{B}=\begin{pmatrix} | |||

4&1\\ | |||

0&3\\ | |||

0&2\\ | |||

2&0\\ | |||

\end{pmatrix}\\ | |||

\text{then}\qquad\boldsymbol{A}\;^+_\times\,\boldsymbol{B}&=\begin{pmatrix} | |||

4&14\\ | |||

10&5\\ | |||

20&4\\ | |||

\end{pmatrix}, | |||

\quad\boldsymbol{A}\;^\and_=\,\boldsymbol{B}=\begin{pmatrix} | |||

0&1\\ | |||

0&0\\ | |||

1&0\\ | |||

\end{pmatrix}\text{,}\\ | |||

\boldsymbol{A}\;^\or_\neq\;\boldsymbol{B}&=\begin{pmatrix} | |||

1&0\\ | |||

1&1\\ | |||

0&1\\ | |||

\end{pmatrix}, | |||

\qquad\text{and}\qquad(\boldsymbol{A}\neq0)\;^+_{\,/}\,\boldsymbol{B}=\begin{pmatrix} | |||

4&6\\ | |||

6&4\\ | |||

6&1\\ | |||

\end{pmatrix}\text{.} | |||

\end{align} | |||

</math> | |||

When the inner product notation was linearised (made to fit on a single line of code) the [[glyph]] <source lang=apl inline>.</source> was chosed to denote what was previously indicated by positioning the two [[operand]]s vertically aligned. Thus, the above correspond to the following modern APL: | |||

<source lang=apl> | |||

⍝ For example, if | |||

A←3 4⍴1 3 2 0 2 1 0 1 4 0 0 2 | |||

B←4 2⍴4 1 0 3 0 2 2 0 | |||

⍝ then | |||

A +.× B | |||

4 14 | |||

10 5 | |||

20 4 | |||

A ∧.= B | |||

0 1 | |||

0 0 | |||

1 0 | |||

A ∨.≠ B | |||

1 0 | |||

1 1 | |||

0 1 | |||

(A ≠ 0) +./ B | |||

4 6 | |||

6 4 | |||

6 1 | |||

</source> | |||

Note that some dialects implement [[Compress]] (<source lang=apl inline>/</source>) as a [[monadic operator]] rather than as a function, which means it cannot be an operand in the inner product. Instead, a cover function is necessary: | |||

<source lang=apl> | |||

∇z←a Compress b | |||

z←a/b | |||

∇ | |||

</source> | |||

== Differences between dialects == | |||

Implementations differ on the exact behaviour of inner product when the right operand is not a [[scalar function]]. It follows from page 121 of the ISO/IEC 13751:2001(E) [[standard]] specifies that <source lang=apl inline>X f.g Y</source> is equivalent to <source lang=apl inline>f/¨ (⊂[⍴⍴x]x)∘.g ⊂[1]y</source>. This is indeed what [[APL2]], [[APLX]], [[APL+Win]], and [[ngn/apl]] follow, while [[Dyalog APL]], [[NARS2000]] and [[GNU APL]] differ as described by [[Roger Hui]]:<ref>[[Roger Hui]]. ''inner product''. Internal Dyalog email. 24 July 2020.</ref> | |||

<blockquote> | |||

The following dop models inner product in Dyalog APL, with caveats. If you find a case where <source lang=apl inline>f.g</source> differs from <source lang=apl inline>f IP g</source>, not covered by the caveats, I'd be interested. | |||

<source lang=apl> | |||

IP←{ | |||

assert((⊃⌽⍴⍺)≡≢⍵)∨(1=×/⍴⍺)∨1=×/⍴⍵: | |||

⊃⍤0 ⊢ (↓⍺) ∘.(⍺⍺/⍵⍵¨) ↓(¯1⌽⍳⍴⍴⍵)⍉⍵ | |||

} | |||

assert←{⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕SIGNAL 8 ⋄ shy←0} | |||

</source> | |||

(Explanation: What's with the <source lang=apl inline>⊃⍤0</source> in <source lang=apl inline>IP</source>? It's because <source lang=apl inline>∘.f</source> has an implicit each, applying <source lang=apl inline>⊂</source> to each item of its result. But the <source lang=apl inline>⍺⍺/</source> in <source lang=apl inline>(⍺⍺/⍵⍵¨)</source> also has an implicit each. So the <source lang=apl inline>⊃⍤0</source> gets rid of one of those encloses.) | |||

Caveats: | |||

* You can not use the hybrid <source lang=apl inline>/</source> directly as an operand as it runs afoul of the parser in weird and wonderful ways. Instead, you have to use <source lang=apl inline>{⍺/⍵}</source>. The same goes for <source lang=apl inline>\</source> and <source lang=apl inline>{⍺\⍵}</source> I guess. | |||

* It differs from ISO/IEC 13751:2001(E) in using <source lang=apl inline>⍵⍵¨</source> instead of just <source lang=apl inline>⍵⍵</source> in the central key expression (i.e. <source lang=apl inline>(⍺⍺/⍵⍵¨)</source> instead of <source lang=apl inline>(⍺⍺/⍵⍵)</source>). So does the primitive <source lang=apl inline>f.g</source>. | |||

* It differs from ISO/IEC 13751:2001(E) in doing full-blown single extension instead of just scalar and 1-element vector extension (as in APL2). So does the primitive <source lang=apl inline>f.g</source>. e.g.<source lang=apl> | |||

(3 4⍴5)+.×1 1 1 1⍴6 ⍝ works in Dyalog, not in ISO or APL2</source> | |||

* It differs from NARS2000 or APL\360 in not permitting unit axis extension. So does the primitive <source lang=apl inline>f.g</source>. e.g.<source lang=apl> | |||

(3 4⍴5)+.×1 5⍴6 ⍝ works in NARS2000 or APL\360, not in Dyalog APL</source> | |||

</blockquote> | |||

== External links == | == External links == | ||

Line 54: | Line 149: | ||

* J [https://www.jsoftware.com/help/dictionary/d300.htm Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/dot#dyadic NuVoc] | * J [https://www.jsoftware.com/help/dictionary/d300.htm Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/dot#dyadic NuVoc] | ||

=== Discussion of differences between dialects === | |||

* [https://groups.google.com/g/comp.lang.apl/c/23LrwRZKmPs Dyalog / APL2000 discrepancy] (Google Groups) | |||

* [https://lists.gnu.org/archive/html/bug-apl/2016-07/msg00020.html multiple inner product] (GNU APL mailing list) | |||

* [https://lists.gnu.org/archive/html/bug-apl/2018-05/msg00003.html an other inner product ,., bug] (GNU APL mailing list) | |||

== References == | |||

<references/> | |||

{{APL built-ins}}[[Category:Primitive operators]] | {{APL built-ins}}[[Category:Primitive operators]] |

1

edit

Retrieved from ‘https://aplwiki.com/wiki/Special:MobileDiff/7308...8114’