UMAP for .NET
A fast, multi-threaded C# implementation of Uniform Manifold Approximation and Projection — reduce high-dimensional vectors to 2D or 3D embeddings for visualisation, clustering, and exploration.
What is UMAP-Sharp?
UMAP-Sharp is a high-performance C# implementation of Uniform Manifold Approximation and Projection, a non-linear dimension reduction algorithm. It is a faithful port of the JavaScript version, which is itself based on the original Python reference implementation.
If you have a set of vectors that represent documents, images, words, or other entities — typically produced by an embedding model — UMAP can reduce those vectors to two or three dimensions so you can plot them, explore clusters, and reason about the structure of your data.
Key features
- Pure C# — no native dependencies, runs anywhere .NET runs (Windows, Linux, macOS, ARM).
- Multi-target — supports
netstandard2.0,netstandard2.1,net7.0,net8.0,net9.0, andnet10.0. - SIMD-accelerated distance and arithmetic kernels.
- Lock-free multi-threaded optimization modelled after Facebook's fastText — uses every available core by default.
- Pluggable distance functions — Cosine, Cosine-for-normalized-vectors, Euclidean, or supply your own delegate.
- Pluggable randomness — pass a deterministic generator for reproducible results, or the default thread-safe fast random for production runs.
- Progress reporting — get a
0.0 → 1.0callback throughoutInitializeFitandStep.
How it works in C#
UMAP-Sharp has one main type, Umap, and three methods you will call. Pass a float[][] of vectors (every row must be the same length), call InitializeFit to compute the fuzzy simplicial set, run the recommended number of Step iterations, then read the projected embedding:
using UMAP;
// Your input vectors — every nested array must have the same length
float[][] vectors = LoadVectors();
// Default configuration: cosine distance, 2-D embedding, 15 neighbors
var umap = new Umap();
// Compute the fuzzy simplicial set and return the recommended number of epochs
var epochs = umap.InitializeFit(vectors);
// Run the stochastic gradient descent
for (var i = 0; i < epochs; i++)
{
umap.Step();
}
// Result: float[N][2], in the same order as the input
float[][] embedding = umap.GetEmbedding();
That's the whole API in one snippet. The rest of this documentation explains the configuration knobs, the distance functions, parallelization, reproducibility, and a complete MNIST example.
Documentation map
Project links
- NuGet — nuget.org/packages/UMAP
- Source — github.com/curiosity-ai/umap-sharp
- License — MIT
- Reference papers — McInnes, Healy & Melville, 2018