

# `⍠` — Axis

Keys: `Alt-q :`

`f⍠A` applies `f` to the cells made of the axes `A`. The other axes form
the frame. `A` is a list of axes, given as numbers or names. Axes count
from 0, and negative axes count from the end.

``` bpl
m←2 3⍴⍳6
{+/⍵}⍠0 m                 ⍝ 3 5 7
ax←0 ⋄ {+/⍵}⍠ax m         ⍝ 3 5 7
```

Rank is the case that selects the last `r` axes. So `⍤1` and `⍠¯1` both
select the last axis.

``` bpl
m←2 3⍴⍳6
+/⍤1 m                    ⍝ 3 12
+/⍠¯1 m                   ⍝ 3 12
+/⍠0 m                    ⍝ 3 5 7
```

Result cells with the same rank as the selected cells return to the axes
`A`. Other result cells start at the position of the first selected
axis.

``` bpl
m←2 3⍴⍳6
{⌽⍵}⍠0 m                  ⍝ [3 4 5 ⋄ 0 1 2]
⍴{,⍵}⍠0 1 (2 3 4⍴⍳24)     ⍝ [6 4]ₓ
```

With two arguments, `A` applies to both. Cells pair using leading
agreement of the frames, as for [Rank](rank.qmd). An argument without
the selected axes is one whole cell, paired with every cell of the other
argument.

``` bpl
m←2 3⍴⍳6
1 0 1 {⍺#⍵}⍠1 m           ⍝ [0 2 ⋄ 3 5]
10 20 {⍺+⍵}⍠0 m           ⍝ [10 11 12 ⋄ 23 24 25]
```

A string names one axis, and a list of strings names several.

``` bpl
n←["row":2 "col":3]⍴⍳6
{+/⍵}⍠"row" n             ⍝ ["col":3]⍴3 5 7
{+/,⍵}⍠"row" "col" n      ⍝ 15
```

## Exceptions

A primitive with its own axis meaning keeps it:

- Multi-axis reduce, including seeded reduce. `+/⍠1 2` flattens each
  cell before reducing.
- Partitioned enclose and partition. `1 0 1 0⊂⍠1` and `1 1 2 2⊆⍠1` cut
  the whole matrix into blocks along axis 1. `⊂⍠K` matches Dyalog.
  Dyalog’s `⊆[K]` partitions each lane instead, which is `{⍺⊆⍵}⍠K` here.
- Rotate with a count array. `1 2 3 4⌽⍠0` pairs one count with each
  column.
- Mix. `⊃⍠A` places the cell axes among the frame axes.
- Axis selectors. `⍳⍠A` returns the keys or positions of the selected
  axes.

``` bpl
+/⍠1 2 (2 3 4⍴⍳24)        ⍝ 66 210
```

Wrapping a primitive in a dfn gives the general rule:

``` bpl
{+/⍵}⍠1 2 (2 3 4⍴⍳24)     ⍝ [6 22 38 ⋄ 54 70 86]
```

## Errors

- `RANK`: an axis operand that is not a unit or vector
- `DOMAIN`: non-integral axes, repeated axes, axes outside the
  higher-rank argument
