13
edits
No edit summary |
No edit summary |
||
(6 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
{{Built-in|Decode|⊥}}, also called '''Base''', is a [[dyadic]] [[primitive function]] which evaluates the right [[argument]] in terms of the radix system defined by the left argument. Some implementations add [[monadic]] usage to this function, where the left argument defaults to the [[scalar]] 2. Decode is the [[inverse]] of [[Encode]] < | {{Built-in|Decode|⊥}}, also called '''Base''', is a [[dyadic]] [[primitive function]] which evaluates the right [[argument]] in terms of the radix system defined by the left argument. Some implementations add [[monadic]] usage to this function, where the left argument defaults to the [[scalar]] 2. Decode is the [[inverse]] of [[Encode]] <syntaxhighlight lang=apl inline>⊤</syntaxhighlight> with the same left argument X, when X is a [[vector]] and the right argument is a valid representation of a number in the radix system defined by X. | ||
== APL model == | == APL model == | ||
Line 5: | Line 5: | ||
Decode can be viewed as calculating the "digit values" defined by the radix system, followed by [[Inner Product|inner product]]. The digit values are found by [[times|product]] [[scan]]. Note that the first number of the radix is ignored; it is there simply to be consistent with [[Encode]]. | Decode can be viewed as calculating the "digit values" defined by the radix system, followed by [[Inner Product|inner product]]. The digit values are found by [[times|product]] [[scan]]. Note that the first number of the radix is ignored; it is there simply to be consistent with [[Encode]]. | ||
< | <syntaxhighlight lang=apl> | ||
0 24 60⊥∘.=⍨⍳3 ⍝ 1 day is 24 hours = 1440 minutes, 1 hour is 60 minutes | 0 24 60⊥∘.=⍨⍳3 ⍝ 1 day is 24 hours = 1440 minutes, 1 hour is 60 minutes | ||
1440 60 1 | 1440 60 1 | ||
⌽×\1,⌽1↓0 24 60 ⍝ The digit values of radix 0 24 60 | ⌽×\1,⌽1↓0 24 60 ⍝ The digit values of radix 0 24 60 | ||
1440 60 1 | 1440 60 1 | ||
</ | </syntaxhighlight> | ||
If the left argument is a [[scalar]] number, it is converted to a [[vector]] filled with that number. | If the left argument is a [[scalar]] number, it is converted to a [[vector]] filled with that number. | ||
< | <syntaxhighlight lang=apl> | ||
10⊥∘.=⍨⍳3 ⍝ Base 10 | 10⊥∘.=⍨⍳3 ⍝ Base 10 | ||
100 10 1 | 100 10 1 | ||
⌽×\1,⌽1↓3⍴10 | ⌽×\1,⌽1↓3⍴10 | ||
100 10 1 | 100 10 1 | ||
</ | </syntaxhighlight> | ||
The resulting model looks like this: | The resulting model looks like this: | ||
< | <syntaxhighlight lang=apl> | ||
Decode←{ | Decode←{ | ||
(⌽×\1,⌽(1↓(≢⍵)⍴⊢)⍤1⊢⍺)+.×⍵ | (⌽×\1,⌽(1↓(≢⍵)⍴⊢)⍤1⊢⍺)+.×⍵ | ||
} | } | ||
</ | </syntaxhighlight> | ||
== Examples == | == Examples == | ||
Line 33: | Line 33: | ||
A common use case is to convert from base-N digits to an integer, usually in base 2 or 10. | A common use case is to convert from base-N digits to an integer, usually in base 2 or 10. | ||
< | <syntaxhighlight lang=apl> | ||
10⊥1 2 3 4 5 ⍝ Base 10 | 10⊥1 2 3 4 5 ⍝ Base 10 | ||
12345 | 12345 | ||
2⊥1 0 1 0 1 ⍝ Base 2 | 2⊥1 0 1 0 1 ⍝ Base 2 | ||
21 | 21 | ||
</ | </syntaxhighlight> | ||
But since the left and right argument's values are not restricted in any way, < | But since the left and right argument's values are not restricted in any way, <syntaxhighlight lang=apl inline>X⊥Y</syntaxhighlight> with scalar X can also be thought as evaluating the [[wikipedia:Polynomial|polynomial]] Y at given value X. For example, evaluating <math>y = 2x^4 + 3x + 1</math> at <math>x = -3</math> can be done as follows: | ||
< | <syntaxhighlight lang=apl> | ||
¯3⊥2 0 0 3 1 ⍝ Polynomial terms are written highest first, and absent terms are written as 0 | ¯3⊥2 0 0 3 1 ⍝ Polynomial terms are written highest first, and absent terms are written as 0 | ||
154 | 154 | ||
</ | </syntaxhighlight> | ||
Decode can be also used to convert from a measure given in a hierarchy of units to the smallest unit. For example, given that 1 day = 24 hours, 1 hour = 60 minutes, and 1 minute = 60 seconds, how many seconds is 2 days, 10 hours, 34 minutes, and 19 seconds? | Decode can be also used to convert from a measure given in a hierarchy of units to the smallest unit. For example, given that 1 day = 24 hours, 1 hour = 60 minutes, and 1 minute = 60 seconds, how many seconds is 2 days, 10 hours, 34 minutes, and 19 seconds? | ||
< | <syntaxhighlight lang=apl> | ||
0 24 60 60⊥2 10 34 19 | 0 24 60 60⊥2 10 34 19 | ||
210859 | 210859 | ||
</ | </syntaxhighlight> | ||
Decode can be also found in many [[idiom|idioms]]. Some of the simple and useful ones are reproduced here: | Decode can be also found in many [[idiom|idioms]]. Some of the simple and useful ones are reproduced here: | ||
< | <syntaxhighlight lang=apl> | ||
⎕←M←3 4⍴⍳12 | ⎕←M←3 4⍴⍳12 | ||
1 2 3 4 | 1 2 3 4 | ||
Line 77: | Line 77: | ||
⊥⍨1 1 0 1 1 1 | ⊥⍨1 1 0 1 1 1 | ||
3 | 3 | ||
</ | </syntaxhighlight> | ||
Kamila Szewczyk suggests the following explanation for the mechanism of action of <syntaxhighlight lang=apl inline>⊥⍨</syntaxhighlight>. Consider the model <syntaxhighlight lang=apl inline>⊥ ≡ {⍵+.×⌽×\1,⌽1↓(≢⍵)⍴⍺}</syntaxhighlight> for a vector (rank 1) <syntaxhighlight lang=apl inline>⍺</syntaxhighlight>. Setting <syntaxhighlight lang=apl inline>⍺≡⍵</syntaxhighlight> yields <syntaxhighlight lang=apl inline>⊥⍨ ≡ {⍵+.×⌽×\1,⌽1↓⍵}</syntaxhighlight> under the same assumptions. Let's dissect the model: <syntaxhighlight lang=apl inline>1,⌽1↓⍵</syntaxhighlight> drops the first element, reverses the vector and prepends it with an one; <syntaxhighlight lang=apl inline>×\</syntaxhighlight> turns off all ones after the first zero, because once it stumbles upon a zero, then for all x, 0*x = 0. Ultimately, <syntaxhighlight lang=apl inline>⌽×\1,⌽1↓⍵</syntaxhighlight> essentially sets all bit to 1 that appear after or on the last zero of a boolean vector. To count the trailing ones, count all the ones that appear after the last zero of a boolean vector. Hence, notice that multiplying the input by this bitmask from the <syntaxhighlight lang=apl inline>⌽×\1,⌽1↓⍵</syntaxhighlight> part will return a vector where ones correspond to the trailing ones, so the sum in the inner product counts them all. | |||
< | Decode has an important property with array [[index]]: Given an arbitrary array A with [[shape]] S, the index of an [[element]] in A can be decoded with S to obtain the corresponding index in the [[ravel]] of A. Decoding all indices given by [[Index Generator]] shows the ravel order of the elements of an array with the given shape. Note that [[index origin]] 0 (<syntaxhighlight lang=apl inline>⎕IO←0</syntaxhighlight>) is required for this to hold. | ||
<syntaxhighlight lang=apl> | |||
⎕IO←0 | ⎕IO←0 | ||
M←2 3 4⍴⎕A | M←2 3 4⍴⎕A | ||
Line 94: | Line 96: | ||
16 17 18 19 | 16 17 18 19 | ||
20 21 22 23 | 20 21 22 23 | ||
</ | </syntaxhighlight> | ||
== External links == | == External links == | ||
Line 106: | Line 108: | ||
* [https://help.dyalog.com/latest/#Language/Primitive%20Functions/Decode.htm Dyalog] | * [https://help.dyalog.com/latest/#Language/Primitive%20Functions/Decode.htm Dyalog] | ||
* [http://microapl.com/apl_help/ch_020_020_660.htm APLX] | * [http://microapl.com/apl_help/ch_020_020_660.htm APLX] | ||
* J [https://www.jsoftware.com/help/dictionary/d401.htm Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/numberdot NuVoc] (as < | * J [https://www.jsoftware.com/help/dictionary/d401.htm Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/numberdot#dyadic NuVoc] (as <syntaxhighlight lang=j inline>#.</syntaxhighlight>) | ||
{{APL built-ins}}[[Category:Primitive functions]] | {{APL built-ins}}[[Category:Primitive functions]] |
edits