Thursday, December 13, 2012

"units" program for running/marathon time calculations

I've been doing a lot of calculations about marathon pacing and times and I wanted to document my favorite method for doing that. It's the venerable unix code "units", which is provided with Mac OS/X.

There's various GUIs provided for this code, or for other unit converters, but it's the command-line version which is the most powerful.

I suspect most users of units fail to appreciate it's power. For example, they might want to convert km to miles (or back). For that, I type:

> units
Currency exchange rates from 2012-06-06 
2546 units, 85 prefixes, 66 nonlinear units

You have: km
You want: miles
 * 0.62137119
 / 1.609344

I see that 1 km is 0.62 miles, with a reciprical conversion of 1.61 km per mile.

Or you can just convert a unit to a basis unit, as follows:

You have: km
You want: 
 Definition: kilo m = 1000 m
You have: miles
You want: 
 Definition: mile = 5280 ft = 1609.344 m

The internal unit for distance is meters, so the code provides the definition in the internal unit if you fail to provide a destination unit.

For times it doesn't do so well. For example, suppose I want to convert 3 hours + 15 seconds to seconds. I might try:

You have: 3:15
             ^
Parse error
You have: 3:15:00
Unknown unit ':15:00'

It doesn't like times listed this way. Instead I need to type:

You have: (3 hours + 15 seconds)
You want: 
 Definition: 10815 s

You can see here it handles mathematical expressions. It has quite a flexible expression parser, and even serves as a good stand-alone calculator. For example:

You have: ln(square(sin(sqrt(10))))
You want: 
 Definition: -7.7568349
You have: ln(exp(1))
You want: 
 Definition: 1

So I can use this in calculating times.

For running, a very useful unit of distance is "marathon".

You have: marathon
You want: 
 Definition: 26 miles + 385 yards = 42194.988 m

I can then easily convert between marathon times and "paces", per mile or km:

You have: (3 hours + 15 minutes) / marathon
You want: minutes / km
 * 4.621402
 / 0.21638455
4.62 minutes. To get the fractional seconds I subtract 4 minutes and convert to seconds:
You have: (3 hours + 15 minutes) / marathon - 4 min / km
You want: seconds/km
 * 37.284117
 / 0.026821072
You have: (3 hours + 15 minutes) / marathon - 7 min / mile
You want: seconds/mile
 * 26.24553
 / 0.038101726

So it's 4:37.3 per km, or 7:26.2 per mile.

I can ask distance scaling questions. Suppose I ran a 41:15 for a 10 km race and I assume I will lose 5% per doubling of distance and wish to project my marathon time. I can solve that:

You have: marathon * ((41 minutes + 15 seconds) / 10 km) * 1.05 ** (ln(marathon / 10 km) / ln(2))
You want: hours
 * 3.2102974
 / 0.31149762
You have: marathon * ((41 minutes + 15 seconds) / 10 km) * 1.05 ** (ln(marathon / 10 km) / ln(2)) - 3 hours
You want: minutes
 * 12.617842
 / 0.079252855
You have: marathon * ((41 minutes + 15 seconds) / 10 km) * 1.05 ** (ln(marathon / 10 km) / ln(2)) - (3 hours + 12 minutes)
You want: seconds
 * 37.070518
 / 0.026975615

I conclude if I can run 10 km in 41:15 for 10 km and if I scale time such that every doubling of distance my time/distance is 5% greater, I get a marathon time of 3:12:37.

Or if I did a 10 km race in 41:15, and a half marathon in 1:30:57, I can estimate a marathon time assuming time per distance depends on distance to some power:

You have: (1 hour + 30 minutes + 57 seconds) * (marathon / half marathon) ** ((hour + 30 minutes + 57 seconds) / (half marathon) ((41 minutes + 15 seconds) / 10 km)) - 3 hours
You want: minutes
 * 7.6730578
 / 0.13032614
You have: (1 hour + 30 minutes + 57 seconds) * (marathon / half marathon) ** ((hour + 30 minutes + 57 seconds) / (half marathon) ((41 minutes + 15 seconds) / 10 km)) - 3 hours - 7 minutes
You want: seconds
 * 40.383468
 / 0.024762608

So the conclusion is I'd be able to run the marathon in 3:07:40 (6.4% increase in time/distance per doubling of distance)

I can also do calculations on the effect of weight reduction. Suppose at the CIM start my running cap weighed 50 grams and with my clothes on I weighed 130 lbs. At the start the wind blew my cap away. How much time did this save me, counting only the effect of the mass and not wind resistance? I assume time is proportional to total weight.

You have: (3 hours + 25 minutes + 34 seconds) * (50 grams / 130 lb)
You want: seconds
 * 10.458391
 / 0.095617007

Answer: 10 seconds, neglecting the potential performance advantage of wearing a cap.

Units has a huge variety of unit definitions, and you can define your own. The default definition file can be identified by typing:

> units --help
which prints the following line (among other information):
To learn about the available units look in /opt/local/share/units/definitions.units

Looking in that file, I see "waterdensity" is a unit.

You have: waterdensity
You want: 
 Definition: gram / cm^3 = 1000 kg / m^3

It's defined to be 1 gram / cubic cm, which is the definition of the gram, after all (this applies only to pure water at its triple point: typical water differs somewhat).

I can use this to ask another question about the marathon... suppose I was 2/3 of the way through and I needed to pee, and if I peed I would release 250 ml of water, and suppose it would delay me 20 seconds. Should I do it, assuming suitable opportunity, or should I suffer on to the finish? Assume I weigh 130 lb with my clothes. I calculate the net time saved by stopping 20 seconds to reduce mass by 250 ml of water:

You have: (250 ml * waterdensity / 130 lb) * ((3 hours + 25 minutes+ 34 seconds) / marathon) * (marathon / 3) - 20 seconds
You want: seconds
 * -2.5693491
 / -0.38920363

So the conclusion is stopping ends up costing me close to 3 seconds. On the other hand, I get most of 20 seconds of rest in the deal, so in the end it's probably a net win (the elasticity of rest question). On the other hand, speed may not be proportional to bladder mass, since I assume center of mass motion contributes only half to total energy required at optimal cadence, the other half from foot motion.

I can also define custom units. For example, BMI is body mass index typically measured in kg2/meter2. And rate of climbing is measured in VAM which is traditionally meters per hour. I would like to be able to use these units.

No luck, though:

You have: BMI
Unknown unit 'BMI'
You have: VAM
Unknown unit 'VAM'
So I define a file ".units" in my home directory with the following definitions:
# additional definitions for the units program
BMI  kg/meter^2
VAM  meters/hour
I can now re-start unis and the definitions appear:
> units
Currency exchange rates from 2012-06-06 
2548 units, 85 prefixes, 66 nonlinear units

You have: 57 kg / (167 cm)^2
You want: BMI
 * 20.438166
 / 0.04892807
You have: 1290 feet / (16 minutes + 36 seconds)
You want: VAM
 * 1421.1759
 / 0.00070364266

So units saves me a lot of time, both in doing in-place unit conversions, but also in calculations when units already match.

No comments: