HypercubeHopfield C++ SDK

June 5, 2026 ยท View on GitHub

Static C++ library for modern Hopfield associative memory on Boolean hypercube graphs.

Contents

What's in the SDK

After installation, the SDK contains:

<prefix>/
  include/HypercubeHopfield/
    HopfieldNetwork.h          -- The public API (the only header consumers include)
  lib/
    libHypercubeHopfieldCore.a
  lib/cmake/HypercubeHopfield/
    HypercubeHopfieldConfig.cmake
    HypercubeHopfieldTargets.cmake
    HypercubeHopfieldConfigVersion.cmake

Consumers include <HypercubeHopfield/HopfieldNetwork.h> and link against HypercubeHopfield::HypercubeHopfieldCore. The single header contains the complete public API: template class, type-erased interface, and runtime factory.

Building from source

Requirements: C++23 compiler (GCC 13+, Clang 17+, MSVC 2022+), CMake 4.1+.

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
cmake --install build --prefix /path/to/sdk

Using the SDK

The simplest way to use HypercubeHopfield in a CMake project. No installation, no manual downloads -- CMake pulls the source from GitHub and builds it alongside your project.

cmake_minimum_required(VERSION 4.1)
project(MyApp)

set(CMAKE_CXX_STANDARD 23)

include(FetchContent)
FetchContent_Declare(
    HypercubeHopfield
    GIT_REPOSITORY https://github.com/dliptak001/HypercubeHopfield.git
    GIT_TAG        v1.0.0
)
FetchContent_MakeAvailable(HypercubeHopfield)

add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE HypercubeHopfieldCore)
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

Pin GIT_TAG to a release tag (e.g., v1.0.0) for reproducible builds. Include paths are set automatically -- use #include "HopfieldNetwork.h".

Note: FetchContent exposes the project root as an include path, so the bare include works. The namespaced <HypercubeHopfield/HopfieldNetwork.h> form is available when using an installed SDK via find_package.

Installed SDK (find_package)

If you prefer to install the library once and link against it:

# Build and install
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
cmake --install build --prefix /path/to/sdk
cmake_minimum_required(VERSION 4.1)
project(MyApp)

set(CMAKE_CXX_STANDARD 23)

find_package(HypercubeHopfield REQUIRED)

add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE HypercubeHopfield::HypercubeHopfieldCore)

Configure with the SDK path:

cmake -B build -DCMAKE_PREFIX_PATH=/path/to/sdk
cmake --build build

Minimal example

#include "HopfieldNetwork.h"  // or <HypercubeHopfield/HopfieldNetwork.h> if installed
#include <cstdio>
#include <random>
#include <vector>

int main()
{
    constexpr size_t DIM = 8;
    constexpr size_t N = 1ULL << DIM;  // 256 neurons

    // Create network with runtime DIM selection
    auto net = CreateHopfieldNetwork(DIM, /*seed=*/42);

    // Generate and store a random pattern
    std::mt19937_64 rng(123);
    std::uniform_real_distribution<float> dist(-1.0f, 1.0f);
    std::vector<float> pattern(N);
    for (auto& v : pattern) v = dist(rng);
    net->StorePattern(pattern);

    // Corrupt the pattern with heavy noise
    std::vector<float> probe(pattern);
    std::normal_distribution<float> noise(0.0f, 2.0f);
    for (auto& v : probe) v += noise(rng);

    // Recall: the network recovers the stored pattern
    auto [steps, converged] = net->Recall(probe);
    std::printf("Converged: %s in %zu steps\n",
                converged ? "yes" : "no", steps);
    return 0;
}

For compile-time DIM selection (avoids virtual dispatch):

auto net = HopfieldNetwork<8>::Create(/*seed=*/42);

API Reference

Template parameter: DIM

DIM is a compile-time template parameter controlling the hypercube dimension. The network has N = 2^DIM neurons. The library provides explicit template instantiations for DIM 4-16.

DIMNeuronsTypical use
4-616-64Fast prototyping, unit tests
7-8128-256Standard workloads, demos
9-12512-4096High-capacity associative memory
13-168192-65536Research, maximum capacity

Enums

UpdateMode

ValueDescription
AsyncSequential random-order updates. Guaranteed energy descent. Not parallelizable.
SyncSimultaneous double-buffered updates. Deterministic, GPU-portable. Default.

RecallResult

struct RecallResult
{
    size_t steps;     // Number of update sweeps performed
    bool   converged; // True if the state stabilized within tolerance
};

Returned by Recall(). Supports structured bindings:

auto [steps, converged] = net->Recall(state);

HopfieldNetwork<DIM>

The core template class. Owns the network state, stored patterns, connection masks, and internal thread pool.

Construction

static std::unique_ptr<HopfieldNetwork> Create(
    uint64_t rng_seed,
    size_t   reach              = DIM / 2,
    float    beta               = 4.0f,
    float    neighbor_fraction  = 1.0f,
    float    tolerance          = 1e-6f);

Returns a unique_ptr to a new network. Parameters:

ParameterTypeDefaultDescription
rng_seeduint64_tRequiredRandom seed for update-order permutations. Deterministic given the same seed.
reachsize_tDIM/2Hamming-ball radius for neighbor connectivity (1 to DIM). Higher = more connections, more capacity, slower per-sweep.
betafloat4.0Inverse temperature for softmax attention. Higher = sharper (more winner-take-all) retrieval.
neighbor_fractionfloat1.0Fraction of the Hamming ball to use (0.0, 1.0]. Masks are sorted by distance (closest first) then truncated.
tolerancefloat1e-6Convergence threshold. A sweep is stable when no vertex changes by more than this.

Throws: std::invalid_argument if reach is outside [1, DIM], beta is not positive, neighbor_fraction is outside (0.0, 1.0], or tolerance is negative.


Core Operations

StorePattern
void StorePattern(std::span<const float> pattern);

Store a pattern for later retrieval. Patterns are stored explicitly (not collapsed into a weight matrix). Continuous-valued floats -- not restricted to {-1, +1}.

Parameters:

  • pattern -- Exactly NumVertices() floats.

Throws: std::invalid_argument if pattern.size() != NumVertices().


Recall
RecallResult Recall(std::span<float> state,
                    size_t max_steps = 100,
                    UpdateMode mode = UpdateMode::Sync);

Run update sweeps until convergence or max_steps. The state buffer is modified in place -- on return it holds the recalled pattern.

Parameters:

  • state -- In/out: NumVertices() floats. Modified in place.
  • max_steps -- Maximum update sweeps before declaring non-convergence.
  • mode -- Sync (default, deterministic) or Async (guaranteed energy descent).

Returns: RecallResult with sweep count and convergence flag. Returns {0, false} if no patterns are stored.

Throws: std::invalid_argument if state.size() != NumVertices().

Notes:

  • Sync mode uses internal multithreading for large workloads (DIM >= ~12 with many patterns).
  • Async mode is inherently sequential (data dependency between vertex updates).

Energy
[[nodiscard]] std::optional<float> Energy(std::span<const float> state) const;

Compute the modern Hopfield energy for the given state.

Returns: Energy value, or std::nullopt if no patterns are stored.

Throws: std::invalid_argument if state.size() != NumVertices().


Pattern Management

NumPatterns
[[nodiscard]] size_t NumPatterns() const;

Number of currently stored patterns.


GetPattern
[[nodiscard]] std::span<const float> GetPattern(size_t idx) const;

Read back a stored pattern by index.

Throws: std::out_of_range if idx >= NumPatterns().


PopPattern
void PopPattern();

Remove the most recently stored pattern.

Throws: std::out_of_range if NumPatterns() == 0.


Clear
void Clear();

Remove all stored patterns and reset internal state.


Introspection

These accessors return construction parameters. Together with GetPattern(), they provide everything needed for serialization and reconstruction.

MethodReturnsDescription
Dim()size_tHypercube dimension (template parameter DIM).
NumVertices()size_tNumber of neurons: 2^DIM.
Seed()uint64_tOriginal RNG seed passed at construction.
Reach()size_tHamming-ball radius.
Beta()floatInverse temperature.
NeighborFraction()floatFraction of Hamming ball used.
Tolerance()floatConvergence threshold.

Serialization round-trip:

// Save: record these values + all patterns
auto dim = net->Dim();
auto seed = net->Seed();
auto reach = net->Reach();
auto beta = net->Beta();
auto nf = net->NeighborFraction();
auto tol = net->Tolerance();
for (size_t i = 0; i < net->NumPatterns(); ++i)
    save(net->GetPattern(i));

// Restore
auto restored = CreateHopfieldNetwork(dim, seed, reach, beta, nf, tol);
for (auto& pat : saved_patterns)
    restored->StorePattern(pat);

IHopfieldNetwork (type-erased interface)

class IHopfieldNetwork

Abstract base class with the same methods as HopfieldNetwork<DIM>, accessed through virtual dispatch. Use this when DIM is not known at compile time (e.g., SDK bindings, plugin systems, configuration-driven applications).

Obtained via CreateHopfieldNetwork() (below). A unique_ptr<HopfieldNetwork<DIM>> converts implicitly to unique_ptr<IHopfieldNetwork> via move.

Thread safety: Not thread-safe. A single instance must not be accessed concurrently. Create separate instances for concurrent use.


CreateHopfieldNetwork (runtime factory)

std::unique_ptr<IHopfieldNetwork> CreateHopfieldNetwork(
    size_t   dim,
    uint64_t rng_seed,
    size_t   reach              = 0,
    float    beta               = 4.0f,
    float    neighbor_fraction  = 1.0f,
    float    tolerance          = 1e-6f);

Create a network with DIM chosen at runtime. Returns a type-erased IHopfieldNetwork pointer. All methods are available through virtual dispatch.

Parameters:

  • dim -- Hypercube dimension (4-16).
  • rng_seed -- Random seed.
  • reach -- Hamming-ball radius. Pass 0 for the default (dim/2).
  • beta, neighbor_fraction, tolerance -- Same as HopfieldNetwork<DIM>::Create().

Throws: std::invalid_argument if dim is outside [4, 16], or if any parameter is out of valid range.


Dependencies

No external dependencies beyond the C++ standard library.