Memory Theatre implements Sparse Distributed Memory (SDM), a mathematical model of associative memory inspired by Kanerva's work. SDM is designed for high-dimensional binary spaces and is capable of storing and retrieving patterns even in the presence of noise.
Address Space: SDM operates in a high-dimensional binary space (e.g., 1000+ dimensions). Each memory location is a random binary vector (address) in this space.
Critical Distance:
When reading or writing, SDM activates all memory locations within a certain Hamming distance (the number of differing bits) from the query address. The critical distance
where
Write Operation:
To write a data vector
- Find all memory locations whose address is within
$d_c$ of$a$ . - For each such location, add
$x$ to its stored data vector.
Read Operation:
To read from address
- Find all memory locations within
$d_c$ of$a$ . - Sum their data vectors and (optionally) normalize by the number of contributors.
Hamming Distance:
Given two binary vectors
Start an IEx session:
iex -S mix
Create a new SDM with 100 dimensions and 1000 memory locations:
iex> sdm = MemoryTheatre.SDM.new(100, 1000)
%MemoryTheatre.SDM{...}
Generate a random binary address and a random data vector:
iex> key = Nx.Random.key(System.unique_integer())
iex> {rand, _} = Nx.Random.uniform(key, 0.0, 1.0, shape: {100}, type: :f32)
iex> address = Nx.greater(rand, 0.5)
iex> {data, _} = Nx.Random.uniform(Nx.Random.key(System.unique_integer()), 0.0, 1.0, shape: {100}, type: :f32)
Write the data to the SDM:
iex> sdm = MemoryTheatre.SDM.write(sdm, address, data)
%MemoryTheatre.SDM{...}
Read the data back:
iex> {retrieved, confidence} = MemoryTheatre.SDM.read(sdm, address)
iex> confidence
# Number of locations that contributed to the read
iex> Nx.shape(retrieved)
{100}
Check Hamming distance between two addresses:
iex> a = Nx.tensor([1, 0, 1, 0, 1], type: {:u, 8})
iex> b = Nx.tensor([1, 1, 0, 0, 1], type: {:u, 8})
iex> MemoryTheatre.SDM.hamming_distance(a, b)
2