bhtsne

Library Listed

Exact and Barnes-Hut implementations of t-SNE.

Checked · Sources

Downloads
11,593
Dependents
2
Stars
95
Forks
8
Contributors
4
Commits
107
Latest release
0.7.13 ·

About

From the project README ·

Parallel Barnes-Hut and exact implementations of the t-SNE algorithm written in Rust. The tree-accelerated version of the algorithm is described with fine detail in this paper by Laurens van der Maaten. The exact, original, version of the algorithm is described in this other paper by G. Hinton and Laurens van der Maaten. Additional implementations of the algorithm, including this one, are listed at this page.

Installation

Add this line to your Cargo.toml:

[dependencies]
bhtsne = "0.7.12"
Documentation

The API documentation is available here.

Example

The implementation supports custom data types and custom defined metrics. For instance, general vector data can be handled in the following way.

Read the full README
use bhtsne;

const N: usize = 150;         // Number of vectors to embed.
const D: usize = 4;           // The dimensionality of the
                              // original space.
const THETA: f32 = 0.5;       // Parameter used by the Barnes-Hut algorithm.
                              // Small values improve accuracy but increase complexity.

const PERPLEXITY: f32 = 10.0; // Perplexity of the conditional distribution.
const EPOCHS: usize = 2000;   // Number of fitting iterations.

// Loads the data from a csv file skipping the first row,
// treating it as headers and skipping the 5th column,
// treating it as a class label.
// Do note that you can also switch to f64s for higher precision.
let data: Vec<f32> = bhtsne::load_csv("iris.csv", true, Some(&[4]), |float| {
    float.parse().unwrap()
})?;
let samples: Vec<&[f32]> = data.chunks(D).collect();

// Executes the Barnes-Hut approximation of the algorithm and writes the embedding to the
// specified csv file.
bhtsne::tSNE::<f32, &[f32], 2>::new(&samples)
    .perplexity(PERPLEXITY)
    .epochs(EPOCHS)
    .barnes_hut(THETA, |sample_a, sample_b| {
        sample_a
            .iter()
            .zip(sample_b.iter())
            .map(|(a, b)| (a - b).powi(2))
            .sum::<f32>()
            .sqrt()
    })
    .write_csv("iris_embedding.csv")?;

In the example euclidean distance is used, but any other distance metric on data types of choice, such as strings, can be defined and plugged in.

The tree-accelerated barnes_hut and barnes_hut_with_neighbors support an embedding dimensionality D of 2, 3, 4, 5, 6, or 7, the dimensionalities a Z-order code covers with ample precision (32, 21, 16, 25, 21, and 18 bits per axis, respectively). The exact exact path stays general for any D.

The Morton (Z-order) linear tree the Barnes-Hut path walks lives in the sibling barnes-hut-tree crate, which the workspace also publishes standalone. Any other force-approximation problem that needs a Z-order linear tree in a contiguous arena can pull it in directly through its Arena, Morton, and Dim API, without depending on bhtsne.

FIt-SNE

For larger datasets the crate also provides fit_sne and fit_sne_with_neighbors, an FFT-accelerated, interpolation-based fitting path (the FIt-SNE method of Linderman et al., the same algorithm openTSNE defaults to). They build the affinity graph exactly like barnes_hut (same vantage point tree, bandwidth search, symmetrization, and affinity cache) but approximate the repulsive forces in O(n) per epoch on an equispaced grid via a real FFT convolution, with no theta knob. They drop in place of barnes_hut:

bhtsne::tSNE::<f32, &[f32], 2>::new(&samples)
    .perplexity(PERPLEXITY)
    .epochs(EPOCHS)
    .fit_sne(|sample_a, sample_b| {
        sample_a
            .iter()
            .zip(sample_b.iter())
            .map(|(a, b)| (a - b).powi(2))
            .sum::<f32>()
            .sqrt()
    })
    .write_csv("embedding.csv")?;

fit_sne is restricted to an embedding dimensionality D of 1 or 2 (where the interpolation grid stays tractable). Its per-epoch cost is nearly flat in the point count, so it matches the parallel Barnes-Hut path around 50k points and is faster beyond; roughly 1.3x at 70k points and widening.

Parallelism

Being built on rayon, the algorithm uses the same number of threads as the number of CPUs available. Do note that on systems with hyperthreading enabled this equals the number of logical cores and not the physical ones. See rayon's FAQs for additional informations.

MNIST embedding

The following embedding has been obtained by preprocessing the MNIST train set using PCA to reduce its dimensionality to 20. It took approximately 20 seconds on a M5 MacBook Pro.

mnist

Runs on
GPU support unknown
What shows it
  • no dependency or feature matches a backend row
Native code
None found
  • No native code found
Python bindings
No Python binding crate found
License
MIT

Compare with similar projects

Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days. ML Rust runs this catalogue, so its closest project always gets a row.

bhtsne beside the projects that share a topic with it
ProjectDownloadsDependentsStarsLatest releaseRuns on (GPU)Native codeLicense
bhtsne This page Listed

Exact and Barnes-Hut implementations of t-SNE.

11,593 downloads over 30 days 2 95 0.7.13 GPU support unknown No native code found MIT
augurs Listed

A time-series toolkit for forecasting, outlier detection, clustering and more.

7,507 downloads over 30 days 8 580 0.10.3 GPU support unknown No native code found Apache-2.0 OR MIT
radiate Listed

A Rust library for genetic algorithms and artificial evolution.

Python bindings

971 downloads over 30 days 0 257 1.3.2 GPU support unknown No native code found MIT
genevo Listed Dormant

genevo provides building blocks to run simulations of optimization and search problems using genetic algorithms (GA). Execute genetic algorithm (GA) simulations in a customizable and extensible way.

372 downloads over 30 days 1 185 0.7.1 GPU support unknown No native code found Apache-2.0 OR MIT

Automated machine learning for classification and regression

170 downloads over 30 days 1 39 0.3.1 GPU support unknown No native code found Apache-2.0 OR MIT
oxigen Listed Dormant

Fast, parallel, extensible and adaptable genetic algorithm library.

89 downloads over 30 days 0 183 2.2.2 GPU support unknown No native code found MPL-2.0
treeboost Listed

Gradient-boosted decision trees for tabular data: trains a baseline model in one call, with full control over boosting modes and configs, and Scalar, AVX-512, SVE2, WGPU and CUDA backends.

Python bindings

18 downloads over 30 days 0 9 0.1.2 CUDA, WebGPU No native code found Apache-2.0
Why ListedNo archive, New or Featured rule places it, so it is Listed.

What it lacks for Featured

  • It has 3 active dependents and 0 new dependents in 365 days. Featured needs 11 active dependents or 9 new dependents in 365 days. The repository route reads 95 stars, 8 forks and 4 contributors. It needs 4,539 stars, 434 forks and 79 contributors together.

What else the check found

  • The last activity is on 31 Aug 2026, 70 days ago. The rules expect an update within 450 days. Dormancy rule

Exact rules: Listed, Featured library. The check on applied thresholds version 9.

Every rule outcome, as the check records it
  • expected-interval: version 0.7.13 base 450: E = 450 days
  • dormancy: last activity 2026-08-31, 70 days ago, E = 450: active
  • featured: not featured: active_users 3 < 11 and new_adopters 0 < 9 and repository route stars 95 (needs 4539), forks 8 (needs 434), contributors 4 (needs 79)
  • listed: listed: no archive, new or featured rule applies

Measurements and sources

Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.

Sources6 sources
Adoption3 active dependents, 0 new dependents in 365 days1 not measured
Adoption measurements
SignalValueSourceFetchedCounts
Active dependents3crates.io database dumpYes
New dependents (365 days)0crates.io database dumpYes
Peak active dependents3crates.io database dumpYes
Active dependents as a share of the peak1crates.io database dumpYes
Binary downloads per releaseNot measuredYes
MaintenanceLatest human commit: 2 months ago3 not measured
Maintenance measurements
SignalValueSourceFetchedCounts
Latest human commit2026-08-31GitHub repositoryYes
Latest release2026-08-31crates.io database dumpYes
First release2020-08-21crates.io database dumpYes
Latest version0.7.13crates.io database dumpYes
Days the oldest outside issue waits for a reply0GitHub repositoryYes
Maintainer replies over 365 days49GitHub repositoryYes
Repository archivedfalseGitHub repositoryYes
Repository gonefalseGitHub repositoryYes
Release commit or manifest in the repotruecrates.io packageYes
Published docstruecrates.io database dumpYes
Latest release fails cargo checkNot measuredYes
Build check dateNot measuredYes
Build check toolchainNot measuredYes
SecurityUnpatched vulnerabilities: none
Security measurements
SignalValueSourceFetchedCounts
Unpatched vulnerabilities past the grace windownoneRustSec advisory databaseYes
RustSec unmaintained advisorynoneRustSec advisory databaseYes
Deprecation noticenonecrates.io database dumpYes
Deprecated requirementnonecrates.io database dumpYes
Distribution35 releases, 11,593 downloads over 30 days5 not measured
Distribution measurements
SignalValueSourceFetchedCounts
Releases35crates.io database dumpYes
Downloads over 30 days11593crates.io database dumpYes
Binary downloads over the last 3 releasesNot measuredYes
Homebrew installs on request over 365 daysNot measuredYes
Repology repository familiesNot measuredYes
Docker pull growth over 90 daysNot measuredYes
Docker pulls at the growth baselineNot measuredYes
Every version a prereleasefalsecrates.io database dumpYes
Every version 0.0.xfalsecrates.io database dumpYes
Every version yankedfalsecrates.io database dumpYes
Crate deleted from crates.iofalsecrates.io database dumpYes
Repository95 stars, 8 forks, 4 contributors, 107 commits. Stars alone never qualify a project.
Repository measurements
SignalValueSourceFetchedCounts
GitHub stars95GitHub repositoryYes — one part of the repository route
GitHub forks8GitHub repositoryYes — one part of the repository route
Contributors with a GitHub account4GitHub contributorsYes — one part of the repository route
Commits on the default branch107GitHub repositoryNo
Repository's main crate left out of the entrynonecrates.io database dumpYes
Facts that never count
Facts that never count measurements
SignalValueSourceFetchedCounts
LicenseMITcrates.io database dumpNo
Runs on, from listed crates and their direct dependenciesGPU support unknowncrates.io database dumpNo
What shows each backendno dependency or feature matches a backend rowcrates.io database dumpNo
Native code, from listed crates and their dependenciesNo native code foundcrates.io database dumpNo
Python bindings, from direct dependencies of listed cratesNo Python binding crate foundcrates.io database dumpNo
Crates that depend on a listed crate directly2crates.io database dumpNo

Corrections and review history

Report a correction

No correction applies to this entry.

Judgments

A judgment enters only through an approved issue and a merged pull request.

No judgment applies to this entry.