Back to Index Page

# Extending indices to floating-point values

#satire#apl

(Last edit: )

We all know 3 7 4 is 3 and 3 7 4 is 7, but what about 3 7 4[1.5]?

This article proposes an extension to indices in the APL family of languages, known as float indexing, which allows indexing an array X in its n-th dimension with any value in the (closed) interval ⎕io to ⎕io+n⌷⍴X, not just integers.

If X is a vector, the extension is quite trivial: define X[a] to be $\mathrm{lerp}($X[⌊a]$,$X[⌈a]$, t=$1|a$)$. For higher-rank arrays, this requires some more thought.

Consider X to be the matrix 2 2⍴3 9 4 1, and a the vector 1.5 1.5. Let's draw a picture:

3   9
\ /
a
/ \
4   1


It really looks like X[a] should be an average of 3, 9, 4 and 1, that is, 4.25. In general, X[a] will be some function of the subarray delimited by the entries X[⌊a] and X[⌈a]. We can calculate the coefficients for one particular value by looking at how close the value is to the desired index.

I wrote the following (intentionally ugly) function for float indexing:

∆I←{
bitstrings←(⊂⍴∘2)(,⊤)¨⎕io-⍨∘⍳2∘*
X←⍵
coefficients←×⌿{1∘-@(⍸⍵)⊢1|,⍺}
index←{X⌷⍨⌊@(⍸⍵)⌈@(⍸~⍵)⊢,⍺}
+⌿⍺∘(index×coefficients)¨bitstrings≢⍺
}


Surely someone will contact me(1) and propose a four glyphs long reimplementation that actually makes use of array-oriented principles and/or obscure Dyalog behavior.

Should other index-related functions be changed as well? Of course. 3 7 4⍳5 should return either ⎕io+÷2 or ⎕io+5÷3 (or maybe both?).

Edit 2023-09-22: I came up with ⊣(1⊥,⍤⊢×(×⌿¨⍤1∘|⍤|⊂⍤⊣-¨~⍤,⍤⍳⍤⍴⍤⊢))(2↑⌊⍤⊣↓⊢) which I think is equivalent if ⎕io←0. You tell me which is better :)

## Footnotes

1. If you actually want to contact me, ping @RubenVerg at The APL Orchard.