Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dcc_htm — Hierarchical Temporal Memory in Rust

A clean-room, standalone Rust port of Hierarchical Temporal Memory (HTM) — the algorithm architecture whose reference implementation is htm.core (C++/Python), the community continuation of Numenta's NuPIC. Pinned to upstream commit bef3088.

HTM models a cortical region as a sheet of minicolumns learning sparse distributed representations of a stream. A spatial pooler turns each input into a fixed-sparsity SDR; a temporal memory learns which cells follow which, so that on each step some cells are predictive — and an input that no cell predicted makes its column burst, which is the anomaly signal.

This is a standalone, self-contained crate. It was extracted from the dcc-core workspace and now builds and versions independently, with no dependency on dcc-core.


Status

Core inference stack ported. Random (a faithful std::mt19937), Sdr, Connections, SpatialPooler, TemporalMemory (incl. external predictive inputs), Classifier/Predictor, ScalarEncoder, Rdse, DateEncoder, SimHashDocumentEncoder (+ a SHAKE256 port), SdrMetrics, AnomalyLikelihood, and serde save/load.

Deferred: NetworkAPI/Regions, and Cereal-byte-compatible serialization. Save/load here is Rust-native serde — it round-trips within this crate but is not byte-compatible with htm.core's Cereal format.

Demos: six runnable examples under examples/, documented in doc/Demos.md.

cargo run --release --example high_order_sequence
cargo run --release --example noise_robustness -- --sweep noise=0,0.4,0.45,0.5 --repeat 5

Three of them — high_order_sequence, classify_stream and noise_robustness — implement a demo contract shared with the sibling ports dcc-sph and dcc-sparsey, so an experiment run against any of the three takes the same flags and emits the same JSONL records. The three repositories share no code and cannot: this crate is AGPL-3.0 and dcc_sph is CC BY-NC-SA 4.0, which do not mix. The other three demos show what HTM does that the siblings cannot — anomaly_stream, spatial_pooling and multistep_predict.

examples/support/pipeline.rs is worth reading on its own: it is the encoder → SpatialPooler → TemporalMemory → Classifier wiring this crate does not otherwise provide, NetworkAPI being deferred.


Features

  • Bit-exact parity with htm.core — seeded runs reproduce the C++ SDR and cell streams exactly
  • Faithful RNGRandom is a real std::mt19937, which is what makes the above possible
  • Full encoder set — scalar, RDSE, date/time, and SimHash document encoding
  • Anomaly detection — raw anomaly score plus AnomalyLikelihood's distribution-based refinement
  • ClassificationClassifier/Predictor for supervised readout over SDRs
  • Dependency-lightserde is the only runtime dependency

Quick start

Requires a Rust toolchain (stable).

git clone https://github.com/jacobeverist/dcc-htm
cd dcc-htm
cargo build            # build the library
cargo test             # unit + integration + determinism tests

To use it from another crate:

[dependencies]
dcc_htm = { git = "https://github.com/jacobeverist/dcc-htm" }

Concepts in 30 seconds

Term Meaning
SDR Sparse Distributed Representation — a large binary vector with few active bits. The universal currency between every component here.
Minicolumn A group of cells sharing one proximal (feed-forward) receptive field. The spatial pooler selects a sparse set of columns; the temporal memory picks cells within them.
Proximal / distal Proximal synapses carry feed-forward input (column selection); distal synapses carry lateral context from other cells (prediction).
Spatial pooler Maps an input SDR to a fixed-sparsity column SDR, with boosting to keep column usage even.
Temporal memory Learns cell→cell transitions so the next step is partially predicted; unpredicted input bursts its column.
Predictive / bursting A cell is predictive when enough distal synapses are active. A column bursts when its input arrived unpredicted — the raw anomaly signal.
Anomaly score Fraction of active columns that burst, in [0, 1]. AnomalyLikelihood turns that into a distribution-relative probability.

Full vocabulary, with the upstream C++ name beside each so a reader can move between this crate and htm.core without guessing: doc/NameReference.md.


Minimal example

use dcc_htm::{Sdr, SpatialPooler};

let mut sp = SpatialPooler::new(
    vec![100], vec![64], 16, 0.5, true, 0.1, 0, 1,
    0.008, 0.05, 0.1, 0.001, 1000, 0.0, /*seed*/ 1, /*wrap*/ true);

let mut input  = Sdr::new(vec![100]);
let mut active = Sdr::new(vec![64]);

input.set_sparse(vec![1, 5, 9, 13, 17]);
sp.compute(&input, /*learn*/ true, &mut active);

Public API at a glance

  • Encode: ScalarEncoder, Rdse, DateEncoder, SimHashDocumentEncoder → an Sdr.
  • Pool: SpatialPooler::compute(&input, learn, &mut active) — input SDR to column SDR.
  • Predict: TemporalMemorycompute / activate_cells / activate_dendrites, plus anomaly() and external predictive inputs.
  • Read out: Classifier / Predictor for supervised inference; argmax for the winning category.
  • Measure: Metrics, Sparsity, Overlap, ActivationFrequency (SdrMetrics); AnomalyLikelihood for distribution-relative anomaly.
  • Low level: Connections (synapse/segment store), Random (the std::mt19937 port), AnMode.

Documentation

Document Description
doc/UserGuide.md Full user guide: concepts, API, worked usage
doc/Architecture.md Component structure and how the pieces compose
doc/Tuning.md Parameter descriptions and tuning advice
doc/NameReference.md HTM vocabulary with the upstream C++ name beside each
doc/PortNotes.md Mapping from C++ names/types to Rust equivalents
doc/MethodFidelity.md Method-by-method correspondence with htm.core
doc/Divergences.md Where this port intentionally differs, and why

Source layout

src/
  lib.rs                  — crate root and public re-exports
  random.rs               — std::mt19937 port; the keystone of bit-exactness
  sdr.rs                  — Sdr: the sparse binary representation
  connections.rs          — synapse/segment store shared by the learners
  spatial_pooler.rs       — SpatialPooler
  temporal_memory.rs      — TemporalMemory, AnMode
  classifier.rs           — Classifier, Predictor, argmax
  encoders.rs             — ScalarEncoder, Rdse, DateEncoder
  simhash.rs              — SimHashDocumentEncoder (+ SHAKE256)
  sdr_metrics.rs          — Metrics, Sparsity, Overlap, ActivationFrequency
  anomaly_likelihood.rs   — AnomalyLikelihood
  topology.rs             — neighbourhood/wrapping helpers
  types.rs                — shared numeric types
tests/
  fidelity.rs             — C++ golden comparison (skips without the fixture)
  serialization.rs        — serde round-trips
  fixtures/               — committed golden data
fidelity/                 — harness for regenerating fixtures (needs an htm.core checkout)
doc/                      — documentation

This is a transliteration, not an idiomatic rewrite. Module and function names, and loop structure, deliberately mirror the C++ so doc/MethodFidelity.md can be audited method by method. That is why several clippy lints are allowed at the crate root — see the comment block in src/lib.rs, particularly approx_constant: htm.core computes 0.5 * erfc(z / 1.4142) with that literal, and 1.4142 != SQRT_2, so "fixing" it would silently change every anomaly likelihood this crate produces.


Fidelity

The port targets bit-exact parity with htm.core. The keystone is random::Random, a faithful std::mt19937 reimplementation — every algorithm draws from it in the same order as the C++, so seeded runs reproduce the C++ SDR and cell streams exactly.

cargo test runs the unit and determinism tests everywhere. The C++ golden comparison runs when the committed fixture is present and skips with a notice when it is not, so a checkout with no htm.core beside it is still green. See fidelity/README.md and doc/MethodFidelity.md.


Optional features

  • json-schema — derives schemars JSON Schema for the config types (cargo build --features json-schema).

License and attribution

AGPL-3.0-only, matching htm.core — whose source headers say "version 3" with no "or any later version". Full text in LICENSE.

Copyright (c) 2026 Jacob Everist, for the Rust port. Upstream copyright and license notices are preserved in the ported sources.

Upstream is htm-community/htm.core. The htm.core README asks to be cited; that citation, the pinned upstream commit, and the attribution notices are in PROVENANCE.md.

About

Clean-room Rust port of Hierarchical Temporal Memory, from the htm.core reference implementation

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages