Back to Index Page

Extending indices to floating-point values

#satire#apl

Madeline Vergani
 (Last edit: )

We all know 3 7 4[1] is 3 and 3 7 4[2] 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 l e r p ( \mathrm{lerp}( X[⌊a] , , X[⌈a] , t = , 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.