The Fugue

Counterpoint by Hans Fugal

%BF Nomogram

Posted by Hans Fugal Mon, 28 Jul 2008 23:54:54 GMT

Remember that system I came up with for calculating body fat percentage using a gallon jug in a swimming pool? I always let the computer do the calculations for me—I have a little script that I run that updates my weight graph. But not everyone is as geeky as that, and formula is not that simple, and when you add units conversion in it gets downright hairy.

I finally figured out how to generate a nomogram. Now you have no excuses.

no comments |

Measure Your Body Density

Posted by Hans Fugal Mon, 20 Aug 2007 16:30:00 GMT

When you try to lose weight, what you are really trying to do is lose fat. Weighing yourself is a first approximation of your progress, but a better indicator is your body fat percentage (%BF). Unfortunately, measuring %BF can be expensive and/or difficult. It doesn't need to be so. All you need is a body of water (e.g. a swimming pool), a gallon jug, and your bathroom scale.

One of the most accurate ways to measure body fat is hydrostatic weighing. You are weighed underwater and on land, and your body's density is determined. Then body fat is estimated from the measured density. This is the same basic technique that we will use, but we don't require an underwater scale or special tank.

First the how, then I'll give you the physics. Get in the pool and exhale all the air you can, and allow yourself to sink. You will sink unless you're particularly obese. Take note of the sensation of sinking. Then do the same thing but with your lungs full. Take note of the sensation of floating. Now, we want to reach the point of neutral buoyancy when your lungs are empty, where you are neither sinking nor floating. You will be weightless under the water. Take the gallon jug and hold it under the water, then exhale completely. If the jug is full of air, you will probably float (unless you are quite lean, in which case you'll need two jugs). Keep adding water and repeating until you reach neutral buoyancy. If you sink, add air (pour out some water). If you float, add water. Once you've found the magic amount of water, use this equation to calculate your body density (ρ):

rho=m/(m liters/kg - v_\text{air}))

where m is your mass (what the scale tells you), v is the volume of you and your buoy combined, and vair is the volume of air in your buoy. If you have ¾ gallon of water in your gallon jug, then vair is ¼ gallon. ρw=1 kg/liter for all the precision we need.

Once you have density, you may like to estimate your body fat. The equation for that is Siri's equation, which says

This equation assumes your lungs are completely empty, which they can't be, so we need to introduce a term for the residual volume of your lungs. This is about ¼ of your total lung capacity, or ⅓ of your vital lung capacity. You can measure your vital lung capacity with a balloon or a by blowing air through a straw into an inverted container filled with water. The average residual lung capacity for an american male is 1.2 liters; mine is about 1.9 liters. So we can adjust the formula for density as follows:

rho=m/(m/rho<em>w - v</em>a - v_r)

If you do this experiment you will probably find that your estimated %BF is not too far from your BMI, which is a statistical tool for estimating %BF. It can be wildly inaccurate for statistical outliers (e.g. people who are actually in shape), but it's easy to calculate and a decent sanity check in this case.

Here's what's going on. We're using Archimedes' principle: the buoyant force on a submerged object is equal to the weight of the fluid displaced. When the buoyant force balances the force of gravity, we have neutral buoyancy. The buoyant force is expressed as F_b = -rho_w v g. Substitute weight for the buoyant force and solve for the volume of the body (v = vbody + vair), then substitute that into the definition of density (m/v), and you get the formula I gave you above (if you consider the mass of air and the gallon jug as negligible). I glossed over that—if you'd like me to go into more detail say so in the comments.

If you're particularly obese and don't sink when you exhale completely, then all is not lost. You just need some counterbalance. The modified equation is:

rho = m<em>b / ((m</em>b + m<em>c)/rho</em>w - v<em>a - v</em>c).

You can find the volume of your counterbalance by taking a cue from Archimedes and measuring displacement.

About accuracy: the biggest variable in this process is how much air is left in your lungs. You will find with practice that you are able to exhale more air, which will lower your %BF estimation, as if by magic. However it always overestimates and once you figure out how to completely exhale will be very consistent. Siri's equation is the next place to look—it basically takes the density of fat and the density of muscle and ignores bone mass and density, what you ate for lunch, etc. It will also almost certainly overestimate %BF. The astute reader will wonder about air compression in the milk jug. I measured this and found that when the jug is held within a foot or so from the surface, it does compress. However, the amount it compresses conveniently offsets the extra capacity of the jug (they don't pack milk spilling over the brim of the jug, after all). All in all I think it's accurate within a few percentage points for %BF, gives you an upper bound (i.e. you are free to brag about the number you get, even if it may be slightly high), and is more accurate than BMI.

Posted in | 1 comment |

align Environment

Posted by Hans Fugal Wed, 14 Feb 2007 02:53:00 GMT

How I managed to get along for so long without knowing this I don't know. The align environment in LaTeX is very nice for typesetting a series of equations, e.g. in a proof. Here is an example:

\begin{align*}
P(A)\text{ and }P(\overline A\cap B)&\text{ are mutually exclusive.}\
P(\overline A\cap B)+P(A\cap B) &= P(B)\
P(A\cup(\overline A\cap B)) &= P(A)+P(\overline A\cap B) &\because           \text{Third axiom of probability}\
P(A)+P(\overline A\cap B) &\le 1 &\because \text{First axiom of probability}\
P(A)+P(\overline A\cap B)+P(A\cap B)-1 &\le P(A\cap B)\
P(A)+P(B)-1 &\le P(A\cap B)
\end{align*}

That will typeset a series of equations aligned by the &s.

Posted in | no comments |

% for Remainder

Posted by Hans Fugal Wed, 05 Apr 2006 19:56:47 GMT

I had my lunch handed to me today because some C DSP code I had written was wrong:

/* M is the size of the buffer, 
 * w is the base pointer, 
 * p is the pointer into the buffer */
void wrap(short M, short *w, short **p)
{
if (*p < w || *p >= (w + M))
    *p = w + (*p - w) % M;
}

What I did not realize is that the % operator in C does not wrap negative numbers into the positive range like you would expect if you were a mathemtician. i.e. -7 % 8 == -7 in C, where in mathematics -7 = 1 mod 8.

I can hear you now: "Didn't you test it, you fool?" Well, yes, I tested the algorithm in Ruby, where mathematics hold true:

rb(main):001:0> -7 % 8
=> 1

How was I to know the C version was braindead?

So which is right? Well you can probably guess my bias by now. But inquiring minds want to know, and no other type reads this blog so I did some research.

First, the mathematics. Wolfram has a dizzying explanation. Search for modular arithmetic for any number of treatments of the subject. Too lazy for that? Fine, look at your watch. If it's 10:05 and you go back in time 10 minutes, is it -5 past 10? Arguably so ("5 to"), but most people would agree that it's actually 9:55 by canon.

Now for the C argument. The 1999 ISO C Standard says:

If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.

So my compiler is fine. It's C that's broken. Before C99 the use of % on negative numbers was IMPLEMENTATION DEPENDENT, which if you know anything about C history means they didn't think it through well enough, or they made a decision based on speed or ease of implementation. The C99 definition was probably chosen either for ease of implementation or for the most common case. Not exactly good enough to convince me.

Naturally, there's no going back now, so if you find yourself possibly needing to do modular arithmetic on negative numbers in C, be sure to add again if negative:

/* M is the size of the buffer, 
 * w is the base pointer, 
 * p is the pointer into the buffer */
void wrap(short M, short *w, short **p)
{
if (*p < w || *p >= (w + M))
    *p = w + (*p - w) % M;

if (*p - w < 0)
    *p += M;
}

Here's a coherent post to the gcc-help list about the subject. Now, I don't want to hear anyone saying that % is the modulus operator from now on. It's the remainder operator.

Posted in | 3 comments |