[Python-ideas] SI scale factors in Python

Ken Kundert python-ideas at shalmirane.com
Thu Aug 25 23:46:54 EDT 2016


On Fri, Aug 26, 2016 at 10:14:53AM +1000, Steven D'Aprano wrote:
> On Thu, Aug 25, 2016 at 11:02:11AM -0700, Ken Kundert wrote:
> 
> > Even if the language completely ignores the units, we have still gained by 
> > allowing the units to be there, just like we gain when we allow user to add 
> > comments to their code even though the compiler ignores them.
> 
> This part of your proposal would be *worse*: you would fool the casual or 
> naive user into believing that Python did dimensional analysis, while in fact 
> not doing so. You would give them a false sense of security.

This idea is new to general purpose languages, but it has been used for over 40 
years in the circuit design community. Specifically, SPICE, an extremely heavily 
used circuit simulation package, introduced this concept in 1974. In SPICE the 
scale factor is honored but any thing after the scale factor is ignored.  Being 
both a heavy user and developer of SPICE, I can tell you that in all that time 
this issue has never come up. In fact, the users never expected there to be any 
support for dimensional analysis, nor did they request it.

> Don't think of people writing code like this:
> 
>     result = 23mA + 75MHz
> 
> which is obviously wrong. Think about them writing code like this:
> 
>     total = sum_resistors_in_parallel(input, extra)

You say that '23mA + 75MHz' is obviously wrong, but it is only obviously wrong 
because the units are included, which is my point. If I had written '0.023 
+ 76e6', it would not be obviously wrong.

> > Some people have suggested that we take the next step and use the units for 
> > dimensional analysis, but that is highly problematic because you cannot do 
> > dimensional analysis unless everything is specified with the correct units, 
> > and that can be a huge burden for the user.
> 
> What?
> 
> That's the *whole point* of dimensional analysis: to ensure that the 
> user is not adding a length to a weight and then treating the result as 
> a time. To say that "it is too hard to specify the correct units, so we 
> should just ignore the units" boggles my mind.
> 
> Any reasonable dimensional program should perform automatic unit 
> conversions: you can add inches to metres, but not inches to pounds. 
> There are already many of these available for Python.

Indeed that is the point of dimensional analysis. However, despite the 
availability of all these packages, they are rarely if ever used because you 
have to invest a tremendous effort before they can be effective. For example, 
consider the simple case of Ohms Law:

    V = R*I

To perform dimensional analysis we need to know the units of V, R, and I. These 
are variables not literals, so some mechanism needs to be provided for 
specifying the units of variables, even those that don't exist yet, like V. And 
what if the following is encountered:

    V = I

Dimensional analysis says this is wrong, but the it may be that the resistance 
is simply being suppressed because it is unity.  False positives of this sort 
are a tremendous problem with this form of automated dimensional analysis. Then 
there are things like this:

    V = 2*sin(f*t)

In this case dimensional analysis (DA) indicates an error, but it is the wrong 
error. DA will complain about the fact that a dimensionless number is being 
assigned to a variable intended to carry a voltage. But in this case 2 has units 
of voltage, but they were not explicitly specified, so this is another false 
positive.  The real error is the argument of the sin function. The sin function 
expects radians, which is dimensionless, and f*t is dimensionless, so there is 
no complaint, but it is not in radians, and so there should be an error.  You 
could put a 'unit' of radians on pi, but that is not right either. Really it is 
2*pi that gives you radians, and if you put radians on py and then used pi to 
compute the area of a unit circle, you would get pi*r^2 where r=1 meter, and the 
resulting units would be radians*m^2, which is nonsensical.

Turns out there are many kinds of dimensionless numbers. For example, the 
following represents a voltage amplifier:

    Av = 4       # voltage gain (V/V)
    Ai = 0.03    # current gain (A/A)
    Vout = Ai*Vin

In this case Ai is expected to be unitless, which it is, so there is no error.  
However Ai is the ratio of two currents, not two voltages, so there actually 
should be an error.

Now consider an expression that contains an arbitrary function call:

    V = f(I)

How do we determine the units of the return value of f?

Now, finally consider the BSIM4 MOSFET model equations. They are described in 

    http://www-device.eecs.berkeley.edu/bsim/Files/BSIM4/BSIM460/doc/BSIM460_Manual.pdf

If you look at this document you will find over 200 pages of extremely 
complicated and tedious model equations. The parameters of these models can have 
extremely complicated units. Well beyond anything I am proposing for real 
literals. For example, consider NOIA, the 'flicker noise parameter A'.  It has 
units of (eV)^-1 s^(1-EF) m^-3.  Where EF is some number between 0 and 1.  That 
will never work with dimensional analysis because it does not even make sense 
from the perspectives of dimensional analysis.  Describing all of the units in 
those equations would be a huge undertaking, and in the end they would end up 
with errors they cannot get rid off.

Dimensional analysis is a seductive siren that, in the end, demands a great deal 
of you and generally delivers very little.

And it has little to do with my proposal, which is basically this:

Numbers with SI scale factor and units have become very popular. Using them is 
a very common way of expressing either large or small numbers. And that is true 
in the scientific and engineering communities, in the programming community 
(even the linux sort command supports sorting on numbers with SI scale factors:  
--human-numeric-sort), and even in popular culture.

Python should support them. And I mean support with a capital S. I can come up 
with many different hacks to support these ideas in Python today, and I have.  
But this should not be a hack. This should be built into the language front and 
center. It should be the preferred way that we specify and output real numbers.

-Ken







More information about the Python-ideas mailing list