Quiver 1.6.0 · Apache 2.0

Quiver

A Swift package for statistics, linear algebra and machine learning.

let position = [3.0, 4.0]position.magnitude // 5.0
How it works

It’s just an Array.

Quiver adds numerical methods directly to Swift’s standard Array through extensions. A plain [Double] gains the math without becoming a different type, so it still flows straight into SwiftUI, Swift Charts and SwiftData.

The compiler knows what fits.

Swift’s type system validates math at compile time. Constrained extensions expose operations only on compatible types, while [Double] and [[Double]] define vectors and matrices as plain arrays, with dimensions checked when the code runs.

Quiver Notebook

Write it. Run it.
Ship it.

A browser-based Swift IDE for testing and evaluating Quiver models before they move into an app. Quiver and Foundation are already imported, teaching datasets are bundled, and documentation appears inline for every symbol.

localhost:8080
QuiverNotebook
Swift · Ready
▶  Run
Examples ›Cosine Similarity
OUTPUT
Running locally on Quiver 1.6.0. No code is sent to the cloud.Line 1, Col 1

Bundled datasets

Iris, Titanic, California housing, GloVe word vectors and more, each loading by name in one line. toPanel() hands back a table of named columns.

Documentation inline

Hover any Quiver symbol for its signature and summary, pulled from the same documentation that ships with the package. Autocomplete and signature help fill in the rest.

Stays on the Mac

The server answers on 127.0.0.1 with a per-launch key. No accounts, no telemetry, no analytics.

From the Notebook to Xcode

Prototype here.
Ship it there.

Code written in the Notebook is ordinary Swift. Copy it into an Xcode project, add Quiver as a package dependency, and it compiles unchanged for iPhone, Apple Watch, Vision Pro or the Mac.

Models we can read, trained where the data lives.

A model fits inside the app from data the device already collects, such as motion, location, HealthKit samples and workouts. Every model exposes what it learned as plain Swift values: coefficients with standard errors and p-values, cluster centroids, principal components. The same code runs on Apple Watch, iPhone, the Mac and Linux.

Same package, same release.

The Notebook builds every snippet against the published Quiver package, pinned to the release shown in its footer. Code that compiles in the Notebook compiles in Xcode against that same release.

The datasets stay in the Notebook.

The teaching datasets are part of the Notebook, not the Quiver package, so the package an app ships stays small with zero dependencies. toPanel() hands back a Quiver Panel, so every line after the load is plain Quiver.

One model, end to end.

The True Effort Score model learns each runner's baseline from their own recent runs. It measures heart rate, pace, cadence, grade, altitude and vertical oscillation during a run and scores the effort on Apple Watch.

Models

Models are always ready.

For models created with fit, there is no empty or unfitted state. The fit method returns a trained model, so calling predict on an untrained model cannot compile.

Trained on creation

fit returns a trained model.

No runtime error for “model not fitted”. The situation cannot arise.

let model = KNearestNeighbors.fit(
    features: trainingData, labels: labels, k: 3)
let predictions = model.predict(newData)
Immutable

Learned parameters never drift.

Coefficients, centroids and learned parameters cannot change once a fitted model exists. A whole category of accidental-retraining bugs disappears.

Codable

Train once, ship it.

Every stored property is a basic Swift type, so models encode to JSON with no extra code. Save one to disk and load it on the next launch without retraining.

Failure in the return type

The signature says how much care a fit needs.

try LinearRegression.fit(...)    // can fail
KNearestNeighbors.fit(...)       // cannot fail
[Double].polyfit(...)            // nil on failure

Regression Regressor

LinearRegression
Ordinary least squares, with a full summary of coefficients, standard errors and confidence intervals.
Ridge
Linear regression with an L2 penalty that keeps correlated features in check.
GradientDescent
Fits a linear model iteratively, one step down the loss at a time.
Polynomial
Curve fitting with polyfit, plus analytic derivatives.

Classification Classifier

LogisticRegression
Predicts class probabilities through the logistic function.
GaussianNaiveBayes
A probabilistic classifier built on per-class feature statistics.
KNearestNeighbors
Labels a point by the vote of its closest training examples.

Unsupervised

KMeans
Groups unlabeled points into k clusters, reproducible with a seed.
PCA
Reduces dimensions along the directions of greatest variance.

Workflow

StandardScaler · Pipeline
Standardize features and chain preprocessing with a model.
ResidualModel
Wraps any regressor and reports the gap between prediction and observation.
ConfusionMatrix · ClassificationReport
Evaluation that prints as a readable report.

Models share their prediction interface through two protocols. Code written against Regressor accepts LinearRegression, Ridge and GradientDescent interchangeably, and code written against Classifier does the same for every classifier.

Clean output by default

Print anything.
Read it at a glance.

Every model and result type prints a readable summary. Vectors and matrices render in textbook form, and the underlying values are never touched.

print(v.asFractions().asExpression())
⎡ 3/5 ⎤ ⎢ 3/4 ⎥ ⎣ 1/2 ⎦
print(features.asExpression())
⎡ 720 15000 ⎤ ⎢ 650 78000 ⎥ ⎢ 580 42000 ⎥ ⎣ 710 8000 ⎦
print(p)
2x² + 3x + 1
print(f)
3/5
print(cm)
TP: 3 FP: 1 TN: 3 FN: 1 (accuracy: 75.0%)
print(model)
KNearestNeighbors: k=3, euclidean, 6 training points, 2 features
print(results)
KMeans: 2 clusters, 4 points, converged in 2 iterations (inertia: 0.77)
Concurrency

Train off the main thread.

Fitted models in Quiver are Sendable. A fitted model is an immutable value, so it crosses task boundaries with nothing to lock and nothing to coordinate.

Long fits stay off the interface.

Run a fit on a detached task and await the trained model back. The interface keeps drawing while training runs.

Predict from many tasks at once.

Prediction is a pure read against immutable parameters, so any number of concurrent tasks can call predict without serialization.

Divide the work across cores.

Pairwise comparisons and other heavy operations split cleanly with withTaskGroup, and the results update SwiftUI when training completes.

Worked examples

From a document to an answer.

Retrieval-augmented context, commonly known as RAG, in six steps. Quiver handles the search so the app can decide what to do with what it finds.

    Retrieving Context for Generation

    Quiver returns a String and stops. The same context block feeds an on-device model on a phone, a hosted model behind an API, or a model running on a server.

    Server-side Swift

    On the server, too.

    Quiver has zero dependencies, so the search code that runs on an iPhone runs inside a Vapor app unchanged. The [Double] Vapor decodes from JSON is the same [Double] Quiver computes on, with no subprocess and no second runtime.

    Vapor + Quiver · a complete semantic search server

    Vector search in Swift

    This example ranks a small dictionary. For a catalog that grows, EmbeddingIndex stores each vector beside its label, ranks a query against all of them by cosine similarity, and saves as a Codable snapshot. Those are the core operations behind vector search, written in Swift.

    Swap the vectors, keep the ranking

    Here both tables are made by hand. A sentence model, plugged in through Quiver’s Embedder protocol, would produce the vectors instead, and the ranking with nearest(to:k:) stays the same.

    The retrieval half of RAG

    A /search route is retrieval. Feed its results to a language model as context and the server has a full RAG pipeline, with Quiver handling the search.

    Built on the CPU

    Quiver runs on the CPU with plain Swift arrays and no dependencies, so the same code runs unchanged on Apple Watch, iPhone and the Mac. Swift concurrency lets us move heavy work off the main thread and divide it across cores.

    Learn

    Learn machine learning in Swift.

    One of Quiver’s goals is to grow machine learning education on Swift. The math stays visible at every step, models expose what they learned, and a classroom needs nothing more than a Mac and the Notebook.

    Notebook › Examples › The Central Limit Theorem in Action

    See the theorem in action.

    Start with a skewed population, draw a thousand small samples from it, and bin their means. The underlying data is nowhere near normal, but the sample means assemble into a classic bell curve. With a fixed seed, every student in the room produces the exact same histogram on their first run.

    Population, 10,000 values mean 2.030 · std 2.050

    1. 2.078732
    2. 6.201073
    3. 10.34171
    4. 14.4822
    5. 18.612

    1,000 sample means, n = 50 mean 2.045 · std 0.294

    1. 1.3436
    2. 1.76369
    3. 2.18470
    4. 2.60120
    5. 3.025

    The sample means center on the population mean, and their spread of 0.294 is the standard error.

    Built to teach. Built to ship.

    Students

    The math runs on Swift arrays and every model exposes its learned parameters so the models are never a black box.

    Educators

    Fork the Notebook, drop examples into examples-custom/ and switch to Presenter mode. Each clone is pinned to one Quiver release for the whole semester.

    Get started

    Create something new.

    The documentation includes nearly 70 articles covering concepts, data preparation, training and implementation. Results are tested against established reference implementations.

    Add the package

    Swift Package Manager.

    dependencies: [ .package(url: "https://github.com/waynewbishop/quiver", from: "1.6.0") ]

    Run the Notebook

    macOS 15 or newer with Swift 6. Then open localhost:8080.

    git clone https://github.com/waynewbishop/quiver-notebook cd quiver-notebook swift run