# Tensors and Views

> NumKong for Swift

`Tensor<T>` is the owning two-dimensional type.
It allocates its own buffer, handles deallocation on `deinit`, and produces non-owning views and spans without nesting `withUnsafeBufferPointer` closures.

```swift
import NumKong

// From an existing array:
let t = try Tensor<Float32>.fromArray([1, 2, 3, 4, 5, 6], rows: 2, columns: 3)

// Zero-initialized:
let z = try Tensor<Float32>.zeros(rows: 4, columns: 768)

// Constant fill:
let c = try Tensor<Float32>.full(rows: 4, columns: 768, value: 1.0)

// Subscript access:
let v = t[0, 2] // row 0, col 2

// Row buffer access:
let row1 = t.row(1) // UnsafeBufferPointer<Float32>

// Non-owning views:
let view: MatrixView<Float32>  = t.view()  // immutable
let span: MatrixSpan<Float32>  = t.span()  // mutable
```

`Tensor<T>` is fixed-capacity resizable.
`capacity` reports the allocated element ceiling.
`tryResize(rows:columns:)` reshapes within capacity without moving storage, so an existing `view()`, `span()`, or `row()` stays valid.
`reserve(_:)` may reallocate to grow, which __invalidates__ any view, span, or row pointer obtained earlier.
`clear()` empties the tensor while keeping capacity.

The view/span split is the same aliasing discipline used throughout the binding.
`MatrixView` is non-owning and immutable.
`MatrixSpan` is non-owning and mutable.
Neither allocates.

The ownership model is explicit:

- `MatrixView<Element>` is a non-owning immutable view.
- `MatrixSpan<Element>` is a non-owning mutable view.
- `PackedMatrix<Element>` owns one internal packed buffer and deallocates it on `deinit`.
- `Tensor<Element>` owns its element storage and deallocates it on `deinit`.

`PackedMatrix` allocates its internal payload with `UnsafeMutableRawPointer.allocate(byteCount:alignment:)`.
The alignment is 64 bytes for the owned packed buffer.
That does _not_ mean your source matrix must be aligned.
Packing accepts ordinary Swift-managed buffers and handles the internal layout itself.

The Tensor API eliminates the nested closure structure required when working directly with Swift's `withUnsafeBufferPointer`.
The difference in call-site verbosity is significant for anything more than a single kernel call:

```swift
// Without Tensor — three nested closures just to call one kernel
try a.withUnsafeBufferPointer { aPtr in
    try b.withUnsafeBufferPointer { bPtr in
        try out.withUnsafeMutableBufferPointer { outPtr in
            let aView = MatrixView(baseAddress: aPtr.baseAddress!, rows: 2, columns: 3)
            let bView = MatrixView(baseAddress: bPtr.baseAddress!, rows: 2, columns: 3)
            var cSpan = MatrixSpan(baseAddress: outPtr.baseAddress!, rows: 2, columns: 2)
            let packed = try PackedMatrix<Float32>(packing: bView)
            try dotsPacked(aView, packed, &cSpan)
        }
    }
}

// With Tensor — no closures at the call site
let a = try Tensor<Float32>.fromArray([1, 2, 3, 4, 5, 6], rows: 2, columns: 3)
let b = try Tensor<Float32>.fromArray([7, 8, 9, 1, 0, 1], rows: 2, columns: 3)
let packed = try b.packForDots()
let c = try a.dotsPacked(packed) // returns Tensor<Float64>
```

`import NumKong`

## MatrixView

Non-owning, immutable view over a row-major matrix stored in contiguous memory.

```swift
struct MatrixView<Element>
```

## baseAddress

```swift
let baseAddress: UnsafePointer<Element>
```

## rows

```swift
let rows: Int
```

## columns

```swift
let columns: Int
```

## rowStrideBytes

```swift
let rowStrideBytes: Int
```

## init

```swift
init(baseAddress: UnsafePointer<Element>, rows: Int, columns: Int, rowStrideBytes: Int? = nil)
```

## MatrixSpan

Non-owning, mutable view over a row-major matrix stored in contiguous memory.

```swift
struct MatrixSpan<Element>
```

## baseAddress

```swift
let baseAddress: UnsafeMutablePointer<Element>
```

## rows

```swift
let rows: Int
```

## columns

```swift
let columns: Int
```

## rowStrideBytes

```swift
let rowStrideBytes: Int
```

## init

```swift
init(baseAddress: UnsafeMutablePointer<Element>, rows: Int, columns: Int, rowStrideBytes: Int? = nil)
```

## Tensor

Owning, row-major dense matrix that deallocates its memory on `deinit`.

```swift
final class Tensor<Element>
```

Conforms to: `Sendable`

## rows

```swift
var rows: Int { get }
```

## columns

```swift
var columns: Int { get }
```

## capacity

Allocated element capacity (>= [`count`](https://www.unum.cloud/docs/numkong/swift/runtime-dispatch.md#count)) — the ceiling [`tryResize`](#tryResize) honors.

```swift
var capacity: Int { get }
```

## count

```swift
var count: Int { get }
```

## shape

```swift
var shape: (rows: Int, columns: Int) { get }
```

## fromArray

Creates a tensor by copying elements from a flat array into owned memory.

```swift
static func fromArray(_ data: [Element], rows: Int, columns: Int) throws -> Tensor
```

## full

Creates a tensor filled with a repeating value.

```swift
static func full(rows: Int, columns: Int, value: Element) throws -> Tensor
```

## *

```swift
func view() -> MatrixView<Element>
```

- `view`
- `span`
- `subscript`
- `row`

## tryResize

Resizes within the allocated [`capacity`](#capacity) without moving storage, so existing `view()`, `span()`, and `row()` results stay valid.

```swift
@discardableResult func tryResize(rows newRows: Int, columns newColumns: Int) -> Bool
```

## reserve

Grows [`capacity`](#capacity) to at least `minimumCapacity`, reallocating and copying the live elements.

```swift
func reserve(_ minimumCapacity: Int)
```

A no-op when already large enough.

Warning: This may move storage, invalidating any outstanding `view()`, `span()`, or `row()` pointers obtained before the call.

## clear

Resets to an empty 0×0 tensor while keeping the allocated [`capacity`](#capacity).

```swift
func clear()
```

## zeros

Creates a zero-filled tensor.

```swift
static func zeros(
    rows: Int,
    columns: Int
) throws -> Tensor where Element : ExpressibleByIntegerLiteral
```

## packForDots

Packs this tensor into a kernel-optimized layout for batch dot products.

```swift
func packForDots() throws -> PackedMatrix<Element> where Element : NumKongDotsMatrixElement
```

## dotsPacked

Computes dot products between this tensor's rows and a packed matrix, owning the result.

```swift
func dotsPacked(
    _ packed: PackedMatrix<Element>
) throws -> Tensor<Element.DotsOutput> where Element : NumKongDotsMatrixElement
```

## dotsSymmetric

Computes the symmetric dot-product matrix for all row pairs, returning an owned result.

```swift
func dotsSymmetric(
    rowsBegin: Int = 0,
    rowsEnd: Int? = nil
) throws -> Tensor<Element.DotsOutput> where Element : NumKongDotsMatrixElement
```

## angularsPacked

Computes angular distances between this tensor's rows and a packed matrix.

```swift
func angularsPacked(
    _ packed: PackedMatrix<Element>
) throws -> Tensor<Element.SpatialOutput> where Element : NumKongSpatialsMatrixElement
```

## euclideansPacked

Computes Euclidean distances between this tensor's rows and a packed matrix.

```swift
func euclideansPacked(
    _ packed: PackedMatrix<Element>
) throws -> Tensor<Element.SpatialOutput> where Element : NumKongSpatialsMatrixElement
```

## angularsSymmetric

Computes the symmetric angular-distance matrix for all row pairs.

```swift
func angularsSymmetric(
    rowsBegin: Int = 0,
    rowsEnd: Int? = nil
) throws -> Tensor<Element.SpatialOutput> where Element : NumKongSpatialsMatrixElement
```

## euclideansSymmetric

Computes the symmetric Euclidean-distance matrix for all row pairs.

```swift
func euclideansSymmetric(
    rowsBegin: Int = 0,
    rowsEnd: Int? = nil
) throws -> Tensor<Element.SpatialOutput> where Element : NumKongSpatialsMatrixElement
```

## hammingsPacked

Computes Hamming distances between this tensor's rows and a packed matrix.

```swift
func hammingsPacked(
    _ packed: PackedMatrix<Element>
) throws -> Tensor<Element.HammingOutput> where Element : NumKongSetsMatrixElement
```

## hammingsSymmetric

Computes the symmetric Hamming-distance matrix for all row pairs.

```swift
func hammingsSymmetric(
    rowsBegin: Int = 0,
    rowsEnd: Int? = nil
) throws -> Tensor<Element.HammingOutput> where Element : NumKongSetsMatrixElement
```

## jaccardsPacked

Computes Jaccard distances between this tensor's rows and a packed matrix.

```swift
func jaccardsPacked(
    _ packed: PackedMatrix<Element>
) throws -> Tensor<Element.JaccardOutput> where Element : NumKongSetsMatrixElement
```

## jaccardsSymmetric

Computes the symmetric Jaccard-distance matrix for all row pairs.

```swift
func jaccardsSymmetric(
    rowsBegin: Int = 0,
    rowsEnd: Int? = nil
) throws -> Tensor<Element.JaccardOutput> where Element : NumKongSetsMatrixElement
```

## maxSimPack

Packs this tensor into a MaxSim-optimized layout for late-interaction scoring.

```swift
func maxSimPack() throws -> MaxSimPackedMatrix<Element> where Element : NumKongMaxSimElement
```

## RandomAccessCollection

```swift
extension RandomAccessCollection
```

## dot

Computes the SIMD-accelerated dot product with another sequence.

```swift
func dot<B>(
    _ b: B
) -> Element.DotOutput? where B : Sequence, Self.Element == B.Element, Self.Element : NumKongDot
```

## angular

Computes the SIMD-accelerated angular, or cosine, distance to another sequence.

```swift
func angular<B>(
    _ b: B
) -> Element.AngularOutput? where B : Sequence, Self.Element == B.Element, Self.Element : NumKongAngular
```

## euclidean

Computes the SIMD-accelerated Euclidean distance to another sequence.

```swift
func euclidean<B>(
    _ b: B
) -> Element.EuclideanOutput? where B : Sequence, Self.Element == B.Element, Self.Element : NumKongEuclidean
```

## sqeuclidean

Computes the SIMD-accelerated squared Euclidean distance to another sequence.

```swift
func sqeuclidean<B>(
    _ b: B
) -> Element.SqEuclideanOutput? where B : Sequence, Self.Element == B.Element, Self.Element : NumKongSqEuclidean
```

## hamming

Computes the SIMD-accelerated Hamming distance to another sequence.

```swift
func hamming<B>(
    _ b: B
) -> Element.HammingOutput? where B : Sequence, Self.Element == B.Element, Self.Element : NumKongHamming
```

## jaccard

Computes the SIMD-accelerated Jaccard distance to another sequence.

```swift
func jaccard<B>(
    _ b: B
) -> Element.JaccardOutput? where B : Sequence, Self.Element == B.Element, Self.Element : NumKongJaccard
```

