2,963
edits
m (→Scalar-vector discrepancy in nested APLs: Kap also treats singleton vectors as vectors) |
|||
(21 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
:''This page is about generating indices for an array of a given size. See [[Indexing]], [[Indices]], [[Index of]], and [[Interval Index]] for other operations named after indices.'' | |||
{{Built-in|Index Generator|⍳}} or '''Interval''', often called by the name of its [[glyph]] '''Iota''', is a [[monadic]] [[primitive function]] which returns an array of [[index|indices]] with [[shape]] given by the right [[argument]]. In the result, the [[element]] at each [[index]] is that index. | {{Built-in|Index Generator|⍳}} or '''Interval''', often called by the name of its [[glyph]] '''Iota''', is a [[monadic]] [[primitive function]] which returns an array of [[index|indices]] with [[shape]] given by the right [[argument]]. In the result, the [[element]] at each [[index]] is that index. | ||
Originally, Iota was defined only on a single number. In [[APL/360]], and all later APLs, < | Originally, Iota was defined only on a single number. In [[APL/360]], and all later APLs, <syntaxhighlight lang=apl inline>⍳l</syntaxhighlight> for a [[scalar]] <syntaxhighlight lang=apl inline>l</syntaxhighlight> returns a [[simple]] [[numeric]] [[vector]] of length <syntaxhighlight lang=apl inline>l</syntaxhighlight> counting from the [[index origin]] up. In [[Nested array theory|nested]] APLs, this result may be seen as an array of [[scalar]] indices; [[NARS]] extended Iota to allow a vector argument by making the result for a non-[[singleton]] vector be an array of vector indices. [[Flat array theory|Flat]] APLs do not use this extension, but may extend to multiple argument elements in different ways. [[A Dictionary of APL]] defines Iota to have [[function rank]] 0, and [[SHARP APL]] gives it rank 1 but requires each row (1-[[cell]]) of the argument to have length 1. In [[A+]] and [[J]] Iota of a vector returns an array which counts up in [[ravel order]], that is, it matches Iota of its [[bound]], [[reshape]]d. A+ refers to this function as '''Interval''' while J calls it '''Integers'''. | ||
== Examples == | == Examples == | ||
< | <syntaxhighlight lang=apl inline>⍳n</syntaxhighlight> returns the first <syntaxhighlight lang=apl inline>n</syntaxhighlight> [[index|indices]] in order: | ||
< | <syntaxhighlight lang=apl> | ||
⍳ 5 | ⍳ 5 | ||
1 2 3 4 5 | 1 2 3 4 5 | ||
</ | </syntaxhighlight> | ||
This result depends on [[index origin]]: if the index origin is set to zero, it starts counting from zero instead: | This result depends on [[index origin]]: if the index origin is set to zero, it starts counting from zero instead: | ||
< | <syntaxhighlight lang=apl> | ||
⎕IO ← 0 | ⎕IO ← 0 | ||
⍳ 5 | ⍳ 5 | ||
0 1 2 3 4 | 0 1 2 3 4 | ||
</ | </syntaxhighlight> | ||
An argument of < | An argument of <syntaxhighlight lang=apl inline>0</syntaxhighlight> produces the [[empty]] [[vector]], [[Zilde]]: | ||
< | <syntaxhighlight lang=apl> | ||
⍳ 0 | ⍳ 0 | ||
⍬ ≡ ⍳ 0 | ⍬ ≡ ⍳ 0 | ||
1 | 1 | ||
</ | </syntaxhighlight> | ||
=== Vector arguments === | === Vector arguments === | ||
In [[A+]] and [[J]], Iota always returns a [[simple]] array. The equivalence < | In [[A+]] and [[J]], Iota always returns a [[simple]] array. The equivalence <syntaxhighlight lang=apl inline>⍳V</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>V⍴⍳×/V</syntaxhighlight> defines the result for non-singleton vectors. If the argument is an [[empty]] vector, the result is a [[scalar]]: the [[index origin]] (which is always 0 in these languages). | ||
< | <syntaxhighlight lang=apl> | ||
⍳ 2 3 4 | ⍳ 2 3 4 | ||
0 1 2 3 | 0 1 2 3 | ||
Line 38: | Line 39: | ||
⍳ 0⍴0 | ⍳ 0⍴0 | ||
0 | 0 | ||
</ | </syntaxhighlight>{{Works in|[[A+]]}} | ||
We might call such a function a "[[ravel index]] generator" since the result is an array of [[scalar]] indices into its own [[ravel]]. In contrast, [[nested array theory|nested]] APLs, if they implement Iota for a vector argument ([[APL2]] and [[APLX]], for example, do not), use [[index|indices]] of [[element]]s: | We might call such a function a "[[ravel index]] generator" since the result is an array of [[scalar]] indices into its own [[ravel]]. In contrast, [[nested array theory|nested]] APLs, if they implement Iota for a vector argument ([[APL2]] and [[APLX]], for example, do not), use [[index|indices]] of [[element]]s: | ||
< | <syntaxhighlight lang=apl> | ||
⍳ 2 5 | ⍳ 2 5 | ||
┌───┬───┬───┬───┬───┐ | ┌───┬───┬───┬───┬───┐ | ||
Line 53: | Line 54: | ||
(⊂⍬) ≡ ⍳⍬ | (⊂⍬) ≡ ⍳⍬ | ||
1 | 1 | ||
</ | </syntaxhighlight>{{Works in|[[NARS]], [[NARS2000]], [[Dyalog APL]], [[GNU APL]], [[ngn/apl]], [[dzaima/APL]]}} | ||
The result of < | The result of <syntaxhighlight lang=apl inline>⍳⍬</syntaxhighlight> should have [[shape]] <syntaxhighlight lang=apl inline>⍬</syntaxhighlight>, implying it is a [[scalar]], and its only [[element]] must be the only possible [[index]] into a scalar, the [[empty]] vector. This means it must be <syntaxhighlight lang=apl inline>⊂⍬</syntaxhighlight>. However, [[Dyalog APL]] returned the scalar <syntaxhighlight lang=apl inline>⎕IO</syntaxhighlight> instead prior to [[Dyalog APL 13.0|version 13.0]]. | ||
=== Negative arguments === | === Negative arguments === | ||
Line 61: | Line 62: | ||
In the [[nested array theory|nested]] APL [[NARS2000]], negating one number in the argument subtracts that value from each index along the corresponding [[axis]]. | In the [[nested array theory|nested]] APL [[NARS2000]], negating one number in the argument subtracts that value from each index along the corresponding [[axis]]. | ||
< | <syntaxhighlight lang=apl> | ||
⍳2 ¯3 | ⍳2 ¯3 | ||
1 ¯2 1 ¯1 1 0 | 1 ¯2 1 ¯1 1 0 | ||
2 ¯2 2 ¯1 2 0 | 2 ¯2 2 ¯1 2 0 | ||
</ | </syntaxhighlight>{{Works in|[[NARS2000]], <syntaxhighlight lang=apl inline>⎕FEATURE[⎕IO]←1</syntaxhighlight>}} | ||
In [[J]], a negative number [[reverse]]s the result along that axis. | In [[J]], a negative number [[reverse]]s the result along that axis. | ||
< | <syntaxhighlight lang=j> | ||
i. 2 _3 | i. 2 _3 | ||
2 1 0 | 2 1 0 | ||
5 4 3 | 5 4 3 | ||
</ | </syntaxhighlight>{{Works in|[[J]]}} | ||
== Scalar-vector discrepancy in nested APLs == | == Scalar-vector discrepancy in nested APLs == | ||
In [[NARS]] and later [[Nested array theory|nested]] APLs which share its definition, the result of Iota is [[simple]] when the argument is a [[singleton]] and [[nested]] otherwise. This is because, when the argument is a singleton, each [[index]] in the result is represented as a [[scalar]] rather than a 1-[[element]] [[vector]]. [[dzaima/APL]] | In [[NARS]] and later [[Nested array theory|nested]] APLs which share its definition, the result of Iota is [[simple]] when the argument is a [[singleton]] and [[nested]] otherwise. This is because, when the argument is a singleton, each [[index]] in the result is represented as a [[scalar]] rather than a 1-[[element]] [[vector]]. [[dzaima/APL]] and [[Kap]] break from this definition by using vector indices whenever the argument is a vector, and scalar indices if the argument is a scalar, so that the result is only simple if the argument was scalar. This definition has the property that the [[shape]] of each index matches the shape of the argument. | ||
Such an extension breaks compatibility with earlier non-nested APLs: although these APLs required the argument of Iota to be a [[singleton]], they always allowed a [[scalar]] or [[vector]], and sometimes any [[singleton]]. This is because a shape to be passed to Iota would often naturally be a vector: for example, [[Shape]] always returns a vector, and a function such as [[Tally]] to return a scalar length did not exist. | Such an extension breaks compatibility with earlier non-nested APLs: although these APLs required the argument of Iota to be a [[singleton]], they always allowed a [[scalar]] or [[vector]], and sometimes any [[singleton]]. This is because a shape to be passed to Iota would often naturally be a vector: for example, [[Shape]] always returns a vector, and a function such as [[Tally]] to return a scalar length did not exist. | ||
[[NARS]] defines its extension using the equivalence < | [[NARS]] defines its extension using the equivalence <syntaxhighlight lang=apl inline>⍳R</syntaxhighlight> {{←→}} <syntaxhighlight lang=apl inline>⊃∘.,/⍳¨R</syntaxhighlight> based on an [[Outer Product]] [[reduction]]. For a singleton vector <syntaxhighlight lang=apl inline>R</syntaxhighlight>, this does yield a simple result, because <syntaxhighlight lang=apl inline>∘.,/</syntaxhighlight> leaves a singleton argument unchanged. However, this is arguably due to inconsistent design in [[Reduce]]: [[NARS]]'s creator, [[Bob Smith]], argues that [[Catenate]] reduction should yield a [[DOMAIN ERROR]], and the same arguments apply to its Outer Product.<ref>[[Bob Smith|Smith, Bob]]. [http://www.sudleyplace.com/APL/Reduction%20Of%20Singletons.pdf "Reduction of Singletons"]. [[Minnowbrook]] 2010.</ref> | ||
== History == | == History == | ||
The | The Greek letter iota, corresponding to the Latin letter i, now usually treated as a mnemonic for "integers" or "[[index]]", more likely stood for "identity" in early [[Iverson notation]]. [[Ken Iverson|Iverson]]'s 1960 paper ''The Description of Finite Sequential Processes'' states that "the identity [[permutation]] vector <math>\iota</math> is defined by the relation <math>\iota_j=j</math>."<ref>[[Ken Iverson]]. [https://www.jsoftware.com/papers/DFSP.htm ''The Description of Finite Sequential Processes'']. Proceedings of a Conference on Information Theory, C. Cherry and W. Jackson, Editors, Imperial College, London, 1960-08-29.</ref> Since <math>e</math> is a more typical letter to use for the identity permutation, it's possible that Iverson's choice was also motivated by the convention of using <math>\iota</math> for an [[wikipedia:inclusion map|inclusion map]], where iota now indicates "inclusion" or "injection".<ref name="iotashaming">Sean Parent. [https://sean-parent.stlab.cc/2019/01/04/iota.html "#iotashaming"]. sean-parent.stlab.cc. 2019-01-04.</ref> The term "inclusion" typically indicates that a particular injection is meant to be treated as an identity. | ||
The notation <math>\iota_o(n)</math>, "Interval", was used in [[A Programming Language]] for the vector of the first <math>n</math> indices starting at [[index origin]] <math>o</math>. Both arguments were optional, with <math>n</math> being implied by [[conformability]] if omitted. It was adopted with the obvious alterations in [[APL\360]], and extended to a vector argument for [[nested array theory|nested]] APLs by [[NARS]] and for [[flat array theory|flat]] arrays by [[A+]]. | |||
== Outside of APL == | |||
The name "iota" has sometimes been used to indicate an increasing sequence of integers even in languages other than APL. In the [[wikipedia:C++|C++11]] standard library, <syntaxhighlight lang=c++ inline>std::iota()</syntaxhighlight> fills an iterator with such a sequence, and was named after the APL glyph.<ref>cppreference.com. [https://en.cppreference.com/w/cpp/algorithm/iota std::iota]. Retrieved 2020-04-28.</ref><ref name="iotashaming"/><ref>Rob Mayoff. [https://stackoverflow.com/a/9244949 Answer to "What does iota of std::iota stand for?"] on Stack Overflow. Retrieved 2020-04-28.</ref> The [[wikipedia:Go (programming language)|Go]] language also uses the name <syntaxhighlight lang=go inline>iota</syntaxhighlight> as a predeclared identifier which represents increasing integers: each time it is used within a single constant declaration its value will be one higher.<ref>The Go Programming Language Specification. [https://golang.org/ref/spec#Iota Iota]. 2020-01-14.</ref> Functions named "iota" appear in libraries such as [[wikipedia:Scheme (programming language)|Scheme]]'s SRFI 1 (list library),<ref>Olin Shivers. [https://srfi.schemers.org/srfi-1/srfi-1.html#iota SRFI 1: List Library]. Finalized 1999-10-09.</ref> [[wikipedia:general-purpose computing on graphics processing units|GPGPU]] library [[wikipedia:ArrayFire|ArrayFire]],<ref>ArrayFire: Functions. [https://arrayfire.org/docs/group__data__func__iota.htm iota]. Jun 2, 2015.</ref> and [[wikipedia:JavaScript|JavaScript]] library scijs.<ref>scijs.not. [https://scijs.net/packages/#scijs/iota-array iota-array]. Retrieved 20223-05-11</ref> The [[wikipedia:Berkeley Software Distribution|BSD]] operating system (including derivative [[wikipedia:macOS|macOS]]) uses <syntaxhighlight lang=shell inline>jot</syntaxhighlight> to print sequential data, a name derived in part from APL's glyph.<ref>openbsd.org. [https://man.openbsd.org/jot#DESCRIPTION jot]. Retrieved 2022-08-04.</ref> | |||
== See also == | |||
* [[Range]] | |||
== External links == | == External links == | ||
=== Tutorials === | === Tutorials === | ||
Line 92: | Line 101: | ||
=== Documentation === | === Documentation === | ||
* [ | * [https://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Index%20Generator.htm Dyalog] | ||
* [http://wiki.nars2000.org/index.php/Index_Generator NARS2000] | * [http://wiki.nars2000.org/index.php/Index_Generator NARS2000] | ||
* [http://microapl.com/apl_help/ch_020_020_150.htm APLX] | * [http://microapl.com/apl_help/ch_020_020_150.htm APLX] | ||
* J [https://www.jsoftware.com/help/dictionary/didot.htm Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/idot Nuvoc] | * J [https://www.jsoftware.com/help/dictionary/didot.htm Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/idot Nuvoc] | ||
* [https://mlochbaum.github.io/BQN/doc/range.html BQN] (as Range) | |||
== References == | == References == | ||
<references /> | <references /> | ||
{{APL built-ins}} | {{APL built-ins}}[[Category:Primitive functions]] |