# Tensors and Views

> NumKong for Rust

The container model is unusual enough that it needs direct documentation.

- `Vector<T>` owns one-dimensional storage.
- `VectorView<'a, T>` is an immutable borrowed view.
- `VectorSpan<'a, T>` is a mutable borrowed view.
- `Tensor<T, A, MAX_RANK>` owns N-dimensional storage and can use a custom allocator.
- `TensorView` and `TensorSpan` are the borrowed forms.
- `Matrix<T>` is a rank-2 alias over `Tensor<T, _, 2>`.

The allocator story is explicit.
`Tensor` and `DotsPackedMatrix` are generic over `core::alloc::Allocator` and default to `numkong::Global`, which forwards to the system heap.
Views and spans borrow their owner's allocator, and every allocating operation, like `view.sin()` or `view.dots_packed(&packed)`, allocates its result through a clone of its first operand's allocator.
An arena that is not `Clone` works by reference, as `&Arena`, and views over foreign memory report `Global`.
Owned allocations start on `DEFAULT_ALIGNMENT`, the C library's boundary: 128 bytes on Arm and x86, 64 on WASM, 256 on IBM Z.
That does _not_ mean callers must align their source buffers manually.
It means owned outputs and packed payloads are allocated in a SIMD-friendly way when the crate owns them.

Owned containers are fixed-capacity resizable.
`capacity()` reports the allocated storage-value ceiling.
`resize()` reshapes within that ceiling without moving storage, so an outstanding `as_slice`/`view`/`span` is never invalidated — the borrow checker rejects a `&mut self` resize while any borrow is alive, so this is enforced at compile time.
`reserve()` is the explicit opt-in that may reallocate and move storage to grow, and `clear()` empties the logical shape while keeping capacity.
`ScaledTensor` resizes its packed elements and per-block scales in lockstep.

```rust
use numkong::{RangeStep, SliceRange, Tensor};

let t = Tensor::<f32>::from_slice(&[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], &[3, 3]).unwrap();

let col = t.slice((.., 1_usize)).unwrap();                  // t[:, 1]  — column 1
let rows = t.slice((0..2_usize, ..)).unwrap();              // t[0:2, :] — first two rows
let tail = t.slice((-2_isize.., ..)).unwrap();              // t[-2:, :] — last two rows
let neg = t.slice((.., -2..-1_isize)).unwrap();             // t[:, -2:-1]
let step = t.slice((.., RangeStep::new(0, 3, 2))).unwrap(); // t[:, ::2]

// Explicit &[SliceRange] syntax also works
let col = t.slice(&[SliceRange::full(), SliceRange::index(1)]).unwrap();
```

Tuple elements implement `SliceArg` — each monomorphized with zero runtime dispatch:

| Rust syntax                     | Meaning                                |
| :------------------------------ | :------------------------------------- |
| `..`                            | all                                    |
| `0_usize` / `-1_isize`          | single index (negative wraps from end) |
| `1..4_usize` / `-3..-1_isize`   | half-open range                        |
| `..3_usize` / `..-1_isize`      | from start                             |
| `1_usize..` / `-2_isize..`      | to end                                 |
| `0..=2_usize` / `-3..=-1_isize` | inclusive range                        |
| `RangeStep::new(0, 6, 2)`       | stepped (no Rust literal)              |

Integer literals default to `i32` — use `_usize` / `_isize` suffixes.
Negative `isize` values wrap from the dimension end, like Python.

Iteration works at the logical-dimension level.
For sub-byte types like `i4x2`, iteration yields one item per dimension, so a 6-dimension vector stored in 3 bytes yields 6 items.
Immutable iterators (`iter()`) yield `DimRef<T>`, which dereferences to `T::DimScalar`.
Mutable iterators (`iter_mut()`) yield `DimMut<T>`, which writes back on drop — the only way to mutate individual nibbles or bits.

```rust
use numkong::{Vector, i4x2};

let mut nibbles = Vector::<i4x2>::zeros(4).unwrap();
for (i, mut dim) in nibbles.iter_mut().enumerate() {
    *dim = i as i8;
}
assert_eq!(nibbles.get(0_usize).unwrap(), 0);
assert_eq!(nibbles.get(3_usize).unwrap(), 3);
```

Vectors and tensors can be converted between each other without copying:

```rust
use numkong::{Vector, Tensor};

let v = Vector::<f32>::from_scalars(&[1.0, 2.0, 3.0]).unwrap();
let t: Tensor<f32, _, 8> = v.into_tensor().unwrap();
assert_eq!(t.shape(), &[3]);
let v2 = t.into_vector().unwrap();
assert_eq!(v2.dims(), 3);
```

The main layout rules are:

- General slicing and transposition are supported by views.
- Elementwise and many reduction kernels accept strided views.
- Matrix-style kernels require rank-2 inputs with contiguous rows.
- A tensor can be non-contiguous overall and still have contiguous rows.
- Some reductions have SIMD kernels for strided lanes.
- Some backends still fall back depending on alignment and dtype.

Sub-byte types (`i4x2`, `u4x2`, `u1x8`) use logical shapes.
A shape of `[8]` for `i4x2` means 8 nibbles (stored in 4 bytes), not 8 bytes.
The innermost extent counts dimensions, a multiple of the values per byte: 2 for nibble types, 8 for bit types.
Transpose and reshape are not supported for sub-byte types — they return `SubByteUnsupported`.

`use numkong::DimMut;`

`use numkong::DimRef;`

`use numkong::AxisIterator;`

`use numkong::AxisIteratorMut;`

`use numkong::CopyFrom;`

`use numkong::Fill;`

`use numkong::RangeStep;`

`use numkong::ScaledTensor;`

`use numkong::ScaledTensorSpan;`

`use numkong::ScaledTensorView;`

`use numkong::SliceArg;`

`use numkong::SliceRange;`

`use numkong::SliceSpec;`

`use numkong::Tensor;`

`use numkong::TensorMut;`

`use numkong::TensorRef;`

`use numkong::TensorSpan;`

`use numkong::TensorSpanDims;`

`use numkong::TensorSpanIterator;`

`use numkong::TensorView;`

`use numkong::TensorViewDims;`

`use numkong::TensorViewIterator;`

`use numkong::Vector;`

`use numkong::VectorIndex;`

`use numkong::VectorSpan;`

`use numkong::VectorSpanIterator;`

`use numkong::VectorView;`

`use numkong::VectorViewIterator;`

`use numkong::types::DimLocation;`

`use numkong::vector::BitRef;`

`use numkong::vector::BitRefMut;`

`use numkong::tensor::*;`

`use numkong::*;`

## TensorIterator

Backward-compatible alias for [`TensorViewIterator`](#TensorViewIterator).

```rust
pub type TensorIterator<'a, Scalar, const MAX_RANK: usize = DEFAULT_MAX_RANK> = TensorViewIterator<'a, Scalar, MAX_RANK>;
```

## TensorDims

Backward-compatible alias for [`TensorViewDims`](#TensorViewDims).

```rust
pub type TensorDims<'a, Scalar, const MAX_RANK: usize = DEFAULT_MAX_RANK> = TensorViewDims<'a, Scalar, MAX_RANK>;
```

## TensorValues

Backward-compatible alias for [`TensorViewDims`](#TensorViewDims).

```rust
pub type TensorValues<'a, Scalar, const MAX_RANK: usize = DEFAULT_MAX_RANK> = TensorViewDims<'a, Scalar, MAX_RANK>;
```

## Matrix

Type alias for a 2D matrix — a Tensor with MAX_RANK=2.

```rust
pub type Matrix<Scalar, Alloc = Global> = Tensor<Scalar, Alloc, 2>;
```

## MatrixView

Type alias for an immutable 2D matrix view.

```rust
pub type MatrixView<'a, Scalar, Alloc = Global> = TensorView<'a, Scalar, 2, Alloc>;
```

## MatrixSpan

Type alias for a mutable 2D matrix view.

```rust
pub type MatrixSpan<'a, Scalar, Alloc = Global> = TensorSpan<'a, Scalar, 2, Alloc>;
```

## VectorIterator

Backward-compatible alias for [`VectorViewIterator`](#VectorViewIterator).

```rust
pub type VectorIterator<'a, Scalar> = VectorViewIterator<'a, Scalar>;
```

## DimMut

Mutable proxy for a single logical dimension within a packed storage value.

```rust
pub struct DimMut<'a, Scalar: FloatConvertible>
```

On `Drop`, performs a read-modify-write: reads the current storage value, overwrites the
sub-dimension at `sub_index`, and writes back.

For normal types (`dimensions_per_value() == 1`), this is equivalent to `&mut Scalar`.
For sub-byte types, this enables modifying individual nibbles/bits.

#### Aliasing

In a standard `for` loop each proxy is dropped before the next is created; holding multiple
proxies to sub-dimensions of the same storage value simultaneously is safe but uses
last-writer-wins semantics.

Implements: `Deref`, `DerefMut`, `Drop`, `Debug`, `Display`

## new

Create a new mutable dimension proxy.

```rust
pub unsafe fn new(ptr: *mut Scalar, sub_index: usize, value: Scalar::DimScalar) -> Self
```

Safety: `ptr` must be valid for reads and writes for the duration of `'a`.

## DimRef

Immutable proxy for a single logical dimension within a packed storage value.

```rust
pub struct DimRef<'a, Scalar: FloatConvertible>
```

For normal types this is equivalent to a [`Scalar::DimScalar`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#DimScalar) copy.
For sub-byte types it represents one unpacked dimension from a packed value.
The lifetime ensures the proxy does not outlive the container it came from.

Implements: `Copy`, `Clone`, `Deref`, `PartialEq`, `PartialOrd`, `Debug`, `Display`

## new

Create a new immutable dimension proxy.

```rust
pub fn new(value: Scalar::DimScalar) -> Self
```

## AxisIterator

Iterator over sub-tensor views along a given axis.

```rust
pub struct AxisIterator<'a, Scalar, const MAX_RANK: usize = DEFAULT_MAX_RANK, Alloc = Global>
```

Each item is a [`TensorView`](#TensorView) with the iterated dimension removed, leaving rank minus one. For a
rank-2 matrix, `axis_views(0)` yields row views.

Implements: `Iterator`, `ExactSizeIterator`, `FusedIterator`

## AxisIteratorMut

Mutable iterator over sub-tensor spans along a given axis.

```rust
pub struct AxisIteratorMut<'a, Scalar, const MAX_RANK: usize = DEFAULT_MAX_RANK, Alloc = Global>
```

Each item is a [`TensorSpan`](#TensorSpan) with the iterated dimension removed, leaving rank minus one. For a
rank-2 matrix, `axis_spans(0)` yields mutable row spans.

Implements: `Iterator`, `ExactSizeIterator`, `FusedIterator`

## CopyFrom

Copy storage from a `Source` into this container in place.

```rust
pub trait CopyFrom<Source>
```

`Source` is the natural read-side counterpart for the implementor:
`&[Scalar]`, the raw storage slice, for an owning [`Tensor`](#Tensor) or [`Vector`](#Vector), or the matching `View`
type for span implementors, mirroring [`tensor_span::copy_from`](#copy_from) and [`vector_span::copy_from`](#copy_from) on
the C++ side.

Implementors: - `impl<Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), Alloc: Allocator, const MAX_RANK: usize> [CopyFrom](#CopyFrom)<&[Scalar]> for [Tensor](#Tensor)<Scalar, Alloc, MAX_RANK>`
- `impl<'a, 'b, Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), const MAX_RANK: usize, Alloc: Allocator, SourceAlloc: Allocator> [CopyFrom](#CopyFrom)<&'b [TensorView](#TensorView)<'_, Scalar, MAX_RANK, SourceAlloc>> for [TensorSpan](#TensorSpan)<'a, Scalar, MAX_RANK, Alloc>`
- `impl<Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), Alloc: Allocator> [CopyFrom](#CopyFrom)<&[Scalar]> for [Vector](#Vector)<Scalar, Alloc>`
- `impl<'a, 'b, Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), Alloc: Allocator, SourceAlloc: Allocator> [CopyFrom](#CopyFrom)<&'b [VectorView](#VectorView)<'_, Scalar, SourceAlloc>> for [VectorSpan](#VectorSpan)<'a, Scalar, Alloc>`

## copy_*_from

Copy from `source` into self.

```rust
fn copy__from(&mut self, source: Source) -> Result<(), Error>
```

Returns an error on a shape or storage mismatch and does not
modify the destination on error.

## Fill

In-place fill operations shared by every mutable container of [`Scalar`](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#Scalar).

```rust
pub trait Fill<Scalar: StorageElement>
```

Implemented for [`Tensor`](#Tensor), [`TensorSpan`](#TensorSpan), [`crate::vector::Vector`](#Vector), and
[`crate::vector::VectorSpan`](#VectorSpan). Mirrors `tensor_span::fill_zeros / fill` and
`vector_span::fill_zeros / fill` from the C++ side. Both methods are infallible and operate on
every storage byte the container owns or borrows.

Implementors: - `impl<Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), Alloc: Allocator, const MAX_RANK: usize> [Fill](#Fill)<Scalar> for [Tensor](#Tensor)<Scalar, Alloc, MAX_RANK>`
- `impl<'a, Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), const MAX_RANK: usize, Alloc: Allocator> [Fill](#Fill)<Scalar> for [TensorSpan](#TensorSpan)<'a, Scalar, MAX_RANK, Alloc>`
- `impl<Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), Alloc: Allocator> [Fill](#Fill)<Scalar> for [Vector](#Vector)<Scalar, Alloc>`
- `impl<'a, Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), Alloc: Allocator> [Fill](#Fill)<Scalar> for [VectorSpan](#VectorSpan)<'a, Scalar, Alloc>`

## fill_*_zeros

Set every storage byte to zero.

```rust
fn fill__zeros(&mut self)
```

Works for every [`StorageElement`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement) since the binary-zero of
all NumKong scalar dtypes is the value-zero.

## *

Set every storage element to `value`.

```rust
fn fill(&mut self, value: Scalar)
```

For 1-byte storage, including sub-byte packings, this
becomes a single byte-pattern memset; for multi-byte storage it falls through to a typed
broadcast loop on the pre-zeroed buffer, so float NaN/inf patterns from uninitialised memory
cannot leak through.

## RangeStep

A stepped range for use in tuple-based slicing — compile-time dispatch.

```rust
pub struct RangeStep
```

Rust has no built-in literal for stepped ranges, so this struct fills that gap. Use it inside
`.slice()` tuples:

```
t.slice((.., RangeStep::new(0, 6, 2))).unwrap();  // t[:, 0:6:2]
```

- `start` `usize`: First index, inclusive.
- `end` `usize`: Last index, exclusive.
- `step` `isize`: Distance between consecutive indices.

Implements: `Clone`, `Copy`, `Debug`, `[SliceArg](#SliceArg)`

## new

Builds a stepped range from its bounds and step.

```rust
pub fn new(start: usize, end: usize, step: isize) -> Self
```

## *

Applies this argument to one dimension, appending its shape and stride and moving the offset.

```rust
fn apply(
    self,
    dim_size: usize,
    dim_stride: isize,
    out_shape: &mut [usize],
    out_strides: &mut [isize],
    new_ndim: &mut usize,
    offset: &mut isize,
) -> Result<(), Error>
```

## ScaledTensor

An owning block-scaled tensor: two composed [`Tensor`](#Tensor)s plus an optional per-tensor scale.

```rust
pub struct ScaledTensor<F: BlockScaledFormat, A: Allocator = Global>
```

A block-scaled tensor stores quantized values in blocks along its last axis. It is exactly:

- [`elements`](#elements): a `Tensor<F::Element>` of logical shape `(rows, columns)`, sub-byte packed
for FP4 formats, and

- [`block_scales`](#block_scales): a `Tensor<F::Scale>` of shape `(rows, columns / F::BLOCK_SIZE)` — one
scale byte per block, and

- [`tensor_scale`](#tensor_scale): an `Option<f32>` per-tensor multiplier (`Some` for NVFP4, `None` for MX).

This composes the existing tensor family rather than introducing a parallel hierarchy; the scale
newtypes ([`crate::Ue4m3`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#Ue4m3) / [`crate::Ue8m0`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#Ue8m0)) and the packed element scalars are plain
[`StorageElement`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement)s. Construct one with `dense.view().cast_to_scaled::<F>()` and decode it back
with `scaled.view().cast::<f32>()`.

Implements: `Debug`

## from_parts

Assemble a block-scaled tensor from its two component tensors and an optional scale.

```rust
pub fn from_parts(
    elements: Tensor<F::Element, A>,
    block_scales: Tensor<F::Scale, A>,
    tensor_scale: Option<f32>,
) -> Result<Self, Error>
```

The cast verbs in [`crate::cast`](#cast) are the usual way to build these; this constructor is
public so callers holding pre-quantized buffers can wrap them without a re-encode.

Both parts must agree, because nothing downstream re-checks them: decoding derives the scale
count from the _elements_ shape alone and hands the scales pointer to the kernel, so a
[`block_scales`](#block_scales) shorter than that shape is read past its end. Whether a per-tensor multiplier
exists at all is fixed by the format rather than the caller, so a mismatch there is rejected
too — its value, for the formats that have one, is genuine data.

## *

Borrow the packed element values.

```rust
pub fn elements(&self) -> TensorView<'_, F::Element, DEFAULT_MAX_RANK, A>
```

## block_*_scales

Borrow the per-block scale bytes.

```rust
pub fn block__scales(&self) -> TensorView<'_, F::Scale, DEFAULT_MAX_RANK, A>
```

## tensor_*_scale

The per-tensor multiplier (`Some` for NVFP4, `None` for the MX family).

```rust
pub fn tensor__scale(&self) -> Option<f32>
```

## shape

Logical `(rows, columns)` shape of the elements tensor.

```rust
pub fn shape(&self) -> &[usize]
```

## view

Borrow the whole tensor as a [`ScaledTensorView`](#ScaledTensorView).

```rust
pub fn view(&self) -> ScaledTensorView<'_, F, A>
```

## span

Borrow the whole tensor mutably as a [`ScaledTensorSpan`](#ScaledTensorSpan).

```rust
pub fn span(&mut self) -> ScaledTensorSpan<'_, F, A>
```

## capacity

Allocated element-storage capacity of the packed [`elements`](#elements) buffer ([`F::Element`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#Element) slots) — the ceiling a coordinated [`resize`](#resize) honors.

```rust
pub fn capacity(&self) -> usize
```

## resize

Resize the packed elements and the per-block scales in lockstep, moving neither buffer.

```rust
pub fn resize(&mut self, new_shape: &[usize]) -> Result<(), Error>
```

Atomic: fails leaving both children unchanged if either would exceed its capacity — call
[`reserve`](https://www.unum.cloud/docs/numkong/rust/maxsim.md#reserve) first to grow.

## reserve

Grow both children's capacity to hold `new_shape` and its paired scales, reallocating if needed.

```rust
pub fn reserve(&mut self, new_shape: &[usize]) -> Result<(), Error>
```

May move storage. A no-op when already large enough.

## clear

Reset both children to empty while keeping their capacities.

```rust
pub fn clear(&mut self)
```

## ScaledTensorSpan

A borrowed, mutable view into a [`ScaledTensor`](#ScaledTensor) — composed [`TensorSpan`](#TensorSpan)s plus the scale.

```rust
pub struct ScaledTensorSpan<'a, F: BlockScaledFormat, A = Global>
```

Implements: `Debug`

## elements

Mutably borrow the packed element values.

```rust
pub fn elements(&mut self) -> &mut TensorSpan<'a, F::Element, DEFAULT_MAX_RANK, A>
```

## block_scales

Mutably borrow the per-block scale bytes.

```rust
pub fn block_scales(&mut self) -> &mut TensorSpan<'a, F::Scale, DEFAULT_MAX_RANK, A>
```

## shape

Logical shape of the packed elements.

```rust
pub fn shape(&self) -> &[usize]
```

## as_view

Reborrow as a read-only [`ScaledTensorView`](#ScaledTensorView).

```rust
pub fn as_view(&self) -> ScaledTensorView<'_, F, A>
```

## ScaledTensorView

A borrowed, read-only view into a [`ScaledTensor`](#ScaledTensor) — composed [`TensorView`](#TensorView)s plus the scale.

```rust
pub struct ScaledTensorView<'a, F: BlockScaledFormat, A = Global>
```

Implements: `Debug`, `Clone`, `Copy`

## cast

Materialize this block-scaled view into a dense `Tensor<T>` of the same shape.

```rust
pub fn cast<T: Clone + CastDType>(&self) -> Result<Tensor<T, A>, Error>
```

## cast_to_scaled

Transcode this block-scaled view into a different block-scaled format.

```rust
pub fn cast_to_scaled<G: BlockScaledFormat>(&self) -> Result<ScaledTensor<G, A>, Error>
```

## shape

Logical `(rows, columns)` shape.

```rust
pub fn shape(&self) -> &[usize]
```

## row

Borrow leading-axis index `i` as a new [`ScaledTensorView`](#ScaledTensorView), slicing both sub-tensors in lockstep and keeping the rank, with the leading extent reduced to 1 rather than dropped.

```rust
pub fn row(&self, i: usize) -> Result<ScaledTensorView<'a, F, A>, Error>
```

## rows

Slice a contiguous leading-axis range `start..end`, slicing both sub-tensors in lockstep.

```rust
pub fn rows(&self, start: usize, end: usize) -> Result<ScaledTensorView<'a, F, A>, Error>
```

## SliceArg

Processes one axis of a slice operation, directly computing the effect on output shape, strides, and byte offset — no intermediate enum dispatch.

```rust
pub trait SliceArg
```

Each impl is monomorphized and fully inlined, so the compiler sees concrete types at every call
site with zero runtime branching overhead.

Unsigned types: `RangeFull`, `usize`, `Range<usize>`, `RangeTo<usize>`, `RangeFrom<usize>`,
`RangeInclusive<usize>`.

Signed types (negative wraps from end): `isize`, `Range<isize>`, `RangeTo<isize>`,
`RangeFrom<isize>`, `RangeInclusive<isize>`.

Stepped: [`RangeStep`](#RangeStep) — Rust has no built-in stepped range literal.

Note: integer literals default to `i32`, so write `0_usize` not `0`.

Implementors: - `impl [SliceArg](#SliceArg) for RangeFull`
- `impl [SliceArg](#SliceArg) for usize`
- `impl [SliceArg](#SliceArg) for isize`
- `impl [SliceArg](#SliceArg) for Range<usize>`
- `impl [SliceArg](#SliceArg) for Range<isize>`
- `impl [SliceArg](#SliceArg) for RangeTo<usize>`
- `impl [SliceArg](#SliceArg) for RangeTo<isize>`
- `impl [SliceArg](#SliceArg) for RangeFrom<usize>`
- `impl [SliceArg](#SliceArg) for RangeFrom<isize>`
- `impl [SliceArg](#SliceArg) for RangeInclusive<usize>`
- `impl [SliceArg](#SliceArg) for RangeInclusive<isize>`
- `impl [SliceArg](#SliceArg) for [RangeStep](#RangeStep)`

## SliceRange

Represents a range specification for slicing along one dimension.

```rust
pub enum SliceRange
```

- `Full`: Full range, equivalent to `..`
- `Index` = `(usize)`: Single index; reduces the dimension
- `Range` = `{ start: usize, end: usize }`: Range from start to end exclusive, equivalent to `start..end`
- `RangeStep` = `{ start: usize, end: usize, step: isize }`: Range from start to end with step, equivalent to `start..end;step`

Implements: `Debug`, `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`

## full

Create a full range.

```rust
pub fn full() -> Self
```

## index

Create a single index.

```rust
pub fn index(i: usize) -> Self
```

## range

Create a range from start to end.

```rust
pub fn range(start: usize, end: usize) -> Self
```

## range_step

Create a range with step.

```rust
pub fn range_step(start: usize, end: usize, step: isize) -> Self
```

## SliceSpec

Computes the full slice layout from shape, strides, and ndim.

```rust
pub trait SliceSpec
```

Implemented for `&[SliceRange]` / `&[SliceRange; N]` — backward compat, runtime dispatch — and
tuples of [`SliceArg`](#SliceArg) types from arity 1-8: compile-time dispatch, fully inlined with zero
branching overhead.

Implementors: - `impl [SliceSpec](#SliceSpec) for &[[SliceRange](#SliceRange)]`
- `impl<const N: usize> [SliceSpec](#SliceSpec) for &[[SliceRange](#SliceRange); N]`
- `impl<Axis0: [SliceArg](#SliceArg)> [SliceSpec](#SliceSpec) for (Axis0,)`
- `impl<Axis0: [SliceArg](#SliceArg), Axis1: [SliceArg](#SliceArg)> [SliceSpec](#SliceSpec) for (Axis0, Axis1)`
- `impl<Axis0: [SliceArg](#SliceArg), Axis1: [SliceArg](#SliceArg), Axis2: [SliceArg](#SliceArg)> [SliceSpec](#SliceSpec) for (Axis0, Axis1, Axis2)`
- `impl<Axis0: [SliceArg](#SliceArg), Axis1: [SliceArg](#SliceArg), Axis2: [SliceArg](#SliceArg), Axis3: [SliceArg](#SliceArg)> [SliceSpec](#SliceSpec) for (Axis0, Axis1, Axis2, Axis3)`
- `impl<Axis0: [SliceArg](#SliceArg), Axis1: [SliceArg](#SliceArg), Axis2: [SliceArg](#SliceArg), Axis3: [SliceArg](#SliceArg), Axis4: [SliceArg](#SliceArg)> [SliceSpec](#SliceSpec) for (Axis0, Axis1, Axis2, Axis3, Axis4)`
- `impl<Axis0: [SliceArg](#SliceArg), Axis1: [SliceArg](#SliceArg), Axis2: [SliceArg](#SliceArg), Axis3: [SliceArg](#SliceArg), Axis4: [SliceArg](#SliceArg), Axis5: [SliceArg](#SliceArg)> [SliceSpec](#SliceSpec) for (Axis0, Axis1, Axis2, Axis3, Axis4, Axis5)`
- `impl<Axis0: [SliceArg](#SliceArg), Axis1: [SliceArg](#SliceArg), Axis2: [SliceArg](#SliceArg), Axis3: [SliceArg](#SliceArg), Axis4: [SliceArg](#SliceArg), Axis5: [SliceArg](#SliceArg), Axis6: [SliceArg](#SliceArg)> [SliceSpec](#SliceSpec) for (Axis0, Axis1, Axis2, Axis3, Axis4, Axis5, Axis6)`
- `impl<Axis0: [SliceArg](#SliceArg), Axis1: [SliceArg](#SliceArg), Axis2: [SliceArg](#SliceArg), Axis3: [SliceArg](#SliceArg), Axis4: [SliceArg](#SliceArg), Axis5: [SliceArg](#SliceArg), Axis6: [SliceArg](#SliceArg), Axis7: [SliceArg](#SliceArg)> [SliceSpec](#SliceSpec) for (Axis0, Axis1, Axis2, Axis3, Axis4, Axis5, Axis6, Axis7)`

## apply_layout

`dims_per_value` is the scalar's packing factor: on the innermost axis a range start counts logical dimensions while the stride spans a whole storage value, so the two must be reconciled here rather than by the caller.

```rust
fn apply_layout<const MAX_RANK: usize>(
    self,
    shape: &[usize; MAX_RANK],
    strides: &[isize; MAX_RANK],
    ndim: usize,
    dims_per_value: usize,
) -> Result<([usize; MAX_RANK], [isize; MAX_RANK], usize, isize, usize), Error>
```

## Tensor

N-dimensional array with NumKong-accelerated operations.

```rust
pub struct Tensor<Scalar: StorageElement, Alloc: Allocator = Global, const MAX_RANK: usize = DEFAULT_MAX_RANK>
```

Uses raw memory allocation, not std::Vec, for maximum control.

Supports:

- Slicing and subviews, zero-copy

- Dot-product multiplication with [`crate::dots::DotsPackedMatrix`](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#DotsPackedMatrix)

- Reductions — sum, min, max

- Elementwise ops — scale, sum, blend, fma

- Trigonometry — sin, cos, atan

Examples: ```
// Requires linking against libnumkong C library
use numkong::{Tensor, DotsPackedMatrix};

let a = Tensor::&#x3C;f32>::full(&#x26;[1024, 512], 1.0).unwrap();
let b = Tensor::&#x3C;f32>::full(&#x26;[256, 512], 1.0).unwrap();

// Pack B once, multiply many times
let b_packed = DotsPackedMatrix::new(&#x26;b).unwrap();
let c = a.dots_packed(&#x26;b_packed).unwrap(); // Returns (1024 × 256)
```

Implements: `[CastOps](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#CastOps)<Source, R>`, `[DenseToScaledOps](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#DenseToScaledOps)<R>`, `[AllCloseOps](https://www.unum.cloud/docs/numkong/rust/platform-notes.md#AllCloseOps)<Scalar, R>`, `[ScaleOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#ScaleOps)<Scalar, R>`, `[SumOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#SumOps)<Scalar, R>`, `[BlendOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#BlendOps)<Scalar, R>`, `[FmaOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#FmaOps)<Scalar, R>`, `[BitwiseReductionsOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#BitwiseReductionsOps)<MAX_RANK>`, `[MomentsOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#MomentsOps)<Scalar, R>`, `[MinMaxOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#MinMaxOps)<Scalar, R>`, `[TrigSinOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#TrigSinOps)<Scalar, R>`, `[TrigCosOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#TrigCosOps)<Scalar, R>`, `[TrigAtanOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#TrigAtanOps)<Scalar, R>`, `[DotsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#DotsPackedOps)<Scalar, MAX_RANK>`, `[SymmetricDotsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricDotsOps)<Scalar, R>`, `[HammingsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#HammingsPackedOps)<Scalar, MAX_RANK>`, `[JaccardsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#JaccardsPackedOps)<Scalar, MAX_RANK>`, `[SymmetricHammingsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricHammingsOps)<Scalar, R>`, `[SymmetricJaccardsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricJaccardsOps)<Scalar, R>`, `[AngularsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#AngularsPackedOps)<Scalar, MAX_RANK>`, `[EuclideansPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#EuclideansPackedOps)<Scalar, MAX_RANK>`, `[SymmetricAngularsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricAngularsOps)<Scalar, R>`, `[SymmetricEuclideansOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricEuclideansOps)<Scalar, R>`, `Send`, `Sync`, `Drop`, `[TensorRef](#TensorRef)<Scalar, R>`, `[TensorMut](#TensorMut)<Scalar, R>`, `[Fill](#Fill)<Scalar>`, `[CopyFrom](#CopyFrom)<&[Scalar]>`, `Debug`, `IntoIterator`, `PartialEq`, `AsRef<[Scalar]>`

## add_scalar_inplace

Element-wise add scalar in-place.

```rust
pub fn add_scalar_inplace(&mut self, scalar: Scalar::Scalar) -> Result<(), Error>
```

## sub_scalar_inplace

Element-wise subtract scalar in-place.

```rust
pub fn sub_scalar_inplace(&mut self, scalar: Scalar::Scalar) -> Result<(), Error>
```

## mul_scalar_inplace

Element-wise multiply scalar in-place.

```rust
pub fn mul_scalar_inplace(&mut self, scalar: Scalar::Scalar) -> Result<(), Error>
```

## add_tensor_inplace

Element-wise sum with another tensor, stored in `self`.

```rust
pub fn add_tensor_inplace<OtherAlloc: Allocator>(
    &mut self,
    other: &Tensor<Scalar, OtherAlloc, MAX_RANK>,
) -> Result<(), Error>
```

## sub_tensor_inplace

Element-wise difference with another tensor, stored in `self`.

```rust
pub fn sub_tensor_inplace<OtherAlloc: Allocator>(
    &mut self,
    other: &Tensor<Scalar, OtherAlloc, MAX_RANK>,
) -> Result<(), Error>
```

## mul_tensor_inplace

Element-wise product with another tensor, stored in `self`.

```rust
pub fn mul_tensor_inplace<OtherAlloc: Allocator>(
    &mut self,
    other: &Tensor<Scalar, OtherAlloc, MAX_RANK>,
) -> Result<(), Error>
```

## sin_inplace

Element-wise sine in-place.

```rust
pub fn sin_inplace(&mut self) -> Result<(), Error>
```

## cos_inplace

Element-wise cosine in-place.

```rust
pub fn cos_inplace(&mut self) -> Result<(), Error>
```

## atan_inplace

Element-wise arctangent in-place.

```rust
pub fn atan_inplace(&mut self) -> Result<(), Error>
```

## dots_packed

Dot-product multiply: C = self × packed_rightᵀ

```rust
pub fn dots_packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::Accumulator, Alloc, MAX_RANK>, Error>
```

```rust
fn dots_packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::Accumulator, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

self must be 2D __[m,k]__ with contiguous rows. packed_right contains B __[n,k]__
packed. Returns C __[m,n]__ using the same allocator as self.

Returns `Err` if:

- self is not 2D

- self has non-contiguous rows

- inner dimensions don't match

- output allocation fails

- the kernel refuses `packed_right`, like one packed under other capabilities

## hammings_packed

Computes Hamming distances between rows of self and packed B matrix.

```rust
pub fn hammings_packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<u32, Alloc, MAX_RANK>, Error>
```

```rust
fn hammings_packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<u32, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

Hamming distances: C = self × packed_rightᵀ

## jaccards_packed

Computes Jaccard distances between rows of self and packed B matrix.

```rust
pub fn jaccards_packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::JaccardResult, Alloc, MAX_RANK>, Error>
```

```rust
fn jaccards_packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::JaccardResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

Jaccard distances: C = self × packed_rightᵀ

## angulars_packed

Computes angular distances between rows of self and packed B matrix.

```rust
pub fn angulars_packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::SpatialResult, Alloc, MAX_RANK>, Error>
```

```rust
fn angulars_packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::SpatialResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

Angular distances: C = angular(self, packed_rightᵀ)

## euclideans_packed

Computes euclidean distances between rows of self and packed B matrix.

```rust
pub fn euclideans_packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::SpatialResult, Alloc, MAX_RANK>, Error>
```

```rust
fn euclideans_packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::SpatialResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

Euclidean distances: C = euclidean(self, packed_rightᵀ)

## clone

Clone this tensor, returning an error on allocation failure.

```rust
pub fn clone(&self) -> Result<Self, Error>
```

## full_in

Creates a new Tensor filled with a value using a custom allocator.

```rust
pub fn full_in(shape: &[usize], value: Scalar, alloc: Alloc) -> Result<Self, Error>
```

The [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape) specifies logical dimensions. For sub-byte types the innermost extent counts
elements, a multiple of the values packed per byte, and storage holds `total` divided by
`dimensions_per_value()` packed values.

Returns `Err` if allocation fails or shape is invalid.

## zeros_in

Creates a zero-initialized Tensor using a custom allocator.

```rust
pub fn zeros_in(shape: &[usize], alloc: Alloc) -> Result<Self, Error>
where
    Scalar: Default,
```

Returns `Err` if allocation fails or shape is invalid.

## ones_in

Creates a Tensor filled with ones using a custom allocator.

```rust
pub fn ones_in(shape: &[usize], alloc: Alloc) -> Result<Self, Error>
where
    Scalar: NumberLike,
```

Returns `Err` if allocation fails or shape is invalid.

## uninitialized_in

Creates an uninitialized Tensor using a custom allocator.

```rust
pub unsafe fn uninitialized_in(shape: &[usize], alloc: Alloc) -> Result<Self, Error>
```

Safety: The returned tensor's contents are uninitialized; reading before writing is undefined
behavior.

## from_slice_in

Creates a Tensor from existing storage data using a custom allocator.

```rust
pub fn from_slice_in(data: &[Scalar], shape: &[usize], alloc: Alloc) -> Result<Self, Error>
```

The [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape) specifies logical dimensions. For sub-byte types, the `data` slice holds
`shape.product()` divided by `dimensions_per_value()` storage values; for normal types,
`data.len()` equals `shape.product()`.

## from_scalars_in

Creates a Tensor from per-dimension `f32` values using a custom allocator.

```rust
pub fn from_scalars_in(scalars: &[f32], shape: &[usize], alloc: Alloc) -> Result<Self, Error>
where
    Scalar: FloatConvertible,
    Alloc: Clone,
```

Each `f32` is converted through [`FloatConvertible::DimScalar::from_f32`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#from_f32) before storage, so
this works for full-byte types ([`f16`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#f16), [`bf16`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#bf16), `i8`, …) and sub-byte types ([`i4x2`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#i4x2), [`u4x2`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#u4x2),
[`u1x8`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#u1x8)) alike. The length of `scalars` must equal the product of [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape).

## from_dims_in

Creates a Tensor from per-dimension [`DimScalar`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#DimScalar) values using a custom allocator.

```rust
pub fn from_dims_in(
    dim_values: &[<Scalar as FloatConvertible>::DimScalar],
    shape: &[usize],
    alloc: Alloc,
) -> Result<Self, Error>
where
    Scalar: FloatConvertible,
    Alloc: Clone,
```

Each element of `dim_values` represents one logical dimension; for sub-byte types the values
are packed into their storage representation. The length of `dim_values` must equal the
product of [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape).

## allocator

Returns a reference to the allocator.

```rust
pub fn allocator(&self) -> &Alloc
```

## storage_*_len

Number of storage values — for sub-byte types, less than numel.

```rust
pub fn storage__len(&self) -> usize
```

## into_vector

Convert a 1D contiguous tensor into a [`Vector`](#Vector), transferring ownership without copying.

```rust
pub fn into_vector(self) -> Result<Vector<Scalar, Alloc>, Error>
```

Returns an error if the tensor is not 1D or not contiguous.

## from_raw_parts_in

Construct a tensor from raw parts, taking ownership of the allocation.

```rust
pub unsafe fn from_raw_parts_in(
    data: NonNull<Scalar>,
    shape: [usize; MAX_RANK],
    strides: [isize; MAX_RANK],
    ndim: usize,
    alloc: Alloc,
) -> Self
```

Safety: - `data` must point to an allocation obtained from `alloc`, aligned to
[`DEFAULT_ALIGNMENT`](https://www.unum.cloud/docs/numkong/rust/external-memory.md#DEFAULT_ALIGNMENT), whose backing buffer is sized for the storage count
implied by [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape) (`product(shape) / Scalar::dimensions_per_value()`
slots of [`Scalar`](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#Scalar)).

- [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape), `strides`, and [`ndim`](#ndim) must be consistent with the data layout.

- The caller must not free the memory — this tensor takes ownership.

## shape

Returns the shape of the array.

```rust
pub fn shape(&self) -> &[usize]
```

## *

Returns the number of dimensions.

```rust
pub fn ndim(&self) -> usize
```

## *

Allocated storage-value capacity ([`Scalar`](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#Scalar) slots) — the ceiling [`resize`](#resize) honors.

```rust
pub fn capacity(&self) -> usize
```

Always `>= numel() / Scalar::dimensions_per_value()`.

Always `>= size_values()`.

## resize

Resize in place to `new_shape` without moving storage.

```rust
pub fn resize(&mut self, new_shape: &[usize]) -> Result<(), Error>
```

Succeeds only when the packed storage fits `capacity()`, so `as_ptr()` stays stable — call
[`reserve`](https://www.unum.cloud/docs/numkong/rust/maxsim.md#reserve) first to grow. Returns [`Error::CapacityExceeded`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#CapacityExceeded) when it
would overflow or hits a shape error, leaving the tensor unchanged.

Examples: ```
let mut t = Tensor::&#x3C;f32>::zeros(&#x26;[8, 8])?; // capacity 64
t.resize(&#x26;[4, 4])?;                         // shrink within capacity; as_ptr() unchanged
assert!(t.resize(&#x26;[9, 8]).is_err());        // beyond capacity
```

## reserve

Grow the allocated `capacity()` to hold at least `new_shape`, reallocating and copying the live elements if needed.

```rust
pub fn reserve(&mut self, new_shape: &[usize]) -> Result<(), Error>
```

A no-op when already large enough. Unlike [`resize`](#resize)
it may move storage. Returns [`Error::AllocationFailed`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#AllocationFailed) on failure, leaving it unchanged.

## clear

Reset to an empty rank-1 shape (`numel() == 0`) while keeping the allocated `capacity()`.

```rust
pub fn clear(&mut self)
```

## stride_*_bytes

Returns the stride in bytes for the given dimension.

```rust
pub fn stride__bytes(&self, dim: usize) -> isize
```

## as_ptr

Returns a pointer to the data.

```rust
pub fn as_ptr(&self) -> *const Scalar
```

## as_mut_ptr

Returns a mutable pointer to the data.

```rust
pub fn as_mut_ptr(&mut self) -> *mut Scalar
```

## as_slice

Returns the underlying storage data as a slice.

```rust
pub fn as_slice(&self) -> &[Scalar]
```

For sub-byte types, the slice holds packed storage values, not individual logical elements.

## as_mut_slice

Returns the underlying storage data as a mutable slice.

```rust
pub fn as_mut_slice(&mut self) -> &mut [Scalar]
```

For sub-byte types, the slice holds packed storage values, not individual logical elements.

## row

Returns a row of a 2D array.

```rust
pub fn row(&self, i: usize) -> Option<&[Scalar]>
```

## row_mut

Returns a mutable row of a 2D array.

```rust
pub fn row_mut(&mut self, i: usize) -> Option<&mut [Scalar]>
```

## full

Creates a new Tensor filled with a value using the global allocator.

```rust
pub fn full(shape: &[usize], value: Scalar) -> Result<Self, Error>
```

Returns `Err` if allocation fails or shape is invalid.

Examples: ```
use numkong::tensor::{Tensor, TensorRef};

let zeros = Tensor::&#x3C;f32>::full(&#x26;[2, 3], 0.0).unwrap();
assert_eq!(zeros.shape(), &#x26;[2, 3]);
assert_eq!(zeros.numel(), 6);
assert!(zeros.as_slice().iter().all(|&#x26;v| v == 0.0));
```

## zeros

Creates a zero-initialized Tensor using the global allocator.

```rust
pub fn zeros(shape: &[usize]) -> Result<Self, Error>
where
    Scalar: Default,
```

## ones

Creates a Tensor filled with ones using the global allocator.

```rust
pub fn ones(shape: &[usize]) -> Result<Self, Error>
where
    Scalar: NumberLike,
```

## uninitialized

Creates an uninitialized Tensor using the global allocator.

```rust
pub unsafe fn uninitialized(shape: &[usize]) -> Result<Self, Error>
```

Safety: The returned tensor's contents are uninitialized; reading before writing is undefined
behavior.

## from_slice

Creates a Tensor from existing slice data using the global allocator.

```rust
pub fn from_slice(data: &[Scalar], shape: &[usize]) -> Result<Self, Error>
```

Returns `Err` if shape doesn't match data length or allocation fails.

## from_scalars

Creates a Tensor from per-dimension `f32` values using the global allocator.

```rust
pub fn from_scalars(scalars: &[f32], shape: &[usize]) -> Result<Self, Error>
where
    Scalar: FloatConvertible,
```

Each `f32` is converted through [`FloatConvertible::DimScalar::from_f32`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#from_f32) before storage. The
length of `scalars` must equal the product of [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape).

## from_dims

Creates a Tensor from per-dimension [`DimScalar`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#DimScalar) values using the global allocator.

```rust
pub fn from_dims(
    dim_values: &[<Scalar as FloatConvertible>::DimScalar],
    shape: &[usize],
) -> Result<Self, Error>
where
    Scalar: FloatConvertible,
```

Each element of `dim_values` represents one logical dimension. The length of `dim_values`
must equal the product of [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape).

## axis_*_views

Iterate along the given axis, yielding sub-tensor views with rank-1.

```rust
pub fn axis__views<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
) -> Result<AxisIterator<'_, Scalar, MAX_RANK, Alloc>, Error>
```

## axis_*_spans

Iterate mutably along the given axis, yielding sub-tensor spans with rank-1.

```rust
pub fn axis__spans<AnyIndex: VectorIndex>(
    &mut self,
    axis: AnyIndex,
) -> Result<AxisIteratorMut<'_, Scalar, MAX_RANK, Alloc>, Error>
```

## *

Returns a lazy iterator over all logical scalars in row-major order.

```rust
pub fn iter(&self) -> TensorViewIterator<'_, Scalar, MAX_RANK>
```

Yields `(position, DimRef)` pairs. Use `.iter().dims()` for just dimensions.

Yields `(position, DimRef)` pairs. Use `.iter().dims()` for just dimensions. For sub-byte
types, the innermost dimension is expanded.

## iter_*_mut

Returns a mutable iterator over all logical scalars in row-major order.

```rust
pub fn iter__mut(&mut self) -> TensorSpanIterator<'_, Scalar, MAX_RANK>
```

Yields `(position, DimMut)` pairs. Use `.iter_mut().dims()` for just dimensions.

## view

Create a view of the entire array.

```rust
pub fn view(&self) -> TensorView<'_, Scalar, MAX_RANK, Alloc>
```

```rust
fn view(&self) -> TensorView<'_, Scalar, R, Alloc>
```

Borrow as an immutable [`TensorView`](#TensorView) with the same shape and strides.

## span

Create a mutable span of the entire tensor.

```rust
pub fn span(&mut self) -> TensorSpan<'_, Scalar, MAX_RANK, Alloc>
```

The returned [`TensorSpan`](#TensorSpan) borrows `self` exclusively for `'_`. Use it to apply in-place
kernels, write to individual elements via [`TensorSpan::flat_mut`](#flat_mut) /
[`TensorSpan::coords_mut`](#coords_mut), or pass it to APIs that need `&mut (impl TensorMut<_, _>)`.

Examples: ```
use numkong::tensor::Tensor;

let mut t = Tensor::&#x3C;f32>::full(&#x26;[2, 2], 0.0).unwrap();
let mut span = t.span();
*span.flat_mut(0_usize).unwrap() = 42.0;
assert_eq!(*span.flat(0_usize).unwrap(), 42.0);
```

## *

Get an element by flat logical row-major index.

```rust
pub fn flat<AnyIndex: VectorIndex>(&self, index: AnyIndex) -> Result<&Scalar, Error>
```

Negative `isize` indices wrap from the end (`-1` is the last element).
Returns [`Error::DimensionMismatch`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#DimensionMismatch) on a rank-0 view and
[`Error::IndexOutOfBounds`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#IndexOutOfBounds) when the index is outside the logical element count.

Examples: ```
use numkong::tensor::Tensor;

let t = Tensor::&#x3C;f32>::from_slice(&#x26;[1.0, 2.0, 3.0, 4.0], &#x26;[2, 2]).unwrap();
let view = t.view();
assert_eq!(*view.flat(0_usize).unwrap(), 1.0);
assert_eq!(*view.flat(-1_i32).unwrap(), 4.0);
```

## flat_*_mut

Get a mutable element by flat logical row-major index.

```rust
pub fn flat__mut<AnyIndex: VectorIndex>(&mut self, index: AnyIndex) -> Result<&mut Scalar, Error>
```

Negative `isize` indices wrap from the end. Returns [`Error::DimensionMismatch`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#DimensionMismatch) on a
rank-0 span and [`Error::IndexOutOfBounds`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#IndexOutOfBounds) when the index is out of range.

Examples: ```
use numkong::tensor::Tensor;

let mut t = Tensor::&#x3C;f32>::full(&#x26;[3], 0.0).unwrap();
let mut span = t.span();
*span.flat_mut(-1_i32).unwrap() = 9.0;
assert_eq!(*span.flat(2_usize).unwrap(), 9.0);
```

## *

Get an element by exact coordinates.

```rust
pub fn coords<C: TensorCoordinates>(&self, coords: C) -> Result<&Scalar, Error>
```

## coords_*_mut

Get a mutable element by exact coordinates.

```rust
pub fn coords__mut<C: TensorCoordinates>(&mut self, coords: C) -> Result<&mut Scalar, Error>
```

## scalar

Access the scalar value of a rank-0 tensor.

```rust
pub fn scalar(&self) -> Result<&Scalar, Error>
```

## scalar_mut

Access the mutable scalar value of a rank-0 tensor.

```rust
pub fn scalar_mut(&mut self) -> Result<&mut Scalar, Error>
```

## slice_*_leading

Slice the leading axis by one index, reducing rank by one.

```rust
pub fn slice__leading<AnyIndex: VectorIndex>(
    &self,
    index: AnyIndex,
) -> Result<TensorView<'_, Scalar, MAX_RANK, Alloc>, Error>
```

## slice_leading_*_leading_mut

Slice the leading axis mutably by one index, reducing rank by one.

```rust
pub fn slice_leading__leading_mut<AnyIndex: VectorIndex>(
    &mut self,
    index: AnyIndex,
) -> Result<TensorSpan<'_, Scalar, MAX_RANK, Alloc>, Error>
```

## slice

Slice the array along multiple dimensions, returning a zero-copy view.

```rust
pub fn slice(&self, spec: impl SliceSpec) -> Result<TensorView<'_, Scalar, MAX_RANK, Alloc>, Error>
```

Accepts tuples of Rust range types or `&[SliceRange]`. Scalar arguments reduce the rank,
range arguments preserve it, and [`RangeStep`](#RangeStep) permits stepped sampling.

Examples: ```
use numkong::tensor::{Tensor, SliceRange};

let arr = Tensor::&#x3C;f32>::full(&#x26;[4, 5], 1.0).unwrap();

// Tuple syntax — preferred
let block = arr.slice((0..2_usize, ..)).unwrap();     // t[0:2, :]
let row   = arr.slice((1_usize, ..)).unwrap();        // t[1, :]
assert_eq!(block.shape(), &#x26;[2, 5]);
assert_eq!(row.shape(),   &#x26;[5]);

// Enum-based syntax still works for programmatic construction
let same_block = arr.slice(&#x26;[SliceRange::range(0, 2), SliceRange::full()]).unwrap();
assert_eq!(block.shape(), same_block.shape());
```

## slice_mut

Slice the array mutably along multiple dimensions.

```rust
pub fn slice_mut(
    &mut self,
    spec: impl SliceSpec,
) -> Result<TensorSpan<'_, Scalar, MAX_RANK, Alloc>, Error>
```

Accepts tuples of Rust range types or `&[SliceRange]`.

## *

Transpose — reverse all dimensions, no data copy.

```rust
pub fn transpose(&self) -> Result<TensorView<'_, Scalar, MAX_RANK, Alloc>, Error>
```

Returns an error for sub-byte types with ndim >= 2.

Returns an error for sub-byte types with ndim >= 2, since transposing would produce
non-contiguous strides that break packed element addressing.

## reshape

Reshape the array — must have same total elements, contiguous only.

```rust
pub fn reshape(&self, new_shape: &[usize]) -> Result<TensorView<'_, Scalar, MAX_RANK, Alloc>, Error>
```

## *

Flatten to 1D; requires contiguous layout.

```rust
pub fn flatten(&self) -> Result<TensorView<'_, Scalar, MAX_RANK, Alloc>, Error>
```

## *

Remove dimensions of size 1.

```rust
pub fn squeeze(&self) -> TensorView<'_, Scalar, MAX_RANK, Alloc>
```

## scale

Apply element-wise scale: result[i] = α × self[i] + β

```rust
pub fn scale(
    &self,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

Returns a new array with the scaled values.

## scale_inplace

Apply element-wise scale in-place: self[i] = α × self[i] + β

```rust
pub fn scale_inplace(&mut self, alpha: Scalar::Scalar, beta: Scalar::Scalar) -> Result<(), Error>
```

## add

Element-wise sum: result[i] = self[i] + other[i]

```rust
pub fn add<OtherAlloc: Allocator, const OTHER_MAX_RANK: usize>(
    &self,
    other: &Tensor<Scalar, OtherAlloc, OTHER_MAX_RANK>,
) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

Returns a new array with the summed values.

## add_inplace

Element-wise sum in-place: self[i] = self[i] + other[i]

```rust
pub fn add_inplace<OtherAlloc: Allocator, const OTHER_MAX_RANK: usize>(
    &mut self,
    other: &Tensor<Scalar, OtherAlloc, OTHER_MAX_RANK>,
) -> Result<(), Error>
```

## blend

Blend: result[i] = α × self[i] + β × other[i]

```rust
pub fn blend<OtherAlloc: Allocator, const OTHER_MAX_RANK: usize>(
    &self,
    other: &Tensor<Scalar, OtherAlloc, OTHER_MAX_RANK>,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

Returns a new array with the blend.

## fma

Fused multiply-add: result[i] = α × self[i] × b[i] + β × c[i]

```rust
pub fn fma<BAlloc: Allocator, CAlloc: Allocator, const B_MAX_RANK: usize, const C_MAX_RANK: usize>(
    &self,
    multiplier: &Tensor<Scalar, BAlloc, B_MAX_RANK>,
    addend: &Tensor<Scalar, CAlloc, C_MAX_RANK>,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

Returns a new array with the FMA result.

## dot_product

Compute the dot product of this array with another.

```rust
pub fn dot_product<OtherAlloc: Allocator, const OTHER_MAX_RANK: usize>(
    &self,
    other: &Tensor<Scalar, OtherAlloc, OTHER_MAX_RANK>,
) -> Result<Scalar::Output, Error>
```

Both arrays must be 1D with the same length.

## *

Casts every element to `Destination`, returning a new tensor of the same shape.

```rust
fn cast<Destination: Clone + CastDType>(
    &self,
) -> Result<Tensor<Destination, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## cast_*_into

Cast into a pre-allocated sink.

```rust
fn cast__into<Destination, OutputTensor>(&self, out: &mut OutputTensor) -> Result<(), Error>
where
    Destination: Clone + CastDType,
    OutputTensor: TensorMut<Destination, MAX_RANK> + ?Sized,
```

The destination may be a `&mut Tensor<...>` or a `&mut TensorSpan<...>`, any [`TensorMut`](#TensorMut); a strided sub-span works too.

## cast_to_*_to_scaled

Encodes the tensor into the block-scaled format `F`.

```rust
fn cast_to__to_scaled<F: BlockScaledFormat>(&self) -> Result<ScaledTensor<F, Self::Alloc>, Error>
where
    Self::Alloc: Clone,
```

## *

Returns `true` iff both tensors share a shape and every element pair is within tolerance.

```rust
fn allclose(&self, other: &impl TensorRef<Scalar, MAX_RANK> + ?Sized, atol: f64, rtol: f64) -> bool
```

## add_*_scalar

Element-wise add scalar into a new tensor.

```rust
fn add__scalar(&self, scalar: Scalar::Scalar) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## sub_*_scalar

Element-wise subtract scalar into a new tensor.

```rust
fn sub__scalar(&self, scalar: Scalar::Scalar) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## mul_*_scalar

Element-wise multiply scalar into a new tensor.

```rust
fn mul__scalar(&self, scalar: Scalar::Scalar) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## scale_tensor_*_tensor_into

Writes α × aᵢ + β into the output tensor.

```rust
fn scale_tensor__tensor_into<OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

## add_scalar_*_scalar_into

Element-wise add scalar into the output tensor.

```rust
fn add_scalar__scalar_into<OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    scalar: Scalar::Scalar,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

## sub_scalar_*_scalar_into

Element-wise subtract scalar into the output tensor.

```rust
fn sub_scalar__scalar_into<OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    scalar: Scalar::Scalar,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

## mul_scalar_*_scalar_into

Element-wise multiply scalar into the output tensor.

```rust
fn mul_scalar__scalar_into<OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    scalar: Scalar::Scalar,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

## add_*_tensor

Element-wise sum of two tensors into a new tensor.

```rust
fn add__tensor(
    &self,
    other: &impl TensorRef<Scalar, MAX_RANK> + ?Sized,
) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## add_tensor_*_tensor_into

Element-wise sum of two tensors into the output tensor.

```rust
fn add_tensor__tensor_into<OtherTensor, OutputTensor>(
    &self,
    other: &OtherTensor,
    out: &mut OutputTensor,
) -> Result<(), Error>
where
    OtherTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized,
```

## sub_*_tensor

Element-wise difference of two tensors into a new tensor.

```rust
fn sub__tensor(
    &self,
    other: &impl TensorRef<Scalar, MAX_RANK> + ?Sized,
) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## blend_tensor_*_tensor_into

Writes α × aᵢ + β × otherᵢ into the output tensor.

```rust
fn blend_tensor__tensor_into<OtherTensor, OutputTensor>(
    &self,
    other: &OtherTensor,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
    out: &mut OutputTensor,
) -> Result<(), Error>
where
    OtherTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized,
```

## sub_tensor_*_tensor_into

Element-wise difference of two tensors into the output tensor.

```rust
fn sub_tensor__tensor_into<OtherTensor, OutputTensor>(
    &self,
    other: &OtherTensor,
    out: &mut OutputTensor,
) -> Result<(), Error>
where
    OtherTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized,
```

## mul_*_tensor

Element-wise product of two tensors into a new tensor.

```rust
fn mul__tensor(
    &self,
    other: &impl TensorRef<Scalar, MAX_RANK> + ?Sized,
) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## fma_tensors_*_tensors_into

Writes α × aᵢ × bᵢ + β × cᵢ into the output tensor.

```rust
fn fma_tensors__tensors_into<BTensor, CTensor, OutputTensor>(
    &self,
    b: &BTensor,
    c: &CTensor,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
    out: &mut OutputTensor,
) -> Result<(), Error>
where
    BTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    CTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized,
```

## mul_tensor_*_tensor_into

Element-wise product of two tensors into the output tensor.

```rust
fn mul_tensor__tensor_into<OtherTensor, OutputTensor>(
    &self,
    other: &OtherTensor,
    out: &mut OutputTensor,
) -> Result<(), Error>
where
    OtherTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized,
```

## *

Number of set bits across the entire tensor.

```rust
fn popcount(&self) -> Result<u64, Error>
```

## any_*_set

`true` if at least one bit in the tensor is set.

```rust
fn any__set(&self) -> Result<bool, Error>
```

## none_*_set

`true` if no bit in the tensor is set.

```rust
fn none__set(&self) -> Result<bool, Error>
```

## all_*_set

`true` if every bit in the tensor is set.

```rust
fn all__set(&self) -> Result<bool, Error>
```

## moments_*_all

Sum and sum of squares over all elements.

```rust
fn moments__all(&self) -> Result<(Scalar::SumOutput, Scalar::SumSqOutput), Error>
```

## moments_*_axis

Sum and sum of squares along one axis, into new tensors.

```rust
fn moments__axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<(Tensor<<Scalar as ReduceMoments>::SumOutput, Self::Alloc, MAX_RANK>, Tensor<<Scalar as ReduceMoments>::SumSqOutput, Self::Alloc, MAX_RANK>), Error>
where
    Self::Alloc: Clone,
```

## moments_axis_*_axis_into

Sum and sum of squares along one axis, into the output tensors.

```rust
fn moments_axis__axis_into<AnyIndex, SumTensor, SumSqTensor>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
    sum_out: &mut SumTensor,
    sumsq_out: &mut SumSqTensor,
) -> Result<(), Error>
where
    AnyIndex: VectorIndex,
    SumTensor: TensorMut<Scalar::SumOutput, MAX_RANK> + ?Sized,
    SumSqTensor: TensorMut<Scalar::SumSqOutput, MAX_RANK> + ?Sized,
```

## sum_*_all

Sum over all elements.

```rust
fn sum__all(&self) -> Result<Scalar::SumOutput, Error>
```

## sum_*_axis

Sum along one axis, into a new tensor.

```rust
fn sum__axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<Scalar::SumOutput, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## sum_axis_*_axis_into

Sum along one axis, into the output tensor.

```rust
fn sum_axis__axis_into<AnyIndex, SumTensor>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
    out: &mut SumTensor,
) -> Result<(), Error>
where
    AnyIndex: VectorIndex,
    SumTensor: TensorMut<Scalar::SumOutput, MAX_RANK> + ?Sized,
```

## norm_*_all

Euclidean norm over all elements.

```rust
fn norm__all(&self) -> Result<f64, Error>
```

## norm_*_axis

Euclidean norm along one axis, into a new tensor.

```rust
fn norm__axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<f64, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## norm_axis_*_axis_into

Euclidean norm along one axis, into the output tensor.

```rust
fn norm_axis__axis_into<AnyIndex, NormTensor>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
    out: &mut NormTensor,
) -> Result<(), Error>
where
    AnyIndex: VectorIndex,
    NormTensor: TensorMut<f64, MAX_RANK> + ?Sized,
```

## minmax_*_all

Minimum and maximum with their indices over all elements.

```rust
fn minmax__all(&self) -> Result<MinMaxResult<Scalar::Output>, Error>
```

## minmax_*_axis

Minimum and maximum with their indices along one axis, into new tensors.

```rust
fn minmax__axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<MinMaxResult<Tensor<<Scalar as ReduceMinMax>::Output, Self::Alloc, MAX_RANK>, Tensor<usize, Self::Alloc, MAX_RANK>>, Error>
where
    Self::Alloc: Clone,
```

## minmax_axis_*_axis_into

Minimum and maximum with their indices along one axis, into the output tensors.

```rust
fn minmax_axis__axis_into<AnyIndex, ValueTensor, IndexTensor>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
    min_out: &mut ValueTensor,
    argmin_out: &mut IndexTensor,
    max_out: &mut ValueTensor,
    argmax_out: &mut IndexTensor,
) -> Result<(), Error>
where
    AnyIndex: VectorIndex,
    ValueTensor: TensorMut<Scalar::Output, MAX_RANK> + ?Sized,
    IndexTensor: TensorMut<usize, MAX_RANK> + ?Sized,
```

## min_*_all

Minimum over all elements.

```rust
fn min__all(&self) -> Result<Scalar::Output, Error>
```

## argmin_*_all

Index of the minimum over all elements.

```rust
fn argmin__all(&self) -> Result<usize, Error>
```

## max_*_all

Maximum over all elements.

```rust
fn max__all(&self) -> Result<Scalar::Output, Error>
```

## argmax_*_all

Index of the maximum over all elements.

```rust
fn argmax__all(&self) -> Result<usize, Error>
```

## min_*_axis

Minimum along one axis, into a new tensor.

```rust
fn min__axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<Scalar::Output, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## argmin_*_axis

Index of the minimum along one axis, into a new tensor.

```rust
fn argmin__axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<usize, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## max_*_axis

Maximum along one axis, into a new tensor.

```rust
fn max__axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<Scalar::Output, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## argmax_*_axis

Index of the maximum along one axis, into a new tensor.

```rust
fn argmax__axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<usize, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## *

Element-wise sine into a new tensor.

```rust
fn sin(&self) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## sin_*_into

Element-wise sine into the output tensor.

```rust
fn sin__into<OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

## *

Element-wise cosine into a new tensor.

```rust
fn cos(&self) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## cos_*_into

Element-wise cosine into the output tensor.

```rust
fn cos__into<OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

## *

Element-wise arctangent into a new tensor.

```rust
fn atan(&self) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## atan_*_into

Element-wise arctangent into the output tensor.

```rust
fn atan__into<OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

## dots_packed_*_packed_into

Dot-product multiply into an existing output, avoiding allocation.

```rust
fn dots_packed__packed_into<PackedAlloc, OutputTensor, const OUTPUT_MAX_RANK: usize>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
    output: &mut OutputTensor,
) -> Result<(), Error>
where
    PackedAlloc: Allocator,
    OutputTensor: TensorMut<Scalar::Accumulator, OUTPUT_MAX_RANK>,
```

The output may be a `&mut Tensor<...>` or `&mut TensorSpan<...>`; any writable tensor
container that implements [`TensorMut`](#TensorMut) works. The kernel overwrites `c` entirely, so it
need not arrive pre-initialized.

## dots_*_symmetric

Computes the upper triangle of the symmetric dot-product matrix of the rows with themselves.

```rust
fn dots__symmetric(&self) -> Result<Tensor<Scalar::Accumulator, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## dots_symmetric_*_symmetric_into

Writes the symmetric dot-product matrix into pre-allocated output, touching only the upper triangle of it.

```rust
fn dots_symmetric__symmetric_into<Out, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut Out,
) -> Result<(), Error>
where
    Out: TensorMut<Scalar::Accumulator, OUTPUT_MAX_RANK>,
```

## hammings_packed_*_packed_into

Hamming distances into an existing output, avoiding allocation.

```rust
fn hammings_packed__packed_into<PackedAlloc, OutputTensor, const OUTPUT_MAX_RANK: usize>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
    output: &mut OutputTensor,
) -> Result<(), Error>
where
    PackedAlloc: Allocator,
    OutputTensor: TensorMut<u32, OUTPUT_MAX_RANK>,
```

The output may be a `&mut Tensor<...>` or `&mut TensorSpan<...>`; any writable tensor
container that implements [`TensorMut`](#TensorMut) works. The kernel overwrites `c` entirely, so it
need not arrive pre-initialized.

## jaccards_packed_*_packed_into

Jaccard distances into an existing output, avoiding allocation.

```rust
fn jaccards_packed__packed_into<PackedAlloc, OutputTensor, const OUTPUT_MAX_RANK: usize>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
    output: &mut OutputTensor,
) -> Result<(), Error>
where
    PackedAlloc: Allocator,
    OutputTensor: TensorMut<Scalar::JaccardResult, OUTPUT_MAX_RANK>,
```

The output may be a `&mut Tensor<...>` or `&mut TensorSpan<...>`; any writable tensor
container that implements [`TensorMut`](#TensorMut) works. The kernel overwrites `c` entirely, so it
need not arrive pre-initialized.

## hammings_*_symmetric

Computes the upper triangle of the symmetric Hamming-distance matrix of the rows with themselves.

```rust
fn hammings__symmetric(&self) -> Result<Tensor<u32, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## hammings_symmetric_*_symmetric_into

Writes the symmetric Hamming-distance matrix into pre-allocated output, touching only the upper triangle of it.

```rust
fn hammings_symmetric__symmetric_into<Out, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut Out,
) -> Result<(), Error>
where
    Out: TensorMut<u32, OUTPUT_MAX_RANK>,
```

## jaccards_*_symmetric

Computes the upper triangle of the symmetric Jaccard-distance matrix of the rows with themselves.

```rust
fn jaccards__symmetric(&self) -> Result<Tensor<Scalar::JaccardResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## jaccards_symmetric_*_symmetric_into

Writes the symmetric Jaccard-distance matrix into pre-allocated output, touching only the upper triangle of it.

```rust
fn jaccards_symmetric__symmetric_into<Out, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut Out,
) -> Result<(), Error>
where
    Out: TensorMut<Scalar::JaccardResult, OUTPUT_MAX_RANK>,
```

## angulars_packed_*_packed_into

Angular distances into an existing output, avoiding allocation.

```rust
fn angulars_packed__packed_into<PackedAlloc, OutputTensor, const OUTPUT_MAX_RANK: usize>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
    output: &mut OutputTensor,
) -> Result<(), Error>
where
    PackedAlloc: Allocator,
    OutputTensor: TensorMut<Scalar::SpatialResult, OUTPUT_MAX_RANK>,
```

The output may be a `&mut Tensor<...>` or `&mut TensorSpan<...>`; any writable tensor
container that implements [`TensorMut`](#TensorMut) works. The kernel overwrites `c` entirely, so it
need not arrive pre-initialized.

## euclideans_packed_*_packed_into

Euclidean distances into an existing output, avoiding allocation.

```rust
fn euclideans_packed__packed_into<PackedAlloc, OutputTensor, const OUTPUT_MAX_RANK: usize>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
    output: &mut OutputTensor,
) -> Result<(), Error>
where
    PackedAlloc: Allocator,
    OutputTensor: TensorMut<Scalar::SpatialResult, OUTPUT_MAX_RANK>,
```

The output may be a `&mut Tensor<...>` or `&mut TensorSpan<...>`; any writable tensor
container that implements [`TensorMut`](#TensorMut) works. The kernel overwrites `c` entirely, so it
need not arrive pre-initialized.

## angulars_*_symmetric

Computes the upper triangle of the symmetric angular-distance matrix of the rows with themselves.

```rust
fn angulars__symmetric(&self) -> Result<Tensor<Scalar::SpatialResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## angulars_symmetric_*_symmetric_into

Writes the symmetric angular-distance matrix into pre-allocated output, touching only the upper triangle of it.

```rust
fn angulars_symmetric__symmetric_into<Out, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut Out,
) -> Result<(), Error>
where
    Out: TensorMut<Scalar::SpatialResult, OUTPUT_MAX_RANK>,
```

## euclideans_*_symmetric

Computes the upper triangle of the symmetric Euclidean-distance matrix of the rows with themselves.

```rust
fn euclideans__symmetric(
    &self,
) -> Result<Tensor<Scalar::SpatialResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## euclideans_symmetric_*_symmetric_into

Writes the symmetric euclidean-distance matrix into pre-allocated output, touching only the upper triangle of it.

```rust
fn euclideans_symmetric__symmetric_into<Out, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut Out,
) -> Result<(), Error>
where
    Out: TensorMut<Scalar::SpatialResult, OUTPUT_MAX_RANK>,
```

## *

Total number of logical elements, the product of the shape dimensions.

```rust
fn numel(&self) -> usize
```

Examples: ```
let t = Tensor::&#x3C;f32>::full(&#x26;[2, 3, 4], 0.0).unwrap();
assert_eq!(t.numel(), 24);
```

## *

Alias for [`ndim`](#ndim) — number of dimensions.

```rust
fn rank(&self) -> usize
```

## is_*_empty

Returns `true` if the tensor contains zero logical elements.

```rust
fn is__empty(&self) -> bool
```

A rank-0 tensor is a scalar and is _not_ empty — it has one element.

## has_contiguous_*_contiguous_rows

Returns `true` for rank-2 tensors whose innermost stride equals one element — the layout required by GEMM's left-hand matrix.

```rust
fn has_contiguous__contiguous_rows(&self) -> bool
```

## is_*_contiguous

Returns `true` if the entire tensor is stored in row-major contiguous order with no gaps.

```rust
fn is__contiguous(&self) -> bool
```

A contiguous tensor can be reinterpreted as a flat slice via
[`TensorView::as_contiguous_slice`](#as_contiguous_slice); a non-contiguous one cannot.

## TensorMut

Mutable structural access to N-dimensional tensor containers.

```rust
pub trait TensorMut<Scalar: StorageElement, const MAX_RANK: usize>: TensorRef<Scalar, MAX_RANK>
```

[`TensorMut`](#TensorMut) is a supertrait of [`TensorRef`](#TensorRef) that adds a single method — a mutable raw pointer
to the first element. It is implemented by [`Tensor`](#Tensor), which owns its memory, and by
[`TensorSpan`](#TensorSpan), which borrows a mutable sub-region. Immutable views ([`TensorView`](#TensorView))
deliberately do not implement [`TensorMut`](#TensorMut).

Generic write-access helpers accept `&mut (impl TensorMut<Scalar, R>)` so they work uniformly
against owned tensors and span reborrows.

Implementors: - `impl<Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), Alloc: Allocator, const R: usize> [TensorMut](#TensorMut)<Scalar, R> for [Tensor](#Tensor)<Scalar, Alloc, R>`
- `impl<'a, Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), const R: usize, Alloc: Allocator> [TensorMut](#TensorMut)<Scalar, R> for [TensorSpan](#TensorSpan)<'a, Scalar, R, Alloc>`

## as_mut_ptr

Raw mutable pointer to the first storage element.

```rust
fn as_mut_ptr(&mut self) -> *mut Scalar
```

The pointer is valid for `numel()` divided by `dimensions_per_value()` writes and preserves
whatever stride layout [`TensorRef::stride_bytes`](#stride_bytes) reports — callers must honour the
per-axis strides when striding through non-contiguous memory.

## TensorRef

Read-only structural access to N-dimensional tensor containers.

```rust
pub trait TensorRef<Scalar: StorageElement, const MAX_RANK: usize>
```

Implemented by [`Tensor`](#Tensor), [`TensorView`](#TensorView), and [`TensorSpan`](#TensorSpan), enabling generic code over any
tensor-like container. Most operations in this crate accept `&(impl TensorRef<Scalar, MAX_RANK>

- ?Sized)` so you can mix owned tensors, views, and spans freely without copying.

The trait only exposes _structural_ accessors — shape, strides, pointer, and a borrow-as-view
constructor. Element reads happen through the resulting [`TensorView`](#TensorView). See [`TensorMut`](#TensorMut) for
the mutable counterpart.

Implementors: - `impl<Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), Alloc: Allocator, const R: usize> [TensorRef](#TensorRef)<Scalar, R> for [Tensor](#Tensor)<Scalar, Alloc, R>`
- `impl<'a, Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), const R: usize, Alloc: Allocator> [TensorRef](#TensorRef)<Scalar, R> for [TensorView](#TensorView)<'a, Scalar, R, Alloc>`
- `impl<'a, Scalar: [StorageElement](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement), const R: usize, Alloc: Allocator> [TensorRef](#TensorRef)<Scalar, R> for [TensorSpan](#TensorSpan)<'a, Scalar, R, Alloc>`

## Alloc

The allocator of the owning tensor, which allocating operations clone for their result.

```rust
type Alloc: Allocator;
```

An arena that is not `Clone` works by reference: `&Arena` is itself a `Clone` allocator.

## *

The owning tensor's allocator, or [`Global`](https://www.unum.cloud/docs/numkong/rust/external-memory.md#Global) for a view over foreign memory.

```rust
fn allocator(&self) -> &Self::Alloc
```

## shape

Logical shape as a slice of length `ndim()`.

```rust
fn shape(&self) -> &[usize]
```

For sub-byte types this is the number of individual elements, not the packed storage count.

## ndim

Number of dimensions currently in use.

```rust
fn ndim(&self) -> usize
```

Always satisfies `ndim() <= MAX_RANK`. A rank-0 tensor reports `0`.

## stride_bytes

Byte stride along dimension `dim`.

```rust
fn stride_bytes(&self, dim: usize) -> isize
```

Negative values indicate reverse traversal, such as from a stepped slice. Only indices in
`0..ndim()` are valid.

Examples: ```
let t = Tensor::&#x3C;f32>::full(&#x26;[3, 4], 0.0).unwrap();
assert_eq!(t.stride_bytes(1), 4);  // innermost f32 stride
```

## as_ptr

Raw pointer to the first storage element.

```rust
fn as_ptr(&self) -> *const Scalar
```

The pointer is valid for `shape().iter().product()` _logical_ reads, divided by
`Scalar::dimensions_per_value()` for sub-byte types.

## *

Borrow as an immutable [`TensorView`](#TensorView) with the same shape and strides.

```rust
fn view(&self) -> TensorView<'_, Scalar, MAX_RANK, Self::Alloc>
```

This is a zero-cost reborrow and is the normal entry point for extension-trait methods that
want to delegate to view-level code.

## TensorSpan

A mutable, zero-copy view into a [`Tensor`](#Tensor).

```rust
pub struct TensorSpan<'a, Scalar, const MAX_RANK: usize = DEFAULT_MAX_RANK, Alloc = Global>
```

[`TensorSpan`](#TensorSpan) borrows the parent tensor's memory exclusively for the duration of `'a`, giving
write access without taking ownership. As with [`TensorView`](#TensorView), a span may carry non-contiguous
byte strides so slicing, transposition, and stepped sub-views all remain free of data copies.

Spans are typically produced by [`Tensor::span`](#span) or by a mutable slicing method such as
`tensor.slice_mut((..,0_usize))`. Lower-level construction from a raw pointer is available
through [`TensorSpan::from_raw_parts`](#from_raw_parts).

A span is the mutable counterpart of [`TensorView`](#TensorView). At most one span to a given region may
exist at a time; reborrow via [`TensorSpan::as_view`](#as_view) to hand out immutable sub-views without
surrendering the span.

The `'a` lifetime ties the span to the owning tensor, so the referenced memory stays valid for
as long as the span exists.

Implements: `[CastOps](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#CastOps)<Source, R>`, `[DenseToScaledOps](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#DenseToScaledOps)<R>`, `[AllCloseOps](https://www.unum.cloud/docs/numkong/rust/platform-notes.md#AllCloseOps)<Scalar, R>`, `[ScaleOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#ScaleOps)<Scalar, R>`, `[SumOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#SumOps)<Scalar, R>`, `[BlendOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#BlendOps)<Scalar, R>`, `[FmaOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#FmaOps)<Scalar, R>`, `[BitwiseReductionsOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#BitwiseReductionsOps)<MAX_RANK>`, `[MomentsOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#MomentsOps)<Scalar, R>`, `[MinMaxOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#MinMaxOps)<Scalar, R>`, `[TrigSinOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#TrigSinOps)<Scalar, R>`, `[TrigCosOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#TrigCosOps)<Scalar, R>`, `[TrigAtanOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#TrigAtanOps)<Scalar, R>`, `[DotsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#DotsPackedOps)<Scalar, MAX_RANK>`, `[SymmetricDotsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricDotsOps)<Scalar, R>`, `[HammingsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#HammingsPackedOps)<Scalar, MAX_RANK>`, `[JaccardsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#JaccardsPackedOps)<Scalar, MAX_RANK>`, `[SymmetricHammingsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricHammingsOps)<Scalar, R>`, `[SymmetricJaccardsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricJaccardsOps)<Scalar, R>`, `[AngularsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#AngularsPackedOps)<Scalar, MAX_RANK>`, `[EuclideansPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#EuclideansPackedOps)<Scalar, MAX_RANK>`, `[SymmetricAngularsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricAngularsOps)<Scalar, R>`, `[SymmetricEuclideansOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricEuclideansOps)<Scalar, R>`, `Debug`, `Send`, `Sync`, `[TensorRef](#TensorRef)<Scalar, R>`, `[TensorMut](#TensorMut)<Scalar, R>`, `[Fill](#Fill)<Scalar>`, `[CopyFrom](#CopyFrom)<&'b [TensorView](#TensorView)<'_, Scalar, MAX_RANK, SourceAlloc>>`, `IntoIterator`, `PartialEq`

## from_raw_parts

Create a mutable view from a raw pointer, shape, and byte strides, reporting [`Global`](https://www.unum.cloud/docs/numkong/rust/external-memory.md#Global) as its allocator.

```rust
pub unsafe fn from_raw_parts(
    data: *mut Scalar,
    shape: &[usize],
    strides_bytes: &[isize],
) -> Result<Self, Error>
```

Safety: - `data` must be valid for reads and writes over the region described by [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape) and
`strides_bytes`.

- The pointed-to memory must outlive `'a`.

- No other references to the memory may exist for the duration of `'a`.

Returns `Err` if `shape.len() > MAX_RANK` or `shape.len() != strides_bytes.len()`.

## from_raw_parts_in

Like [`TensorSpan::from_raw_parts`](#from_raw_parts), reporting [`allocator`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#allocator) to the operations that allocate.

```rust
pub unsafe fn from_raw_parts_in(
    data: *mut Scalar,
    shape: &[usize],
    strides_bytes: &[isize],
    allocator: &'a Alloc,
) -> Result<Self, Error>
```

Safety: The same as for [`TensorSpan::from_raw_parts`](#from_raw_parts).

## *

Returns the shape of the view.

```rust
pub fn shape(&self) -> &[usize]
```

## as_*_ptr

Returns a pointer to the first element.

```rust
pub fn as__ptr(&self) -> *const Scalar
```

## as_mut_ptr

Returns a mutable pointer to the first element.

```rust
pub fn as_mut_ptr(&mut self) -> *mut Scalar
```

## as_view

Reborrow as immutable view.

```rust
pub fn as_view(&self) -> TensorView<'_, Scalar, MAX_RANK, Alloc>
```

## scalar

Access the scalar value of a rank-0 tensor span.

```rust
pub fn scalar(&self) -> Result<&Scalar, Error>
```

## scalar_mut

Access the mutable scalar value of a rank-0 tensor span.

```rust
pub fn scalar_mut(&mut self) -> Result<&mut Scalar, Error>
```

## slice

Slice the span along multiple dimensions.

```rust
pub fn slice(&self, spec: impl SliceSpec) -> Result<TensorView<'_, Scalar, MAX_RANK, Alloc>, Error>
```

Accepts tuples of Rust range types or `&[SliceRange]`.

## slice_mut

Slice the span mutably along multiple dimensions.

```rust
pub fn slice_mut(
    &mut self,
    spec: impl SliceSpec,
) -> Result<TensorSpan<'_, Scalar, MAX_RANK, Alloc>, Error>
```

Accepts tuples of Rust range types or `&[SliceRange]`.

## as_contiguous_*_contiguous_slice

Convert to slice; only valid for contiguous views.

```rust
pub fn as_contiguous__contiguous_slice(&self) -> Option<&[Scalar]>
```

## as_contiguous_slice_mut

Convert to mutable slice; only valid for contiguous views.

```rust
pub fn as_contiguous_slice_mut(&mut self) -> Option<&mut [Scalar]>
```

## reshape

Reshape the span — must have same total elements, contiguous only.

```rust
pub fn reshape(&self, new_shape: &[usize]) -> Result<TensorSpan<'a, Scalar, MAX_RANK, Alloc>, Error>
```

Returns an error for sub-byte types.

## to_owned

Copy the span contents to a new owned Tensor.

```rust
pub fn to_owned(&self) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

## scale_inplace

In-place affine: selfᵢ = α × selfᵢ + β.

```rust
pub fn scale_inplace(&mut self, alpha: Scalar::Scalar, beta: Scalar::Scalar) -> Result<(), Error>
```

## add_scalar_inplace

In-place add scalar: selfᵢ = selfᵢ + scalar.

```rust
pub fn add_scalar_inplace(&mut self, scalar: Scalar::Scalar) -> Result<(), Error>
```

## sub_scalar_inplace

In-place subtract scalar: selfᵢ = selfᵢ − scalar.

```rust
pub fn sub_scalar_inplace(&mut self, scalar: Scalar::Scalar) -> Result<(), Error>
```

## mul_scalar_inplace

In-place multiply scalar: selfᵢ = selfᵢ × scalar.

```rust
pub fn mul_scalar_inplace(&mut self, scalar: Scalar::Scalar) -> Result<(), Error>
```

## add_inplace

In-place sum: selfᵢ = selfᵢ + otherᵢ.

```rust
pub fn add_inplace<OtherAlloc: Allocator>(
    &mut self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
) -> Result<(), Error>
```

## sub_inplace

In-place subtract tensor: selfᵢ = selfᵢ − otherᵢ.

```rust
pub fn sub_inplace<OtherAlloc: Allocator>(
    &mut self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
) -> Result<(), Error>
```

## mul_inplace

In-place multiply tensor: selfᵢ = selfᵢ × otherᵢ.

```rust
pub fn mul_inplace<OtherAlloc: Allocator>(
    &mut self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
) -> Result<(), Error>
```

Mirrors out-of-place [`mul_tensor`](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#mul_tensor), which is an FMA with `c = self` and `alpha = 1`, `beta = 0`. The `c` operand is bound to `self` inside the kernel via the single span pointer, so
`other` remains the only foreign slice.

## sin_inplace

In-place sine: selfᵢ = sin(selfᵢ).

```rust
pub fn sin_inplace(&mut self) -> Result<(), Error>
```

## cos_inplace

In-place cosine: selfᵢ = cos(selfᵢ).

```rust
pub fn cos_inplace(&mut self) -> Result<(), Error>
```

## atan_inplace

In-place arctangent: selfᵢ = atan(selfᵢ).

```rust
pub fn atan_inplace(&mut self) -> Result<(), Error>
```

## dots_*_packed

Dot-product multiply: C = self × packed_rightᵀ

```rust
fn dots__packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::Accumulator, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

self must be 2D __[m,k]__ with contiguous rows. packed_right contains B __[n,k]__
packed. Returns C __[m,n]__, allocated like `self`.

Returns `Err` if:

- self is not 2D

- self has non-contiguous rows

- inner dimensions don't match

- output allocation fails

- the kernel refuses `packed_right`, like one packed under other capabilities

## hammings_*_packed

Hamming distances: C = self × packed_rightᵀ

```rust
fn hammings__packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<u32, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

self must be 2D __[m,k]__ with contiguous rows. packed_right contains B __[n,k]__
packed. Returns C __[m,n]__, allocated like `self`.

Returns `Err` if:

- self is not 2D

- self has non-contiguous rows

- inner dimensions don't match

- output allocation fails

- the kernel refuses `packed_right`, like one packed under other capabilities

## jaccards_*_packed

Jaccard distances: C = self × packed_rightᵀ

```rust
fn jaccards__packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::JaccardResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

self must be 2D __[m,k]__ with contiguous rows. packed_right contains B __[n,k]__
packed. Returns C __[m,n]__, allocated like `self`.

Returns `Err` if:

- self is not 2D

- self has non-contiguous rows

- inner dimensions don't match

- output allocation fails

- the kernel refuses `packed_right`, like one packed under other capabilities

## angulars_*_packed

Angular distances: C = angular(self, packed_rightᵀ)

```rust
fn angulars__packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::SpatialResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

self must be 2D __[m,k]__ with contiguous rows. packed_right contains B __[n,k]__
packed. Returns C __[m,n]__, allocated like `self`.

Returns `Err` if:

- self is not 2D

- self has non-contiguous rows

- inner dimensions don't match

- output allocation fails

- the kernel refuses `packed_right`, like one packed under other capabilities

## euclideans_*_packed

Euclidean distances: C = euclidean(self, packed_rightᵀ)

```rust
fn euclideans__packed<PackedAlloc: Allocator>(
    &self,
    packed_right: &DotsPackedMatrix<Scalar, PackedAlloc>,
) -> Result<Tensor<Scalar::SpatialResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

self must be 2D __[m,k]__ with contiguous rows. packed_right contains B __[n,k]__
packed. Returns C __[m,n]__, allocated like `self`.

Returns `Err` if:

- self is not 2D

- self has non-contiguous rows

- inner dimensions don't match

- output allocation fails

- the kernel refuses `packed_right`, like one packed under other capabilities

## TensorSpanDims

A mutable dimension-only adapter over [`TensorSpanIterator`](#TensorSpanIterator), yielding [`DimMut`](#DimMut) items and discarding positions.

```rust
pub struct TensorSpanDims<'a, Scalar: FloatConvertible, const MAX_RANK: usize = DEFAULT_MAX_RANK>
```

Implements: `Iterator`, `ExactSizeIterator`, `FusedIterator`

## TensorSpanIterator

Mutable element iterator over possibly non-contiguous tensor data.

```rust
pub struct TensorSpanIterator<'a, Scalar: FloatConvertible, const MAX_RANK: usize = DEFAULT_MAX_RANK>
```

Yields `(position, DimMut<'a, Scalar>)` pairs in row-major order at the logical-scalar level.
For sub-byte types, each proxy performs a read-modify-write on drop.

Implements: `Iterator`, `ExactSizeIterator`, `FusedIterator`

## dims

Adapt this iterator to yield only mutable dimension proxies, discarding positions.

```rust
pub fn dims(self) -> TensorSpanDims<'a, Scalar, MAX_RANK>
```

## TensorView

A read-only, zero-copy view into a [`Tensor`](#Tensor).

```rust
pub struct TensorView<'a, Scalar, const MAX_RANK: usize = DEFAULT_MAX_RANK, Alloc = Global>
```

[`TensorView`](#TensorView) borrows the parent tensor's memory for the duration of `'a` without owning or
copying any data. Views may have arbitrary byte strides, so they transparently represent
slicing, transposition, or step-sampling of the underlying storage — iteration and indexing
honour those strides.

A view is normally obtained by calling [`Tensor::view`](#view) or by slicing:
`tensor.slice((0..4_usize, ..))`. For lower-level construction from a raw pointer plus
shape/stride arrays, see [`TensorView::from_raw_parts`](#from_raw_parts).

[`TensorView`](#TensorView) is the immutable counterpart of [`TensorSpan`](#TensorSpan). Both share the same layout fields,
but a view cannot be used to mutate the backing storage. Multiple views into the same tensor may
coexist, subject to Rust's borrow rules; a mutable span excludes all other references.

The `'a` lifetime ties the view to the source tensor or outer view, ensuring the referenced
memory outlives the view itself.

Implements: `[CastOps](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#CastOps)<Source, R>`, `[DenseToScaledOps](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#DenseToScaledOps)<R>`, `[AllCloseOps](https://www.unum.cloud/docs/numkong/rust/platform-notes.md#AllCloseOps)<Scalar, R>`, `[ScaleOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#ScaleOps)<Scalar, R>`, `[SumOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#SumOps)<Scalar, R>`, `[BlendOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#BlendOps)<Scalar, R>`, `[FmaOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#FmaOps)<Scalar, R>`, `[BitwiseReductionsOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#BitwiseReductionsOps)<MAX_RANK>`, `[MomentsOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#MomentsOps)<Scalar, R>`, `[MinMaxOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#MinMaxOps)<Scalar, R>`, `[TrigSinOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#TrigSinOps)<Scalar, R>`, `[TrigCosOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#TrigCosOps)<Scalar, R>`, `[TrigAtanOps](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#TrigAtanOps)<Scalar, R>`, `[DotsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#DotsPackedOps)<Scalar, MAX_RANK>`, `[SymmetricDotsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricDotsOps)<Scalar, R>`, `[HammingsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#HammingsPackedOps)<Scalar, MAX_RANK>`, `[JaccardsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#JaccardsPackedOps)<Scalar, MAX_RANK>`, `[SymmetricHammingsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricHammingsOps)<Scalar, R>`, `[SymmetricJaccardsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricJaccardsOps)<Scalar, R>`, `[AngularsPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#AngularsPackedOps)<Scalar, MAX_RANK>`, `[EuclideansPackedOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#EuclideansPackedOps)<Scalar, MAX_RANK>`, `[SymmetricAngularsOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricAngularsOps)<Scalar, R>`, `[SymmetricEuclideansOps](https://www.unum.cloud/docs/numkong/rust/matrix-kernels.md#SymmetricEuclideansOps)<Scalar, R>`, `Clone`, `Copy`, `Debug`, `Send`, `Sync`, `[TensorRef](#TensorRef)<Scalar, R>`, `[CopyFrom](#CopyFrom)<&'b [TensorView](#TensorView)<'_, Scalar, MAX_RANK, SourceAlloc>>`, `IntoIterator`, `PartialEq`

## dots_symmetric

Computes the symmetric dot-product matrix C = A × Aᵀ.

```rust
pub fn dots_symmetric(&self) -> Result<Tensor<Scalar::Accumulator, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn dots_symmetric(&self) -> Result<Tensor<Scalar::Accumulator, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

Computes the upper triangle of the symmetric dot-product matrix of the rows with themselves.

Given a matrix of row vectors, computes the symmetric __[n,n]__ matrix of all pairwise dot
products, where result[i,j] = dot(row_i, row_j).

Examples: ```
use numkong::{Tensor, TensorView};

// 100 vectors of dimension 768
let vectors = Tensor::&#x3C;f32>::full(&#x26;[100, 768], 0.0)?;

// Compute 100×100 symmetric matrix
let gram = vectors.view().dots_symmetric()?;
assert_eq!(gram.shape(), &#x26;[100, 100]);
```

## dots_symmetric_into

Computes the symmetric dot-product matrix into pre-allocated output.

```rust
pub fn dots_symmetric_into<OutputTensor, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut OutputTensor,
) -> Result<(), Error>
where
    OutputTensor: TensorMut<Scalar::Accumulator, OUTPUT_MAX_RANK>,
```

```rust
fn dots_symmetric_into<Out, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut Out,
) -> Result<(), Error>
where
    Out: TensorMut<Scalar::Accumulator, OUTPUT_MAX_RANK>,
```

Writes the symmetric dot-product matrix into pre-allocated output, touching only the upper triangle of it.

Only the upper triangle of `c` is written; the lower triangle is queries as-is. The output
may be a `&mut Tensor<...>` or `&mut TensorSpan<...>`.

## hammings_symmetric

Computes symmetric Hamming distance matrix for a set of binary vectors.

```rust
pub fn hammings_symmetric(&self) -> Result<Tensor<u32, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn hammings_symmetric(&self) -> Result<Tensor<u32, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

Computes the upper triangle of the symmetric Hamming-distance matrix of the rows with themselves.

## hammings_symmetric_into

Computes symmetric Hamming distances into pre-allocated output, touching only the upper triangle of it.

```rust
pub fn hammings_symmetric_into<OutputTensor, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut OutputTensor,
) -> Result<(), Error>
where
    OutputTensor: TensorMut<u32, OUTPUT_MAX_RANK>,
```

```rust
fn hammings_symmetric_into<Out, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut Out,
) -> Result<(), Error>
where
    Out: TensorMut<u32, OUTPUT_MAX_RANK>,
```

Writes the symmetric Hamming-distance matrix into pre-allocated output, touching only the upper triangle of it.

## jaccards_symmetric

Computes symmetric Jaccard distance matrix for a set of binary vectors.

```rust
pub fn jaccards_symmetric(&self) -> Result<Tensor<Scalar::JaccardResult, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn jaccards_symmetric(&self) -> Result<Tensor<Scalar::JaccardResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

Computes the upper triangle of the symmetric Jaccard-distance matrix of the rows with themselves.

## jaccards_symmetric_into

Computes symmetric Jaccard distances into pre-allocated output, touching only the upper triangle of it.

```rust
pub fn jaccards_symmetric_into<OutputTensor, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut OutputTensor,
) -> Result<(), Error>
where
    OutputTensor: TensorMut<Scalar::JaccardResult, OUTPUT_MAX_RANK>,
```

```rust
fn jaccards_symmetric_into<Out, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut Out,
) -> Result<(), Error>
where
    Out: TensorMut<Scalar::JaccardResult, OUTPUT_MAX_RANK>,
```

Writes the symmetric Jaccard-distance matrix into pre-allocated output, touching only the upper triangle of it.

## angulars_symmetric

Computes symmetric angular distance matrix for a set of vectors.

```rust
pub fn angulars_symmetric(&self) -> Result<Tensor<Scalar::SpatialResult, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn angulars_symmetric(&self) -> Result<Tensor<Scalar::SpatialResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

Computes the upper triangle of the symmetric angular-distance matrix of the rows with themselves.

## angulars_symmetric_into

Computes symmetric angular distances into pre-allocated output, touching only the upper triangle of it.

```rust
pub fn angulars_symmetric_into<OutputTensor, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut OutputTensor,
) -> Result<(), Error>
where
    OutputTensor: TensorMut<Scalar::SpatialResult, OUTPUT_MAX_RANK>,
```

```rust
fn angulars_symmetric_into<Out, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut Out,
) -> Result<(), Error>
where
    Out: TensorMut<Scalar::SpatialResult, OUTPUT_MAX_RANK>,
```

Writes the symmetric angular-distance matrix into pre-allocated output, touching only the upper triangle of it.

## euclideans_symmetric

Computes symmetric euclidean distance matrix for a set of vectors.

```rust
pub fn euclideans_symmetric(&self) -> Result<Tensor<Scalar::SpatialResult, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn euclideans_symmetric(
    &self,
) -> Result<Tensor<Scalar::SpatialResult, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

Computes the upper triangle of the symmetric Euclidean-distance matrix of the rows with themselves.

## euclideans_symmetric_into

Computes symmetric euclidean distances into pre-allocated output, touching only the upper triangle of it.

```rust
pub fn euclideans_symmetric_into<OutputTensor, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut OutputTensor,
) -> Result<(), Error>
where
    OutputTensor: TensorMut<Scalar::SpatialResult, OUTPUT_MAX_RANK>,
```

```rust
fn euclideans_symmetric_into<Out, const OUTPUT_MAX_RANK: usize>(
    &self,
    output: &mut Out,
) -> Result<(), Error>
where
    Out: TensorMut<Scalar::SpatialResult, OUTPUT_MAX_RANK>,
```

Writes the symmetric euclidean-distance matrix into pre-allocated output, touching only the upper triangle of it.

## from_raw_parts

Create a view from a raw pointer, shape, and byte strides, reporting [`Global`](https://www.unum.cloud/docs/numkong/rust/external-memory.md#Global) as its allocator.

```rust
pub unsafe fn from_raw_parts(
    data: *const Scalar,
    shape: &[usize],
    strides_bytes: &[isize],
) -> Result<Self, Error>
```

The [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape) specifies logical dimensions. For sub-byte types, the storage count is
`shape.product()` divided by `dimensions_per_value()`; for normal types the two are equal.

Safety: - `data` must be valid for reads over the region described by [`shape`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#shape) and `strides_bytes`.

- The pointed-to memory must outlive `'a`.

Returns `Err` if `shape.len() > MAX_RANK` or `shape.len() != strides_bytes.len()`.

## from_raw_parts_in

Like [`TensorView::from_raw_parts`](#from_raw_parts), reporting [`allocator`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#allocator) to the operations that allocate.

```rust
pub unsafe fn from_raw_parts_in(
    data: *const Scalar,
    shape: &[usize],
    strides_bytes: &[isize],
    allocator: &'a Alloc,
) -> Result<Self, Error>
```

Safety: The same as for [`TensorView::from_raw_parts`](#from_raw_parts).

## get_unchecked

Get element at flat index; only valid for contiguous views.

```rust
pub unsafe fn get_unchecked(&self, index: usize) -> &Scalar
```

Safety: Caller must ensure the view is contiguous and index is in bounds.

## scalar

Access the scalar value of a rank-0 tensor view.

```rust
pub fn scalar(&self) -> Result<&Scalar, Error>
```

## slice

Slice the view along multiple dimensions.

```rust
pub fn slice(&self, spec: impl SliceSpec) -> Result<TensorView<'a, Scalar, MAX_RANK, Alloc>, Error>
```

Accepts tuples of Rust range types or `&[SliceRange]`. Indexing with a scalar reduces the
rank, while range arguments preserve it.

Examples: ```
use numkong::tensor::{Tensor, SliceRange};

let t = Tensor::&#x3C;f32>::full(&#x26;[4, 5], 1.0).unwrap();
let view = t.view();

// Rust-native tuple syntax
let row = view.slice((1_usize, ..)).unwrap();            // t[1, :]
let block = view.slice((1..3_usize, 0..4_usize)).unwrap();// t[1:3, 0:4]

// Enum-based syntax for programmatic construction
let same_row = view.slice(&#x26;[SliceRange::index(1), SliceRange::full()]).unwrap();
assert_eq!(row.shape(), same_row.shape());
```

## to_owned

Copy the view contents to a new owned Tensor.

```rust
pub fn to_owned(&self) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

## is_packed_contiguous

True when the underlying storage _bytes_ are densely packed in memory.

```rust
pub fn is_packed_contiguous(&self) -> bool
```

Unlike [`is_contiguous`](#is_contiguous), this accounts for sub-byte packing: the
innermost-axis extent is measured in storage values (`shape / dimensions_per_value`), so a
freshly-allocated [`e2m1x2`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#e2m1x2) tensor, whose row stride is `columns / 2` bytes, is recognized as
packed. Used by the block-scaled casts, which hand raw byte buffers to the C kernel.

## as_packed_slice

Storage values as a slice when the bytes are packed, sub-byte aware.

```rust
pub fn as_packed_slice(&self) -> Option<&[Scalar]>
```

Returns `None` for strided/transposed views. This is the sub-byte-aware companion to
[`as_contiguous_slice`](#as_contiguous_slice).

## reshape

Reshape the view — must have same total elements, contiguous only.

```rust
pub fn reshape(&self, new_shape: &[usize]) -> Result<TensorView<'a, Scalar, MAX_RANK, Alloc>, Error>
```

For sub-byte types this returns an error, since a reshape would invalidate the packed
element layout.

## scale_tensor

Writes α × aᵢ + β into a new tensor.

```rust
pub fn scale_tensor(
    &self,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

## add_scalar

Element-wise add scalar into a new tensor.

```rust
pub fn add_scalar(&self, scalar: Scalar::Scalar) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn add_scalar(&self, scalar: Scalar::Scalar) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## sub_scalar

Element-wise subtract scalar into a new tensor.

```rust
pub fn sub_scalar(&self, scalar: Scalar::Scalar) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn sub_scalar(&self, scalar: Scalar::Scalar) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## mul_scalar

Element-wise multiply scalar into a new tensor.

```rust
pub fn mul_scalar(&self, scalar: Scalar::Scalar) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn mul_scalar(&self, scalar: Scalar::Scalar) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## add_tensor

Element-wise sum of two tensors into a new tensor.

```rust
pub fn add_tensor<OtherAlloc: Allocator>(
    &self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn add_tensor(
    &self,
    other: &impl TensorRef<Scalar, MAX_RANK> + ?Sized,
) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## add_tensor_into

Element-wise sum of two tensors into the output tensor.

```rust
pub fn add_tensor_into<OtherAlloc: Allocator, OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

```rust
fn add_tensor_into<OtherTensor, OutputTensor>(
    &self,
    other: &OtherTensor,
    out: &mut OutputTensor,
) -> Result<(), Error>
where
    OtherTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized,
```

## blend_tensor

Writes α × aᵢ + β × otherᵢ into a new tensor.

```rust
pub fn blend_tensor<OtherAlloc: Allocator>(
    &self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

## blend_tensor_into

Writes α × aᵢ + β × otherᵢ into the output tensor.

```rust
pub fn blend_tensor_into<OtherAlloc: Allocator, OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

```rust
fn blend_tensor_into<OtherTensor, OutputTensor>(
    &self,
    other: &OtherTensor,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
    out: &mut OutputTensor,
) -> Result<(), Error>
where
    OtherTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized,
```

## sub_tensor

Element-wise difference of two tensors into a new tensor.

```rust
pub fn sub_tensor<OtherAlloc: Allocator>(
    &self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn sub_tensor(
    &self,
    other: &impl TensorRef<Scalar, MAX_RANK> + ?Sized,
) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## sub_tensor_into

Element-wise difference of two tensors into the output tensor.

```rust
pub fn sub_tensor_into<OtherAlloc: Allocator, OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

```rust
fn sub_tensor_into<OtherTensor, OutputTensor>(
    &self,
    other: &OtherTensor,
    out: &mut OutputTensor,
) -> Result<(), Error>
where
    OtherTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized,
```

## fma_tensors

Writes α × aᵢ × bᵢ + β × cᵢ into a new tensor.

```rust
pub fn fma_tensors<BAlloc: Allocator, CAlloc: Allocator>(
    &self,
    b: &TensorView<'_, Scalar, MAX_RANK, BAlloc>,
    c: &TensorView<'_, Scalar, MAX_RANK, CAlloc>,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

## fma_tensors_into

Writes α × aᵢ × bᵢ + β × cᵢ into the output tensor.

```rust
pub fn fma_tensors_into<BAlloc: Allocator, CAlloc: Allocator, OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    b: &TensorView<'_, Scalar, MAX_RANK, BAlloc>,
    c: &TensorView<'_, Scalar, MAX_RANK, CAlloc>,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

```rust
fn fma_tensors_into<BTensor, CTensor, OutputTensor>(
    &self,
    b: &BTensor,
    c: &CTensor,
    alpha: Scalar::Scalar,
    beta: Scalar::Scalar,
    out: &mut OutputTensor,
) -> Result<(), Error>
where
    BTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    CTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized,
```

## mul_tensor

Element-wise product of two tensors into a new tensor.

```rust
pub fn mul_tensor<OtherAlloc: Allocator>(
    &self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn mul_tensor(
    &self,
    other: &impl TensorRef<Scalar, MAX_RANK> + ?Sized,
) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## mul_tensor_into

Element-wise product of two tensors into the output tensor.

```rust
pub fn mul_tensor_into<OtherAlloc: Allocator, OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized>(
    &self,
    other: &TensorView<'_, Scalar, MAX_RANK, OtherAlloc>,
    out: &mut OutputTensor,
) -> Result<(), Error>
```

```rust
fn mul_tensor_into<OtherTensor, OutputTensor>(
    &self,
    other: &OtherTensor,
    out: &mut OutputTensor,
) -> Result<(), Error>
where
    OtherTensor: TensorRef<Scalar, MAX_RANK> + ?Sized,
    OutputTensor: TensorMut<Scalar, MAX_RANK> + ?Sized,
```

## cast

Casts every element to `Destination`, returning a new tensor of the same shape.

```rust
pub fn cast<Destination: Clone + CastDType>(
    &self,
) -> Result<Tensor<Destination, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn cast<Destination: Clone + CastDType>(
    &self,
) -> Result<Tensor<Destination, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## cast_into

Casts every element to `Destination`, writing into the output tensor.

```rust
pub fn cast_into<Destination, OutputTensor>(&self, out: &mut OutputTensor) -> Result<(), Error>
where
    Destination: Clone + CastDType,
    OutputTensor: TensorMut<Destination, MAX_RANK> + ?Sized,
```

## sin

Element-wise sine into a new tensor.

```rust
pub fn sin(&self) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn sin(&self) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## cos

Element-wise cosine into a new tensor.

```rust
pub fn cos(&self) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn cos(&self) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## atan

Element-wise arctangent into a new tensor.

```rust
pub fn atan(&self) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn atan(&self) -> Result<Tensor<Scalar, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## moments_axis

Sum and sum of squares along one axis, into new tensors.

```rust
pub fn moments_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<(Tensor<<Scalar as ReduceMoments>::SumOutput, Alloc, MAX_RANK>, Tensor<<Scalar as ReduceMoments>::SumSqOutput, Alloc, MAX_RANK>), Error>
where
    Alloc: Clone,
```

```rust
fn moments_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<(Tensor<<Scalar as ReduceMoments>::SumOutput, Self::Alloc, MAX_RANK>, Tensor<<Scalar as ReduceMoments>::SumSqOutput, Self::Alloc, MAX_RANK>), Error>
where
    Self::Alloc: Clone,
```

## sum_axis

Sum along one axis, into a new tensor.

```rust
pub fn sum_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<Scalar::SumOutput, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn sum_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<Scalar::SumOutput, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## norm_axis

Euclidean norm along one axis, into a new tensor.

```rust
pub fn norm_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<f64, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn norm_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<f64, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## minmax_axis

Minimum and maximum with their indices along one axis, into new tensors.

```rust
pub fn minmax_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<MinMaxResult<Tensor<<Scalar as ReduceMinMax>::Output, Alloc, MAX_RANK>, Tensor<usize, Alloc, MAX_RANK>>, Error>
where
    Alloc: Clone,
```

```rust
fn minmax_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<MinMaxResult<Tensor<<Scalar as ReduceMinMax>::Output, Self::Alloc, MAX_RANK>, Tensor<usize, Self::Alloc, MAX_RANK>>, Error>
where
    Self::Alloc: Clone,
```

## min_axis

Minimum along one axis, into a new tensor.

```rust
pub fn min_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<Scalar::Output, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn min_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<Scalar::Output, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## argmin_axis

Index of the minimum along one axis, into a new tensor.

```rust
pub fn argmin_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<usize, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn argmin_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<usize, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## max_axis

Maximum along one axis, into a new tensor.

```rust
pub fn max_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<Scalar::Output, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn max_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<Scalar::Output, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## argmax_axis

Index of the maximum along one axis, into a new tensor.

```rust
pub fn argmax_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<usize, Alloc, MAX_RANK>, Error>
where
    Alloc: Clone,
```

```rust
fn argmax_axis<AnyIndex: VectorIndex>(
    &self,
    axis: AnyIndex,
    keep_dims: bool,
) -> Result<Tensor<usize, Self::Alloc, MAX_RANK>, Error>
where
    Self::Alloc: Clone,
```

## TensorViewDims

Dimension-only adapter over [`TensorViewIterator`](#TensorViewIterator), yielding [`DimRef`](#DimRef) without positions.

```rust
pub struct TensorViewDims<'a, Scalar: FloatConvertible, const MAX_RANK: usize = DEFAULT_MAX_RANK>
```

Created by [`TensorViewIterator::dims()`](#dims).

Implements: `Iterator`, `ExactSizeIterator`, `FusedIterator`

## TensorViewIterator

Lazy element iterator over possibly non-contiguous tensor data.

```rust
pub struct TensorViewIterator<'a, Scalar: FloatConvertible, const MAX_RANK: usize = DEFAULT_MAX_RANK>
```

Yields `(position, DimRef<'a, Scalar>)` pairs in row-major order at the logical-scalar level.
For sub-byte types, the innermost dimension is expanded by [`dimensions_per_value`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#dimensions_per_value); use
[`.dims()`](#dims) when only the dimension proxies are needed.

Cost per `next()` is O(1) amortized (O(ndim) only on carry propagation).

Implements: `Iterator`, `ExactSizeIterator`, `FusedIterator`

## dims

Adapt this iterator to yield only dimension proxies, discarding positions.

```rust
pub fn dims(self) -> TensorViewDims<'a, Scalar, MAX_RANK>
```

## Vector

Owning, non-resizable, SIMD-aligned vector.

```rust
pub struct Vector<Scalar: StorageElement, Alloc: Allocator = Global>
```

Size is fixed at construction. Uses [`StorageElement`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#StorageElement) for element types, including sub-byte
packed types via `Scalar::dimensions_per_value()`.

Read and write dimensions with [`get`](#get)/[`set`](#set), which return errors rather than panic, or iterators.

Implements: `Send`, `Sync`, `Drop`, `Default`, `[Fill](#Fill)<Scalar>`, `[CopyFrom](#CopyFrom)<&[Scalar]>`, `IntoIterator`, `AsRef<[Scalar]>`, `PartialEq`, `PartialEq<[<Scalar as [FloatConvertible](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#FloatConvertible)>::DimScalar]>`, `Debug`, `Display`

## from_raw_parts_in

Construct a vector from raw parts, taking ownership of the allocation.

```rust
pub unsafe fn from_raw_parts_in(data: NonNull<Scalar>, dims: usize, alloc: Alloc) -> Self
```

Safety: - `data` must point to an allocation obtained from `alloc`, aligned to
[`crate::DEFAULT_ALIGNMENT`](https://www.unum.cloud/docs/numkong/rust/external-memory.md#DEFAULT_ALIGNMENT), whose backing buffer is sized for the storage count
implied by [`dims`](#dims) (`Scalar::dimensions_to_values(dims)` slots of [`Scalar`](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#Scalar)).

- The caller must not free the memory — this vector takes ownership.

## empty_in

An empty vector that owns no allocation, holding only the given allocator.

```rust
pub fn empty_in(alloc: Alloc) -> Self
```

Cannot fail, because nothing is allocated until the first [`reserve`](https://www.unum.cloud/docs/numkong/rust/maxsim.md#reserve)
or [`resize`](#resize).

## zeros_in

Create a zero-initialized vector with the given number of dimensions.

```rust
pub fn zeros_in(dims: usize, alloc: Alloc) -> Result<Self, Error>
```

## full_in

Create a vector filled with `value`.

```rust
pub fn full_in(dims: usize, value: Scalar, alloc: Alloc) -> Result<Self, Error>
```

## ones_in

Create a vector filled with ones.

```rust
pub fn ones_in(dims: usize, alloc: Alloc) -> Result<Self, Error>
where
    Scalar: NumberLike,
```

## uninitialized_in

Create an uninitialized vector.

```rust
pub unsafe fn uninitialized_in(dims: usize, alloc: Alloc) -> Result<Self, Error>
```

Safety: The returned vector's contents are uninitialized. Reading from it before writing is
undefined behavior.

## from_scalars_in

Create a vector from a slice of scalars — f32 values.

```rust
pub fn from_scalars_in(scalars: &[f32], alloc: Alloc) -> Result<Self, Error>
where
    Scalar: FloatConvertible,
```

Each f32 value is converted through `DimScalar::from_f32()` before storage.

## from_dims_in

Create a vector from a slice of per-dimension scalars.

```rust
pub fn from_dims_in(dim_values: &[Scalar::DimScalar], alloc: Alloc) -> Result<Self, Error>
where
    Scalar: FloatConvertible,
```

Each element in `dim_values` corresponds to one logical dimension.

## *

Number of logical dimensions.

```rust
pub fn dims(&self) -> usize
```

## size

Number of logical dimensions; same as `dims()`.

```rust
pub fn size(&self) -> usize
```

## size_values

Number of underlying storage values ([`Scalar`](https://www.unum.cloud/docs/numkong/rust/elementwise-and-reductions.md#Scalar) instances).

```rust
pub fn size_values(&self) -> usize
```

## is_empty

Returns true if the vector has zero dimensions.

```rust
pub fn is_empty(&self) -> bool
```

## resize

Resize in place to `new_dims` dimensions without moving storage.

```rust
pub fn resize(&mut self, new_dims: usize) -> Result<(), Error>
```

Succeeds only when the packed storage fits `capacity()`, so `as_ptr()` stays stable — call
[`reserve`](https://www.unum.cloud/docs/numkong/rust/maxsim.md#reserve) first to grow. Returns [`Error::CapacityExceeded`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#CapacityExceeded) otherwise,
leaving the vector unchanged.

Examples: ```
let mut v = Vector::&#x3C;f32>::zeros(8)?; // capacity 8
v.resize(3)?;                         // shrink within capacity; as_ptr() unchanged
assert!(v.resize(9).is_err());        // beyond capacity
```

## reserve

Grow the allocated `capacity()` to hold at least `new_dims` dimensions, reallocating and copying the live elements if needed.

```rust
pub fn reserve(&mut self, new_dims: usize) -> Result<(), Error>
```

A no-op when already large enough. Unlike
[`resize`](#resize) it may move storage, invalidating any raw pointer captured outside
the borrow system. Returns [`Error::AllocationFailed`](https://www.unum.cloud/docs/numkong/rust/quickstart.md#AllocationFailed) on failure, unchanged.

## clear

Reset to an empty vector (`dims() == 0`) while keeping the allocated `capacity()`.

```rust
pub fn clear(&mut self)
```

## as_ptr

Raw pointer to the underlying data.

```rust
pub fn as_ptr(&self) -> *const Scalar
```

## as_mut_ptr

Mutable raw pointer to the underlying data.

```rust
pub fn as_mut_ptr(&mut self) -> *mut Scalar
```

## size_bytes

Size in bytes.

```rust
pub fn size_bytes(&self) -> usize
```

## view

Create an immutable view of this vector.

```rust
pub fn view(&self) -> VectorView<'_, Scalar, Alloc>
```

## span

Create a mutable span of this vector.

```rust
pub fn span(&mut self) -> VectorSpan<'_, Scalar, Alloc>
```

## get

Get the logical dimension at [`index`](#index); supports signed indexing.

```rust
pub fn get<AnyIndex: VectorIndex>(&self, index: AnyIndex) -> Result<Scalar::DimScalar, Error>
where
    Scalar: FloatConvertible,
```

Returns the native [`DimScalar`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#DimScalar) type, e.g. `f64` for `Vector<f64>` or `i8` for
`Vector<i4x2>`. For sub-byte types, unpacks the appropriate sub-dimension from the packed
storage value.

Examples: Positive and Python-style negative indexing:

```
use numkong::vector::Vector;
let v = Vector::&#x3C;f32>::from_dims(&#x26;[10.0, 20.0, 30.0, 40.0, 50.0]).unwrap();
assert_eq!(v.get(0_usize).unwrap(), 10.0);
assert_eq!(v.get(-1_i32).unwrap(), 50.0);
assert_eq!(v.get(-5_i32).unwrap(), 10.0);
// Out-of-range indices return an error instead of panicking.
assert!(v.get(5_usize).is_err());
assert!(v.get(-6_i32).is_err());
```

## set

Set the logical dimension at [`index`](#index).

```rust
pub fn set<AnyIndex: VectorIndex>(
    &mut self,
    index: AnyIndex,
    value: Scalar::DimScalar,
) -> Result<(), Error>
where
    Scalar: FloatConvertible,
```

Accepts the native [`DimScalar`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#DimScalar) type. For sub-byte types, reads the current packed value,
updates the targeted sub-dimension, and writes back the modified packed value.

Examples: ```
use numkong::vector::Vector;
let mut v = Vector::&#x3C;f32>::zeros(4).unwrap();
v.set(0_usize, 1.0).unwrap();
// Signed indices let you write to the tail without computing the length.
v.set(-1_i32, 4.0).unwrap();
assert_eq!(v.get(0_usize).unwrap(), 1.0);
assert_eq!(v.get(3_usize).unwrap(), 4.0);
```

## as_slice

Get a slice of the underlying storage values.

```rust
pub fn as_slice(&self) -> &[Scalar]
```

For sub-byte types this returns the packed
storage values, not the logical dimensions.

## as_mut_slice

Get a mutable slice of the underlying storage values.

```rust
pub fn as_mut_slice(&mut self) -> &mut [Scalar]
```

## iter

Returns an iterator over the logical dimension values, yielding [`DimRef`](#DimRef) proxies.

```rust
pub fn iter(&self) -> VectorViewIterator<'_, Scalar>
where
    Scalar: FloatConvertible,
```

## iter_mut

Returns a mutable iterator over the logical dimension values, yielding [`DimMut`](#DimMut) proxies.

```rust
pub fn iter_mut(&mut self) -> VectorSpanIterator<'_, Scalar>
where
    Scalar: FloatConvertible,
```

## into_tensor

Convert this vector into a 1D tensor, transferring ownership without copying.

```rust
pub fn into_tensor<const MAX_RANK: usize>(self) -> Result<Tensor<Scalar, Alloc, MAX_RANK>, Error>
```

## zeros

Create a zero-initialized vector with the global allocator.

```rust
pub fn zeros(dims: usize) -> Result<Self, Error>
```

## full

Create a vector filled with `value`.

```rust
pub fn full(dims: usize, value: Scalar) -> Result<Self, Error>
```

## ones

Create a vector filled with ones.

```rust
pub fn ones(dims: usize) -> Result<Self, Error>
where
    Scalar: NumberLike,
```

## uninitialized

Create an uninitialized vector.

```rust
pub unsafe fn uninitialized(dims: usize) -> Result<Self, Error>
```

Safety: The returned vector's contents are uninitialized. Reading from it before writing is
undefined behavior.

## from_scalars

Create a vector from scalar f32 values.

```rust
pub fn from_scalars(scalars: &[f32]) -> Result<Self, Error>
where
    Scalar: FloatConvertible,
```

## from_dims

Create a vector from per-dimension scalars.

```rust
pub fn from_dims(dims: &[Scalar::DimScalar]) -> Result<Self, Error>
where
    Scalar: FloatConvertible,
```

## clone

Clone this vector, returning an error on allocation failure.

```rust
pub fn clone(&self) -> Result<Self, Error>
```

## popcount

Number of set bits across the entire vector.

```rust
pub fn popcount(&self) -> Result<u64, Error>
```

## any_set

`true` if at least one bit in the vector is set.

```rust
pub fn any_set(&self) -> Result<bool, Error>
```

## none_set

`true` if no bit in the vector is set.

```rust
pub fn none_set(&self) -> Result<bool, Error>
```

## all_set

`true` if every bit in the vector is set.

```rust
pub fn all_set(&self) -> Result<bool, Error>
```

## *

Check if all elements are within tolerance of `other`.

```rust
pub fn allclose<OtherAlloc: Allocator>(
    &self,
    other: &Vector<Scalar, OtherAlloc>,
    atol: f64,
    rtol: f64,
) -> bool
```

Returns `false` if dimensions differ; otherwise checks the formula |a − b| ≤ atol + rtol ×
|b| per element.

## VectorIndex

Trait for vector index types.

```rust
pub trait VectorIndex: Sealed + Copy
```

Supports signed integers; negative counts from the end.

Implementors: - `impl [VectorIndex](#VectorIndex) for usize`
- `impl [VectorIndex](#VectorIndex) for u8`
- `impl [VectorIndex](#VectorIndex) for u16`
- `impl [VectorIndex](#VectorIndex) for u32`
- `impl [VectorIndex](#VectorIndex) for u64`
- `impl [VectorIndex](#VectorIndex) for isize`
- `impl [VectorIndex](#VectorIndex) for i8`
- `impl [VectorIndex](#VectorIndex) for i16`
- `impl [VectorIndex](#VectorIndex) for i32`
- `impl [VectorIndex](#VectorIndex) for i64`

## resolve

Resolve this index to a `usize` offset, or `None` if out of bounds.

```rust
fn resolve(self, len: usize) -> Option<usize>
```

## VectorSpan

Mutable, possibly strided, non-owning view into a vector.

```rust
pub struct VectorSpan<'a, Scalar: StorageElement, Alloc = Global>
```

[`VectorSpan`](#VectorSpan) is the read-write counterpart of [[`VectorView`](#VectorView)]: it still performs zero-copy
borrowing via a raw pointer, dimension count, and byte stride, but additionally allows element
writes through [`set`](#set), [`fill`](#fill), and [`iter_mut`](#iter_mut). Spans are typically obtained via
[`Vector::span`](#span) or a mutable slice of a tensor row.

Like views, spans support signed [`VectorIndex`](#VectorIndex) indexing, negative strides via
[`VectorSpan::as_view`](#as_view) + [`VectorView::rev`](#rev), and Python-style slicing through their view
projection. The `'a` lifetime mirrors the owner of the underlying memory, and Rust's borrow
checker prevents aliasing a single span with any other reference for the duration of `'a`.

Implements: `Send`, `Sync`, `[Fill](#Fill)<Scalar>`, `[CopyFrom](#CopyFrom)<&'b [VectorView](#VectorView)<'_, Scalar, SourceAlloc>>`, `IntoIterator`, `PartialEq`, `Debug`

## from_raw_parts

Create a mutable view from a raw pointer, dimension count, and byte stride, reporting [`Global`](https://www.unum.cloud/docs/numkong/rust/external-memory.md#Global) as its allocator.

```rust
pub unsafe fn from_raw_parts(data: *mut Scalar, dims: usize, stride: isize) -> Self
```

Safety: - `data` must be valid for reads and writes of [`dims`](#dims) elements at the given stride.

- The pointed-to memory must outlive `'a`.

- `stride` must be non-zero for non-empty views.

- No other references to the memory may exist for the duration of `'a`.

## from_raw_parts_in

Like [`VectorSpan::from_raw_parts`](#from_raw_parts), reporting [`allocator`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#allocator) as the span's allocator.

```rust
pub unsafe fn from_raw_parts_in(
    data: *mut Scalar,
    dims: usize,
    stride: isize,
    allocator: &'a Alloc,
) -> Self
```

Safety: The same as for [`VectorSpan::from_raw_parts`](#from_raw_parts).

## allocator

The allocator of the vector this span borrows, or [`Global`](https://www.unum.cloud/docs/numkong/rust/external-memory.md#Global) for foreign memory.

```rust
pub fn allocator(&self) -> &'a Alloc
```

## *

Number of logical dimensions; alias for dims.

```rust
pub fn size(&self) -> usize
```

## is_*

Returns true if empty.

```rust
pub fn is_empty(&self) -> bool
```

- `is_empty`
- `is_contiguous`
- `is_empty`

## stride_bytes

Stride in bytes.

```rust
pub fn stride_bytes(&self) -> isize
```

## as_*_ptr

Get the underlying pointer.

```rust
pub fn as__ptr(&self) -> *const Scalar
```

## as_mut_ptr

Get the mutable underlying pointer.

```rust
pub fn as_mut_ptr(&mut self) -> *mut Scalar
```

## as_view

Reborrow as an immutable view, sharing the same data pointer and stride.

```rust
pub fn as_view(&self) -> VectorView<'_, Scalar, Alloc>
```

## get

Get element at index.

```rust
pub fn get<AnyIndex: VectorIndex>(&self, index: AnyIndex) -> Result<Scalar::DimScalar, Error>
where
    Scalar: FloatConvertible,
```

## set

Set the element at [`index`](#index).

```rust
pub fn set<AnyIndex: VectorIndex>(
    &mut self,
    index: AnyIndex,
    value: Scalar::DimScalar,
) -> Result<(), Error>
where
    Scalar: FloatConvertible,
```

Accepts the native [`DimScalar`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#DimScalar) type. For sub-byte types, uses value_index for stride-based
pointer walks to avoid buffer overwrite.

## as_contiguous_slice

Get a contiguous slice, if this span is contiguous.

```rust
pub fn as_contiguous_slice(&self) -> Option<&[Scalar]>
```

## as_contiguous_slice_mut

Get a mutable contiguous slice, if this span is contiguous.

```rust
pub fn as_contiguous_slice_mut(&mut self) -> Option<&mut [Scalar]>
```

## *

Returns an iterator over logical dimension values, yielding [`DimRef`](#DimRef) proxies.

```rust
pub fn iter(&self) -> VectorViewIterator<'_, Scalar>
where
    Scalar: FloatConvertible,
```

## iter_mut

Returns a mutable iterator over logical dimension values, yielding [`DimMut`](#DimMut) proxies.

```rust
pub fn iter_mut(&mut self) -> VectorSpanIterator<'_, Scalar>
where
    Scalar: FloatConvertible,
```

## popcount

Number of set bits across the entire vector span.

```rust
pub fn popcount(&self) -> Result<u64, Error>
```

## any_set

`true` if at least one bit in the vector span is set.

```rust
pub fn any_set(&self) -> Result<bool, Error>
```

## none_set

`true` if no bit in the vector span is set.

```rust
pub fn none_set(&self) -> Result<bool, Error>
```

## all_set

`true` if every bit in the vector span is set.

```rust
pub fn all_set(&self) -> Result<bool, Error>
```

## VectorSpanIterator

Stride-aware mutable iterator over logical dimensions, yielding [`DimMut`](#DimMut) proxies.

```rust
pub struct VectorSpanIterator<'a, Scalar: FloatConvertible>
```

For normal types (`dimensions_per_value=1`), yields one proxy per storage value.
For sub-byte types, each proxy performs a read-modify-write on drop.
Implements `ExactSizeIterator`, `FusedIterator`, and `DoubleEndedIterator`.

Implements: `Iterator`, `ExactSizeIterator`, `FusedIterator`, `DoubleEndedIterator`

## VectorView

Immutable, possibly strided, non-owning view into a vector.

```rust
pub struct VectorView<'a, Scalar: StorageElement, Alloc = Global>
```

[`VectorView`](#VectorView) is a zero-copy borrow: it holds a raw pointer, a dimension count, and a byte stride
between consecutive logical elements. It never frees its memory and is tied to the lifetime `'a`
of whatever owns the storage — typically a [`Vector`](#Vector) obtained via [`Vector::view`](#view), or a row /
column of a tensor.

Because the stride is stored in bytes and may be negative, views can walk memory in either
direction, skip entries via [`VectorView::strided`](#strided), or expose a reversed iteration order
via [`VectorView::rev`](#rev).

Use [`VectorView`](#VectorView) when only read access is needed. Its mutable counterpart is [`VectorSpan`](#VectorSpan),
which offers the same striding semantics plus element writes. Both types support the
[`VectorIndex`](#VectorIndex) trait, so `view.get(0_usize)`, `view.get(-1_i32)`, and friends all resolve via
the same Python-style rules.

Implements: `Send`, `Sync`, `Clone`, `Copy`, `[CopyFrom](#CopyFrom)<&'b [VectorView](#VectorView)<'_, Scalar, SourceAlloc>>`, `IntoIterator`, `PartialEq`, `Debug`

## from_raw_parts

Create a view from a raw pointer, dimension count, and byte stride, reporting [`Global`](https://www.unum.cloud/docs/numkong/rust/external-memory.md#Global) as its allocator.

```rust
pub unsafe fn from_raw_parts(data: *const Scalar, dims: usize, stride: isize) -> Self
```

Safety: - `data` must be valid for reads of [`dims`](#dims) elements at the given stride.

- The pointed-to memory must outlive `'a`.

- `stride` must be non-zero for non-empty views.

## from_raw_parts_in

Like [`VectorView::from_raw_parts`](#from_raw_parts), reporting [`allocator`](https://www.unum.cloud/docs/numkong/rust/mesh-alignment.md#allocator) as the view's allocator.

```rust
pub unsafe fn from_raw_parts_in(
    data: *const Scalar,
    dims: usize,
    stride: isize,
    allocator: &'a Alloc,
) -> Self
```

Safety: The same as for [`VectorView::from_raw_parts`](#from_raw_parts).

## allocator

The allocator of the vector this view borrows, or [`Global`](https://www.unum.cloud/docs/numkong/rust/external-memory.md#Global) for foreign memory.

```rust
pub fn allocator(&self) -> &'a Alloc
```

## stride_bytes

Stride in bytes between consecutive elements.

```rust
pub fn stride_bytes(&self) -> isize
```

## is_contiguous

Returns true if elements are stored contiguously (stride == sizeof(Scalar)).

```rust
pub fn is_contiguous(&self) -> bool
```

## as_contiguous_slice

Get a contiguous slice, if this view is contiguous.

```rust
pub fn as_contiguous_slice(&self) -> Option<&'a [Scalar]>
```

## get

Get element at index; supports signed indexing.

```rust
pub fn get<AnyIndex: VectorIndex>(&self, index: AnyIndex) -> Result<Scalar::DimScalar, Error>
where
    Scalar: FloatConvertible,
```

Returns the native [`DimScalar`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#DimScalar) type. For sub-byte types, uses value_index for stride-based
pointer walks to avoid buffer overread.

## rev

Create a reversed view by negating the stride and pointing to the last element.

```rust
pub fn rev(&self) -> Self
```

The returned view has the same number of dimensions but iterates in the opposite direction.
For an empty view, returns a copy unchanged.

## strided

Create a sub-view with start, end, and step — Python-style slicing.

```rust
pub fn strided(&self, start: usize, end: usize, step: isize) -> Result<Self, Error>
```

Supports negative steps for reverse iteration. `step` must be non-zero.
Returns an error if `start` or `end` exceed `dims()`, or if `step == 0`.

## popcount

Number of set bits across the entire vector view.

```rust
pub fn popcount(&self) -> Result<u64, Error>
```

## any_set

`true` if at least one bit in the vector view is set.

```rust
pub fn any_set(&self) -> Result<bool, Error>
```

## none_set

`true` if no bit in the vector view is set.

```rust
pub fn none_set(&self) -> Result<bool, Error>
```

## all_set

`true` if every bit in the vector view is set.

```rust
pub fn all_set(&self) -> Result<bool, Error>
```

## VectorViewIterator

Stride-aware immutable iterator over logical dimensions, yielding [`DimRef`](#DimRef) proxies.

```rust
pub struct VectorViewIterator<'a, Scalar: FloatConvertible>
```

For normal types (`dimensions_per_value=1`), yields one proxy per storage value.
For sub-byte types, unpacks each storage value and yields sub-dimensions individually.
Implements `ExactSizeIterator`, `FusedIterator`, and `DoubleEndedIterator`.

Implements: `Iterator`, `ExactSizeIterator`, `FusedIterator`, `DoubleEndedIterator`

## DimLocation

Where one logical dimension lives inside packed storage.

```rust
pub struct DimLocation
```

Produced by [`StorageElement::locate_dim`](https://www.unum.cloud/docs/numkong/rust/scalar-types.md#locate_dim). For the full-byte types both fields degenerate —
`value_index` is the dimension index and `sub_index` is always zero — so code written against
this stays correct for every scalar without branching on the packing factor.

- `value_index` `usize`: Index of the storage value holding the dimension.
- `sub_index` `usize`: Position of the dimension within that storage value.

Implements: `Debug`, `Clone`, `Copy`, `StructuralPartialEq`, `PartialEq`, `Eq`

## read_from

Read this dimension out of the storage value at `slot`.

```rust
pub unsafe fn read_from<Scalar: FloatConvertible>(self, slot: *const Scalar) -> Scalar::DimScalar
```

Safety: `slot` must point at the storage value this location addresses — for a contiguous buffer
that is `base.add(self.value_index)`, and for a strided one the corresponding stride step.

## write_into

Write `value` into this dimension, leaving the others sharing the storage value untouched.

```rust
pub unsafe fn write_into<Scalar: FloatConvertible>(
    self,
    slot: *mut Scalar,
    value: Scalar::DimScalar,
)
```

Sub-byte dimensions cannot be addressed individually, so a write is a read-modify-write of
the whole storage value. Doing it here rather than at each call site is what keeps a caller
from clobbering the neighbours that share the byte.

Safety: `slot` must point at the storage value this location addresses, and be writable.

## BitRef

Immutable reference to a single bit within a packed byte.

```rust
pub struct BitRef<'a>
```

Obtained by iterating over or indexing into a `Vector<u1x8>`. The `mask` selects which of the
eight bits the proxy represents; the byte itself is shared with the seven sibling proxies for
the same byte.

Examples: ```
use numkong::vector::Vector;
use numkong::types::u1x8;
let mut v = Vector::&#x3C;u1x8>::zeros(8).unwrap();
v.set(3_usize, 1).unwrap();
// Immutable iteration yields BitRef-like proxies that deref to the bit value.
let bits: Vec&#x3C;u8> = v.iter().map(|b| *b).collect();
assert_eq!(bits, vec![0, 0, 0, 1, 0, 0, 0, 0]);
```

## *

Read the bit as bool.

```rust
pub fn get(&self) -> bool
```

## BitRefMut

Mutable reference to a single bit within a packed byte.

```rust
pub struct BitRefMut<'a>
```

Obtained via mutable iteration / indexing of a `Vector<u1x8>`. Writes OR or AND the stored byte
so sibling bits are preserved; the `mask` selects which bit this proxy represents.

Examples: ```
use numkong::vector::Vector;
use numkong::types::u1x8;
let mut v = Vector::&#x3C;u1x8>::zeros(8).unwrap();
for (i, mut bit) in v.iter_mut().enumerate() {
    *bit = (i % 2 == 0) as u8;
}
assert_eq!(v.get(0_usize).unwrap(), 1);
assert_eq!(v.get(1_usize).unwrap(), 0);
```

## set

Set the bit.

```rust
pub fn set(&self, value: bool)
```

## DEFAULT_MAX_RANK

Default maximum rank for tensors.

```rust
pub const DEFAULT_MAX_RANK: usize = 8;
```

