Saturday, August 14, 2004

Idea: Units calculator

I've been doing this electronics course; I'm still doing the basic introductory stuff. Part of this has been in dealing with units of measurement and conversion between SI base units, SI derived units, and other systems of measurement.

Here is a post of mine in another blog with excellent references on units of measurement.

SI are the standard units, as below:

---------------------------------------------
SI base units
---------------------------------------------
Base quantity Name Symbol
length meter m
mass kilogram kg
time second s
electric current ampere A
thermodynamic temp. kelvin K
amount of substance mole mol
luminous intensity candela cd
---------------------------------------------


Anyway, if you want to do conversions, just go to Google.com . For example, try typing in "200 feet per second in furlongs per fortnight" . It's got a calculator that understands units built into it.

I was grinding away at this basic stuff in the labs at TAFE the other night, when it struck me that this is a very easy thing to build.

If you restrict yourself to the 7 standard units (I've listed them above in the third paragraph), you can describe any measured quantity using a scalar value for the amount, and a septuple for the units. Each entry in the septuple represents the index or power for the base unit that entry represents. You need to define a strict ordering, so we'll use that in the table above. Then we can have the following representations, by example:

10 m / s^2 => 10 (1, 0, -2, 0, 0, 0, 0)
20 Joules = 20 m^2 kg / s^2 => 20 (2, 1, -2, 0, 0, 0, 0)
30 kW = 30 000 m^2 kg / s^3 => 30000 (3, 1, -3, 0, 0, 0, 0)
911 Fahrenheit = 761.48 Kelvin => 761.48 (0, 0, 0, 0, 1, 0, 0)
etc...

Once you've got this representation, it becomes pretty easy. If someone asks for quantity Q in units U to be converted to units V (ie: they want converted quantity R), then
- you need to convert U to U' where U' is entirely described in SI base units, and so is described in the format above
- you need to convert V to V', where V' is entirely described in SI base units, and so is described in the format above
- If the unit septuple is identical, conversion is possible. If not, conversion can't be done. You can tell them what the problem is, by subtracting V' from U', and explaining to the user that U converts to units V * (U'-V'), not V
- If the conversion can be done, then lets do it. Now to get U into form U', we need a lookup telling us what each non-base unit it in terms of base units. It will be a scalar and a septuple, where the scalar is a multiplying factor to be used in conversion. For example, google tells me that 1 foot is 0.3048 meters. So, a foot is represented as:

foot conversion -> 0.3048 (1, 0, 0, 0, 0, 0, 0)

Where you see "12 feet", the conversion tells you to replace "feet" with 0.3048 meters, so it reduces to 12 * 0.3048 meters which is 3.6576 meters.

Where we have complex units, they consist of many units multiplied together (consider division as a multiple of the inverse). So we can take each unit, raise its multiplication factor to the power of the unit in the expression (eg: 12 feet squared is 12 * 0.3048^2 meters) and multiply each element in the unit septuplet by the power of the unit, then multiply all these seperated unit results together by multiplying all the multiplication factors and adding all the septuplets

eg: We want 14 square feet per hour in square meters per day.

U is square feet per hour

foot conversion -> 0.3048 (1, 0, 0, 0, 0, 0, 0)
hour conversion -> 60 (0, 0, 1, 0, 0, 0, 0)

square feet -> 0.3048 ^ 2 (1 * 2, 0, 0, 0, 0, 0, 0)
-> 0.09290304 (2, 0, 0, 0, 0, 0, 0)
per hour conversion -> 3600^-1 (0, 0, -1, 0, 0, 0, 0)

U' = square feet per hour -> 0.09290304 * 3600^-1 (2, 0, -1, 0, 0, 0, 0)
-> 0.0000258064 (2, 0, -1, 0, 0, 0, 0)

V -> V' is easier:

V is square meters per second
square meters conversion -> 1^2(1 * 2, 0, 0, 0, 0, 0, 0)
-> 1(2, 0, 0, 0, 0, 0, 0)
day conversion -> 86400 (0, 0, 1, 0, 0, 0, 0)
per day conversion -> 86400^-1(0, 0, 1*-1, 0, 0, 0, 0)
-> 1.15740741 × 10^-5(0, 0, -1, 0, 0, 0, 0)

V' = square meters per day -> 1.15740741 × 10^-5(2, 0, -1, 0, 0, 0, 0)


Note that V' and U' are compatible (same septuplet). Now, the answer is:
14 * 0.0000258064 / 1.15740741 × 10^-5 = 31.2154214

ie: 14 square feet per hour is 31.22 square meters per day


--

So you can see that any units can be converted to any others. It is trivial to implement multiplying to different quantities with units together (convert to base units, multiply scalars and add septuplets), and addition (convert to base units, must have matching unit septuplets, these are unchanged, add scalars together). So an expression evaluator is fairly straightforward (all the work will be in the parsing & expression analysis).

So you can do units a calculator, and a units convertor. You can also give feedback on mismatching units as I described above (eg: 10 meters squared per second in feet per second yields a mismatching septuplet of (1, 0, 0, 0, 0, 0, 0), so you can say "meters squared per second converts to feet meters per second, not feet per second", maybe you could do some magic to work out that feet meters is silly and convert it to feet squared :-) ).

Also, you could allow other units, like "dollars" (so you could work with dollars per cubic meter, or something along those lines). Lots of others, actually; "byte" might be a nice base unit. Maybe allow the user to define arbitrary extra base units!

There might be a way to allow users to add new units, by giving the scalar and the septuplet (or longer vector, as above). Also, we might be able to rip the scalar out of google using it's API to look up the conversion!

Food for thought, ey?

0 Comments:

Post a Comment

<< Home