[SciPy-dev] design of a physical quantities package: seeking comments

Jonathan Guyer guyer@nist....
Sun Aug 3 10:35:47 CDT 2008

On Aug 3, 2008, at 9:22 AM, Darren Dale wrote:

>> More, what happens when you have a quantity in Newton-metres (say)  
>> and
>> you ask it to convert to feet? Do you get Newton-feet, or do all the
>> occurrences of "feet" in the Newtons get converted?
> They all get converted.

I'm with Anne. I'm having a really hard time seeing when I would want  
this as a default behavior, whereas I frequently want to be able  
automatically convert BTUs to Joules and atmospheres to Pascals, but I  
want an exception if somebody tries to give me a pressure when I ask  
for an energy. Having it possible to do what you suggest seems like it  
might be useful sometimes, but I don't think it should be the default  

>> I think the hard part will be getting the ufuncs to behave correctly.
>> As you say, if you can get addition, multiplication, and fractional
>> powers working, you're pretty much there.
>> The key question for me is what units quantities are kept in
>> internally. Keep in mind that some arrays are large, so conversions  
>> of
>> quantities between units can be expensive. If I'm doing many
>> calculations with quantities expressed in pc/cm^3, I would hope that
>> they are not constantly being converted to m^{-2} on input and back  
>> to
>> pc/cm^3 on output. In fact I can imagine cases where both these
>> conversions happen inside a loop. That could get expensive.
> The values would not be stored in some standard internal  
> representation like
> SI, but rather in the units specified, decomposed into fundamental
> dimensions. I do not know how a compound unit like pc/cm^3 would  
> work, but
> Frink doesnt know how to do it either. There is an example from my  
> field too:
> How much surface-area can you pack into a given volume? This is often
> expressed in m^2/cm^3. What a headache. Maybe I could come up with a  
> method
> that returns an alternate string representation of the quantity:
> q.in_units_of("pc/cm^3"). But it would not effect the internal
> representation.

Several years ago, we adapted Konrad Hinsen's PhysicalQuantity (from  
ScientificPython) to work with the large fields of numbers we needed  
for FiPy. It's largely Konrad's code; the primary difference is that a  
1000x1000 array gets one unit, not a million of them.

Using this scheme:

 >>> from fipy import PhysicalField
 >>> PhysicalField("12 lyr/cm**3")
 >>> PhysicalField("1 lyr") / "7.3 cm**2"
 >>> PhysicalField("12 lyr/cm**3").inUnitsOf("m**-2")

so the compound unit that Anne wants is supported and conversion to  
canonical units happens only when requested.

Note: I had to use light years because parsecs aren't predefined, and  
adding new units & constants is one of the weaknesses of Konrad's  

I urge a long look at Konrad's code (or our adaptation of it: http://matforge.org/fipy/browser/trunk/fipy/tools/dimensions) 
, as it already does a lot of what you want. It was written in Numeric  
days, so I think a re-implementation as a subclass of ndarray with  
tighter integration with ufuncs [*] would be a big improvement, but  
the basic design is a good one, IMO.

[*] Actually, I don't know if the ufunc integration needs to be any  

 >>> from fipy import PhysicalField
 >>> import numpy
 >>> numpy.exp(PhysicalField("1 m**2"))
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "/Users/guyer/Documents/research/FiPy/trunk/fipy/tools/ 
dimensions/physicalField.py", line 595, in __array__
     raise TypeError, 'Numeric array value must be dimensionless'
TypeError: Numeric array value must be dimensionless
 >>> numpy.exp(-PhysicalField("1. eV") / "300 K * kB")

We presently have a "numerix" abstraction layer to make sure that  
numerix.exp() calls the methods we want, because Numeric didn't do  
this, but with numpy I think a lot of that can go away.

More information about the Scipy-dev mailing list