# Indexing arrays in APL: Squad indexing on multi-dimensional arrays

I had a question for the team in our regular meeting on Wednesday, but it relied on an understanding on squad indexing, and nobody felt comfortable enough with `⌷` to answer my question.

I’ve since reach a conclusion and thought I’d share.

## Squad indexing vs. Square bracket indexing

`````` ⎕←cube←?3 4 5⍴7
4 3 4 1 1
5 5 7 6 3
2 2 5 1 4
4 6 5 4 3

1 6 1 6 6
3 1 5 3 3
2 5 5 4 7
1 5 6 5 2

5 6 6 4 1
7 1 5 1 1
1 1 4 1 1
6 6 4 1 1
``````

For a given 3-dimensional object, I can use square bracket indexing to retrieve the indices I want. I can even omit a dimension completely to receive all items in that dimension, i.e. here I am asking for the first plane, the second row, and all columns:

``````     cube[1;2;]
5 5 7 6 3
``````

In this example, you can do the same with squad indexing- just omit any indices for that axis:

``````      1 2⌷cube
5 5 7 6 3
``````

Square bracket indexing has a bit more of an advantage for some cases, though. If the axes you want are non-contiguous, you can ask for `[x;;y]`. With squad indexing it’s not so simple. See the below example:

``````cube[1;;2]
3 5 2 6

1 ⍬ 2⌷cube
⍝ empty result
``````

My thoughts were with `[x;;y]`, `;; ←→ ⍬`, `⍬` representing an empty numeric array. This is not the case, however. As with typical indexing, the shape of the index is the shape of your result. Zilde is of shape 0 (`⍬←→ 0⍴0`), and therefore I would get back a shape 0 result:

``````      ⍴1 ⍬ 2⌷cube
0
``````

My question to the team was how would I perform an operation like this, similar to `[x;;y]`?

Gilgamesh Athoraya has since told me the only way of performing this kind of indexing is to use axis specification:

``````      1 2⌷[1 3]cube
3 5 2 6
``````

I feel like there should be a way to do it using without specifying axis. Zilde may not be appropriate, but it was my immediate go-to answer. In fact, what we’re after is not an empty array, but an array whose shape is that of the actual object- identity (`⊢`) would achieve something like this. There is a slight issue with using identity, though:

``````	1 ⊢ 2⌷cube
``````

Here, right tack will be used dyadically as a function, and return the right argument. Let me know your thoughts: how should squad indexing behave? Should there be a way of achieving this in APL without axis specification (identity, zilde, etc), or do you have a different opinion entirely?

## Why am I against axis specification with squad indexing?

I have an answer to my original question so I’ve quenched my thirst for knowledge and I have a workaround. The issue lies in performance. If we consider the same cube which was defined earlier (`cube←?3 4 5⍴7`) there are several ways of getting at all of the rows, some more efficient than others:

``````      ]runtime 'cube[1;;2]' '1 2⌷[1 3]cube' '1(1 2 3 4)2⌷cube' '1(⍳4)2⌷cube' -compare

cube[1;;2]       → 6.1E¯7 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
1 2⌷[1 3]cube    → 8.7E¯7 | +43% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
1(1 2 3 4)2⌷cube → 9.5E¯7 | +55% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
1(⍳4)2⌷cube      → 1.1E¯6 | +84% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
``````
Figure 1. Version: 17.0.36114.0 32 Unicode

Using axis-specification I am immediately hit by a 43% speed penalty and this is worsened further if I actually specify all rows by hand! Naturally, using `⍳4` in place of (1 2 3 4) yields a slower result still as a function is taking place to generate the indices.

Something about the omission of the indices with square-bracket indexing allows for a fast execution time, and this is something I’d like to see in squad indexing if it’s not already a feature.

James Heslip

James is an APL Programmer with a keen interest in mathematics. His love for computing was almost an accident. From a young age he always enjoyed using them- playing video games and such- but it was never considered that anything more would come from it. James originally had plans to pursue a career in finance. More about James.

More from James

APL9

APL9

Other Posts