CycleEncoder and VarCycleEncoder

I think the clock analogy is a bit confusing, it suggests there is some time involved here. It’s for any scalar value.

And it doesn’t use cosines, just modulo 1 to output values between 0 and 1

Here-s a code snippet:

# multi cycle encoder. As CycleEncoder yet its period varies linearly between a min and a max value
def VarCycleEncoder(sdr_size, period = 1, sdr_len = 0, seed = None):
    me = Self()
    if sdr_len == 0:
        # Arbitrary initial sdr length. 
        sdr_len = sdr_size // 4

    periods = np.linspace(period, period * math.e, sdr_size)

    r = np.linspace(0,1, num = sdr_size, endpoint = False, dtype = np.float32)
    r += 0.5 / sdr_size

    np.random.seed(seed)
    np.random.shuffle(r)
    np.random.shuffle(periods)

    @numba.njit
    def dense(x):
        return (r + x / periods) % 1

    @numba.njit
    def sdr(x, slen = sdr_len):
        # dense2sdr(v, k) simply outputs 1 for top k values in v, and 0 for all others
        # That's basic "sdr-ification" of the dense vector v 
        return dense2sdr(dense(x), slen)

    me.dense, me.sdr, me.periods, me.r = dense, sdr, periods, r
    return me

# Self is an empty class: 
class Self: pass

# dense2sdr(vector, k) just return the indices of highest k values in vector 
1 Like