Wednesday, April 30, 2014

algorithm for variable-lifetime maximal power curve derivation

The traditional problem with maximal power curves is they may contain rides so old that the power generated in those rides has little relevance to the present. So it's useful to truncate the data: to set an age limit for points used.

But there may be a considerable data set to process for this purpose. Calculating a maximal power curve from scratch makes little sense.

When calculating a curve from an entire data set, you start at the oldest activity, calculate the maximal powers for each duration for that set, then that's it. For each additional activity you compare the average power for each duration, extending the existing maximal power curve to longer durations if needed (constant work), then adding in points from the newert activity (extending that if needed).

But with an adjustable age limit, it gets more complicated. Instead I need to retain, for each duration, all points which are the maximum power for their age or less. These numbers can be saved, for example, as a linked list in order of age.

The durations need not be every duration. In my fitting procedure I use times which are separated from each other by no less than 2%. So 1 sec, 2 sec, 3 sec, etc, up to 50 seconds, but then 52 second, 54 seconds, 56 seconds, etc, up to 100 seconds, then 103, 106, etc. Approximately every 50 seconds the time step increases by 1

So consider I have a new time point for today's ride, where I got 300 watts for some duration. I have a linked list as follows:

  1. 270 watts, 5 days old
  2. 285 watts, 30 days old
  3. 310 watts, 90 days old
I then step down the linked list until I get a power which is larger than the present one, and insert the new point as the new head of the list. So, for example, the new list in this example will be:
  1. 300 watts, 0 days old
  2. 310 watts, 90 days old

Had the power been at least 310 watts, the new point would be the only point in the list. On the other hand, had it been under 270 watts, it would have gone on the head of the list, with all other elements shifted downward.

Given the linked list for each duration, if I want to construct a maximal power curve for any time cut-off I go through the linked lists for each duration and take the oldest/highest power point no older than the limit.

Note the linked lists contain points of strictly increasing power and strictly increasing age. While it is pathologically feasible this will include points from all activities, the far more likely scenario is it will contain only a small fraction. This is why a linked list, rather than a static array, makes sense here: the linked list has arbitrary length yet is optimized for short lists.

No comments: