OPF time encoder parameter questions

According to NuPIC API documentation ‘21’ in timeOfDay and weekend encoders is not ‘n’, but width ‘w’:

Parameters:

  • timeOfDay -
    (int | tuple) Time of day, where midnight = 0, units = hour.

    • (int) width of attribute: default radius = 4 hours
    • (tuple) timeOfDay[0] = width; timeOfDay[1] = radius

The same you can see from the code. In nupic/encoders/date.py:

215     self.timeOfDayEncoder = None
216     if timeOfDay != 0:
217       # Value is time of day in hours
218       # Radius = 4 hours, e.g. morning, afternoon, evening, early night,
219       #  late night, etc.
220       if hasattr(timeOfDay, "__getitem__"):
221         w = timeOfDay[0]
222         radius = timeOfDay[1]
223       else:
224         w = timeOfDay
225         radius = 4
226       self.timeOfDayEncoder = ScalarEncoder(w = w, minval=0, maxval=24,
227                               periodic=True, radius=radius, name="time of day", forced=forced)
228       self.timeOfDayOffset = self.width
229       self.width += self.timeOfDayEncoder.getWidth()
230       self.description.append(("time of day", self.timeOfDayOffset))
231       self.encoders.append(("time of day", self.timeOfDayEncoder, self.timeOfDayOffset))

‘w’ is initialized as the first element of timeOfDay tuple:

221         w = timeOfDay[0]

Then it’s passed to initialize ScalarEncoder:

226       self.timeOfDayEncoder = ScalarEncoder(w = w, minval=0, maxval=24,
227                               periodic=True, radius=radius, name="time of day", forced=forced)

Later ‘n’ is calculated in init function of ScalarEncoder _initEncoder():

268     if n != 0:
        ...

287     else:
        ...
305         nfloat = self.w * (self.range / self.radius) + 2 * self.padding
306         self.n = int(math.ceil(nfloat))

Note: ‘n’ is 0, so ‘else’ path is taken.

So, in ‘timeOfDay’: ( 21, 6.090344152692538):

‘21’ (width) is a number of bits that are set to encode a single time value.
‘6.090344152692538’ (radius) is a distance between inputs which have non-overlapping representations, e.g.:

0h
0111111111111111111111000…
6.09h
0000000000000000000000111… (21set bits)

Here 0h and 6.09h are completely different inputs from encoder point of view, since there’s no even 1 bit of overlapping.

Another way to think about this is a proportion. If:

w [bits, 21] -> radius [time, 6.09hours]
n [bits] -> range [time, 24hours]

then:

n = w * range / radius

This is what you see in line 305 above. (There’s also padding there, but it’s a different story)

@rhyolight Please correct me if I’m wrong.

3 Likes