> ## Documentation Index
> Fetch the complete documentation index at: https://antlobach-clorch-182a83cb.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Complete PyTorch-to-Clorch Tensor Slicing Reference

> Map every PyTorch indexing pattern to Clorch ix: integer indices, ranges, stepped slices, negative-step reversal, ellipsis, and boolean mask indexing.

Clorch exposes tensor indexing through a single function, `torch/ix`, that accepts a tensor followed by one indexer per dimension. Every PyTorch indexing pattern — from a simple integer access to a reversed multi-dimensional slice — has a direct `ix` equivalent. This guide provides a structured translation reference so you can convert Python notebooks and research implementations into idiomatic Clorch code without guessing.

## Quick Reference

The table below maps common PyTorch expressions to their Clorch equivalents.

| PyTorch | Clorch | Description |
| - | - | - |
| `t[0]` | `(ix t 0)` | Single element |
| `t[-1]` | `(ix t -1)` | Last element |
| `t[0, 1]` | `(ix t 0 1)` | Multi-dimensional |
| `t[:, :]` | `(ix t :all :all)` | Select all dimensions |
| `t[0:5]` | `(ix t [0 5])` | Range slice |
| `t[:5]` | `(ix t [nil 5])` | From start |
| `t[5:]` | `(ix t [5 nil])` | To end |
| `t[::2]` | `(ix t [nil nil 2])` | Every 2nd element |
| `t[1:8:2]` | `(ix t [1 8 2])` | Step slice |
| `t[::-1]` | `(ix t [nil nil -1])` | Reverse entire tensor |
| `t[5::-1]` | `(ix t [5 nil -1])` | Reverse from index 5 |
| `t[..., 0]` | `(ix t (quote ...) 0)` | Ellipsis |
| `t[0, ...]` | `(ix t 0 (quote ...))` | Ellipsis at end |

***

## Basic Indexing

### 1D Tensors

Integer indexing extracts a single scalar. Negative indices count from the end. All scalar results are returned as floats by default.

```clojure theme={null}
(require '[clorch.torch :as torch])

(def x (torch/tensor [10 11 12 13 14]))

(torch/ix x 0)   ;; → 10.0
(torch/ix x 1)   ;; → 11.0
(torch/ix x -1)  ;; → 14.0  (last element)
(torch/ix x -2)  ;; → 13.0  (second to last)
```

### Multi-dimensional Tensors

Pass one indexer per dimension. Providing fewer indexers than dimensions selects the full remaining dimensions.

```clojure theme={null}
(def x (torch/tensor [[1 2 3]
                      [4 5 6]
                      [7 8 9]]))

(torch/ix x 0)        ;; → [1.0, 2.0, 3.0]   (first row)
(torch/ix x -1)       ;; → [7.0, 8.0, 9.0]   (last row)
(torch/ix x 0 0)      ;; → 1.0
(torch/ix x 0 1)      ;; → 2.0
(torch/ix x :_ 0)     ;; → [1.0, 4.0, 7.0]   (first column)
(torch/ix x :_ -1)    ;; → [3.0, 6.0, 9.0]   (last column)
```

***

## Slicing

### Basic Ranges

A two-element vector `[start stop]` selects elements from `start` (inclusive) to `stop` (exclusive), matching Python's exclusive-stop convention.

```clojure theme={null}
(def y (torch/tensor (range 10)))  ;; [0 1 2 3 4 5 6 7 8 9]

(torch/ix y [2 5])    ;; → [2.0, 3.0, 4.0]
(torch/ix y [0 4])    ;; → [0.0, 1.0, 2.0, 3.0]
(torch/ix y [6 10])   ;; → [6.0, 7.0, 8.0, 9.0]
```

### Open-Ended Ranges

Use `nil` in place of a bound to leave it open. `[start nil]` runs to the end; `[nil stop]` starts from the beginning.

```clojure theme={null}
(torch/ix y [5 nil])    ;; → [5.0, 6.0, 7.0, 8.0, 9.0]  (last 5)
(torch/ix y [nil 5])    ;; → [0.0, 1.0, 2.0, 3.0, 4.0]  (first 5)
(torch/ix y [nil nil])  ;; → [0.0, ..., 9.0]             (all)
```

### Step Slices

A three-element vector `[start stop step]` applies a stride. Either or both of `start` and `stop` may be `nil` to leave that bound open.

```clojure theme={null}
(torch/ix y [nil nil 2])   ;; → [0.0, 2.0, 4.0, 6.0, 8.0]  (every 2nd)
(torch/ix y [1 nil 2])     ;; → [1.0, 3.0, 5.0, 7.0, 9.0]  (every 2nd from 1)
(torch/ix y [1 8 2])       ;; → [1.0, 3.0, 5.0, 7.0]        (every 2nd, range 1–8)
(torch/ix y [nil nil 3])   ;; → [0.0, 3.0, 6.0, 9.0]        (every 3rd)
```

### Negative Step Slicing (Reversing)

A negative step reverses traversal order. `[nil nil -1]` is the full reversal; `[start nil -1]` reverses from a given index down to zero.

```clojure theme={null}
(def t (torch/tensor (range 10)))

;; Full reverse
(torch/ix t [nil nil -1])    ;; → [9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0]

;; From index 5 back to start
(torch/ix t [5 nil -1])      ;; → [5.0, 4.0, 3.0, 2.0, 1.0, 0.0]

;; Partial reverse: indices 5, 4, 3 (stop=2 is exclusive)
(torch/ix t [5 2 -1])        ;; → [5.0, 4.0, 3.0]

;; Reverse every 2nd element
(torch/ix t [nil nil -2])    ;; → [9.0, 7.0, 5.0, 3.0, 1.0]

;; Reverse every 3rd element
(torch/ix t [nil nil -3])    ;; → [9.0, 6.0, 3.0, 0.0]
```

***

## 2D Tensor Examples

Multi-dimensional slicing combines one indexer per axis, separated by spaces.

```clojure theme={null}
(def x (torch/tensor [[0 1 2 3]
                      [4 5 6 7]
                      [8 9 10 11]]))

;; Rows 0–1, columns 1–2
(torch/ix x [0 2] [1 3])       ;; → [[1.0, 2.0], [5.0, 6.0]]

;; All rows, last two columns
(torch/ix x :all [2 4])        ;; → [[2.0, 3.0], [6.0, 7.0], [10.0, 11.0]]

;; Row 0, columns 1 to end
(torch/ix x 0 [1 4])           ;; → [1.0, 2.0, 3.0]

;; Every 2nd row, all columns
(torch/ix x [0 3 2] :all)      ;; → [[0.0, 1.0, 2.0, 3.0], [8.0, 9.0, 10.0, 11.0]]
```

### Reversing Rows and Columns

```clojure theme={null}
(def m (torch/tensor [[1 2 3 4]
                      [5 6 7 8]
                      [9 10 11 12]]))

;; Reverse rows
(torch/ix m [nil nil -1] :_)
;; → [[9.0, 10.0, 11.0, 12.0],
;;    [5.0, 6.0, 7.0, 8.0],
;;    [1.0, 2.0, 3.0, 4.0]]

;; Reverse columns
(torch/ix m :_ [nil nil -1])
;; → [[4.0, 3.0, 2.0, 1.0],
;;    [8.0, 7.0, 6.0, 5.0],
;;    [12.0, 11.0, 10.0, 9.0]]

;; Reverse both axes
(torch/ix m [nil nil -1] [nil nil -1])
;; → [[12.0, 11.0, 10.0, 9.0],
;;    [8.0, 7.0, 6.0, 5.0],
;;    [4.0, 3.0, 2.0, 1.0]]
```

***

## The `ix` Function: Indexer Type Reference

`torch/ix` accepts a tensor and any number of indexers — one per dimension you want to slice.

### Indexer Syntax Summary

| Clorch Syntax | Meaning |
| - | - |
| `0`, `1`, `-1` | Integer index — extracts a scalar, reduces dimensionality |
| `:all` | Select entire dimension |
| `:_` | Select entire dimension (alternative spelling) |
| `(quote ...)` | Ellipsis — fills all remaining unspecified dimensions |
| `[start stop]` | Slice from `start` (inclusive) to `stop` (exclusive) |
| `[start stop step]` | Slice with positive step |
| `[nil stop]` | From index 0 to `stop` |
| `[start nil]` | From `start` to end of dimension |
| `[nil nil step]` | Every `step`-th element, full dimension |
| `[nil nil -1]` | Reverse entire dimension |
| `[nil nil -2]` | Reverse every 2nd element |
| `[start nil -1]` | Reverse from `start` down to index 0 |

***

## Advanced Indexing

### Ellipsis

The ellipsis fills all unspecified dimensions between explicitly indexed ones. Use `(quote ...)` or the reader shorthand `'...` in scripts.

```clojure theme={null}
(def t3d (torch/reshape (torch/tensor (range 24)) [2 3 4]))

;; First element along dimension 0, all others
(torch/ix t3d 0 (quote ...))    ;; → shape [3, 4]

;; All along first dims, first element of last dim
(torch/ix t3d (quote ...) 0)    ;; → shape [2, 3]

;; Specific position with middle dimensions filled
(torch/ix t3d 1 (quote ...) 2)  ;; → shape [3]
```

### Select-All Identity

`:all` and `:_` are interchangeable. Using them on every dimension returns the tensor unchanged.

```clojure theme={null}
(def t (torch/tensor [[1 2 3]
                      [4 5 6]]))

(torch/ix t :all :all)   ;; → full tensor
(torch/ix t :_ :_)       ;; → full tensor (same result)
```

### Integer Tensor (Fancy) Indexing

Pass a tensor with dtype `:int64` as an indexer to perform gather-style selection.

```clojure theme={null}
(def m (torch/tensor [[1 2 3]
                      [4 5 6]
                      [7 8 9]
                      [10 11 12]]))

(def idx (torch/tensor [0 2 0 1] {:dtype :int64}))

(torch/ix m idx)        ;; → shape [4, 3]  — rows 0, 2, 0, 1
(torch/ix m :_ idx)     ;; → shape [4, 4]  — columns by index
```

### Boolean Mask Indexing

Pass a boolean tensor to select elements where the mask is `true`.

```clojure theme={null}
(def t (torch/tensor [1 2 3 4 5]))
(def mask (torch/tensor [false false true true true] {:dtype :bool}))

(torch/ix t mask)   ;; → [3.0, 4.0, 5.0]
```

***

## Helper Pattern: Tensor to Clojure Vector

When you need to work with slice results in pure Clojure, convert with `item-float` and `tseq`.

```clojure theme={null}
(defn tensor->vec [t]
  (mapv torch/item-float (torch/tseq t)))

(defn tensor->vecs [t]
  (mapv #(mapv torch/item-float (torch/tseq %)) (torch/tseq t)))

;; Usage
(def x (torch/tensor [1 2 3]))
(tensor->vec (torch/ix x [0 2]))   ;; → [1.0 2.0]
```

***

## Real-World Patterns

<Accordion title="Train/test split">
  ```clojure theme={null}
  (def data (torch/tensor (range 100)))
  (def split-point 80)

  (def train (torch/ix data [0 split-point]))
  (def test  (torch/ix data [split-point nil]))
  ```
</Accordion>

<Accordion title="Extract mini-batches">
  ```clojure theme={null}
  (def batch-data (torch/tensor (range 100)))
  (def batch-size 16)
  (def batch-idx 2)

  (def start (* batch-idx batch-size))
  (def end (+ start batch-size))

  (torch/ix batch-data [start end])
  ```
</Accordion>

<Accordion title="Sliding window sequences">
  ```clojure theme={null}
  (def sequence (torch/tensor (range 20)))
  (def window-size 5)
  (def stride 3)

  ;; Window at offset
  (defn window [offset]
    (torch/ix sequence [offset (+ offset window-size)]))

  (window 0)  ;; → [0.0, 1.0, 2.0, 3.0, 4.0]
  (window 3)  ;; → [3.0, 4.0, 5.0, 6.0, 7.0]
  ```
</Accordion>

***

## Important Notes

<Note>
  **Float results.** Scalar extractions via integer indexing return `double` values. Use `torch/item-float` to extract a Clojure number from a 0-dimensional tensor result.
</Note>

<Note>
  **`nil` vs `::`.** Slice vectors use `nil` to denote open bounds, not Clojure's auto-qualified `::` keywords, which would conflict with the keyword indexer namespace.
</Note>

<Warning>
  **Ellipsis quoting.** The bare symbol `...` is a valid Clojure symbol but may be read differently at the REPL versus in compiled source. Always use `(quote ...)` or the `'...` reader macro inside scripts to guarantee correct behavior.
</Warning>

<Tip>
  Run the full example file to verify every slice operation in one pass:

  ```bash theme={null}
  clojure -M -e "(load-file \"examples/slicing_examples.clj\")"
  ```
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.