Skip to content

It is not correct to take the average of speed; tqdm needs to use two EMAs. #1102

@almson

Description

@almson

Average speed is not the average of speed measurements, it is the ratio of the average of units and the average of time. This fact means that tqdm.update calculates average speed incorrectly in many cases.

Average speed is (a + b)/(c + d) and does not equal ((a/c)+(b/d))/2 in the general case.

As an example, consider the following elementary school problem. Jack wants to travel from city A to city C through city B. The distance A->B is 10 miles and B->C is 100 miles. Jack walks 2mph A->B and then drives 50mph B->C. What is Jack's average speed? It is 15.7mph. tqdm would calclulate 3.84mph, which is (very) incorrect.

The solution is to keep two running averages. One for distance and the other for time, and to take their ratio as the output.

Here is a sample program demonstrating current behavior:

from tqdm import tqdm
from time import sleep

t = tqdm(unit='miles', total=110, smoothing=0.5, mininterval=0, miniters=0, ncols=60, postfix='\n')
sleep(5)
t.update(10)
sleep(2)
t.update(100)

It outputs:

  0%|                         | 0/110 [00:00<?, ?miles/s, 
  9%|█▍              | 10/110 [00:05<00:50,  2.00miles/s, 
100%|███████████████| 110/110 [00:07<00:00,  3.84miles/s, 
100%|███████████████| 110/110 [00:07<00:00, 15.70miles/s, 
]

The second-to-last output is the incorrect average speed calculated in update, and the last output is the true average speed calculated over the entire run.

Correct implementation would track two running averages. Average distance would be 10*0.5+100*0.5==55 and average time would be 5*0.5+2*0.5==3.5. Their ratio is 55/3.5 which gives the correct 15.7.

The only case where tqdm currently works correctly is when n is always the same (eg, 1) and the average is updated after every update (mininterval/miniters has no effect). In that case, because you're averaging time/n (which is not called the rate, it is the period) the denominator is constant and the average of the period works out to 1/(average speed).

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions