Numericalunits
numericalunits python package
Install / Use
/learn @sbyrnes321/NumericalunitsREADME
========================================================================= numericalunits: Units and dimensional analysis compatible with everything
Package homepage at PyPI <http://pypi.python.org/pypi/numericalunits>_ --
Source code at github <http://github.com/sbyrnes321/numericalunits>_ --
Written by Steve Byrnes <http://sjbyrnes.com>_
This package implements units and dimensional analysis in an unconventional way that has the following unique advantages:
-
Compatible with everything: Compatible with virtually any numerical calculation routine, including numpy and scipy, and even including routines not written in Python! That means, for example, if you have a decades-old closed-source C routine for numerical integration, you can pass it a quantity with units of velocity and an integration range with units of time, and the final answer will magically have units of distance. This extreme compatibility is possible because if the variable
xrepresents a quantity with dimensions (like "3.3 kg"),xis actually stored internally as an ordinary floating-point number. The dimension is encoded in the value as a multiplicative factor. When two numbers are multiplied, their dimensions are automatically multiplied, and so on. -
Modular and non-intrusive: When you input data, you say what units they are in. When you display results, you say what units you want to display them in. These steps are very little trouble, and in fact help you create nice, self-documenting code. Other than that, you have to do nothing at all to pass dimensionful quantities into and out of any already-written programs or routines.
-
Powerful tool for debugging: Not all calculation mistakes cause violations of dimensional analysis, but most do--for example, if you accidentally multiply two lengths instead of adding them, the result will have the wrong dimension. If you use this package, it will alert you to these sorts of mistakes.
-
Zero storage overhead
-
Zero calculation overhead
These great features come with the disadvantage that the interface is less
slick than other unit packages. If you have a quantity with units, you
cannot directly see what the units are. You are supposed to already know
what the units are, and then the package will tell you whether you made a
mistake. Even worse, you only get alerted to the mistake after running a
calculation all the way through twice.
Therefore the package is not suggested for students exploring how units work. It is suggested for engineering and science professionals who want to make their code more self-documenting and self-debugging.
Installation
You can install from PyPI: ::
pip install numericalunits
Alternatively---since it's a single module that requires no setup or
compilation---you can download numericalunits.py from PyPI <http://pypi.python.org/pypi/numericalunits>_ or github <http://github.com/sbyrnes321/numericalunits>_ and use it directly.
Usage and examples
To assign a unit to a quantity, multiply by the unit, e.g.
my_length = 100 * mm. (In normal text you would write "100 mm", but
unfortunately Python does not have "implied multiplication".)
To express a dimensionful quantity in a certain unit, divide by that unit,
e.g. when you see my_length / cm, you pronounce it "my_length expressed
in cm".
Unit errors, like trying to add a length to a mass, will not immediately announce themselves as unit errors. Instead, you need to run the whole calculation twice (in a new Python session each time). If you get the same final answers both times, then congratulations, all your calculations are almost guaranteed to pass dimensional analysis! If you get different answers every time you run, then you made a unit error! It is up to you to figure out where and what the error is.
Example 1: What is 5 mL expressed in cubic nanometers?::
from numericalunits import mL, nm
x = 5 * mL # "Read: x is equal to 5 milliliters"
print(x / nm**3) # "Read: x expressed in cubic nanometers is..." --> 5e21
Example 2: An electron is in a 1e5 V/cm electric field. What is its acceleration? (Express the answer in m/s².) ::
from numericalunits import V, cm, e, me, m, s
Efield = 1e5 * (V / cm)
force = e * Efield # (e is the elementary charge)
accel = force / me # (me is the electron mass)
print(accel / (m / s**2)) # Answer --> 1.7588e18
Example 3: You measured a voltage as a function of the position of dial: 10 volts when the dial is at 1cm, 11 volts when the dial is at 2cm, etc. etc. Interpolate from this data to get the expected voltage when the dial is at 41mm, and express the answer in mV. ::
from numericalunits import cm, V, mm, mV
from numpy import array
from scipy.interpolate import interp1d
voltage_data = array([[1 * cm, 10 * V],
[2 * cm, 11 * V],
[3 * cm, 13 * V],
[4 * cm, 16 * V],
[5 * cm, 18 * V]])
f = interp1d(voltage_data[:,0], voltage_data[:,1])
print(f(41 * mm) / mV) # Answer --> 16200
Example 4: A unit mistake ... what is 1 cm expressed in atmospheres? ::
from numericalunits import cm, atm
print((1 * cm) / atm) # --> a randomly-varying number
# The answer randomly varies every time you run this (in a new Python
# session), indicating that you are violating dimensional analysis.
How it works
A complete set of independent base units (meters, kilograms, seconds, coulombs, kelvins) are defined as randomly-chosen positive floating-point numbers. All other units and constants are defined in terms of those. In a dimensionally-correct calculation, the units all cancel out, so the final answer is deterministic, not random. In a dimensionally-incorrect calculations, there will be random factors causing a randomly-varying final answer.
Included units and constants
Includes a variety of common units, both SI and non-SI, everything from frequency to magnetic flux. Also includes common physical constants like Planck's constant and the speed of light. Browse the source code to see a complete list. It is very easy to add in any extra units and constants that were left out.
Notes
Notes on implementation and use
-
What does it mean to "run the calculation again in a new Python session?" You know that you've started a new Python session if all the variable definitions have been forgotten. Three examples: In Spyder, each "Console" tab is its own session. In Jupyter, make a new Python session by selecting "Restart kernel". From the command line, each time you type
python blah.py, you are opening a new Python session. -
For little, self-contained calculations (a few lines that are all within a single module), it is possible to check the units without opening a new Python session: Run the function
numericalunits.reset_units()at the beginning of the calculation before any variables are defined; then check for dimensional errors by re-running the whole calculation (including thereset_units()part). Note that if you are usingfrom-style imports, likefrom numericalunits import cm, you need to put them afterreset_units()in the code. -
While debugging a program, it may be annoying to have intermediate values in the calculation that randomly vary every time you run the program. In this case, you can use
reset_units('SI')instead of the normalreset_units(). This puts all dimensionful variables in standard (MKS) SI units: All times are in seconds, all lengths are in meters, all forces are in newtons, etc. Alternatively,reset_units(123)uses123as the seed for the random-number generator. Obviously, in these modes, you will not get any indication of dimensional-analysis errors. As above, if you are going to use any version ofreset_units(), make sure you do it before any dimensionful variable is defined in any module. -
If you have a quantity you want to plot, store, pass between different parallel processes, etc., make sure you first express it in a known unit. (e.g. "energy expressed in joules" can be passed between processses, but "energy" cannot.) For parallel processing in particular, see
README appendix <https://github.com/sbyrnes321/numericalunits/blob/master/README_appendix.rst>_ for different ways of using the package, with example code. -
There are very rare, strange cases where the final answer does not seem to randomly vary even though there was a dimensional-analysis violation: For example, the expression
(1 + 1e-50 * cm / atm)fails dimensional analysis, so if you calculate it the answer is randomly-varying. But, it is only randomly varying around the 50th decimal point, so the variation is hidden from view. You would not notice it as an error. -
Since units are normal Python
float-type numbers, they follow the normal casting rules. For example,2 * cmis a pythonfloat, not anint. This is usually what you would want and expect. -
You can give a dimension to complex numbers in the same way as real numbers--for example
(2.1e3 + 3.9e4j) * ohm. -
Requires Python 3. (For Python 2 compatibility, install numericalunits version 1.23 or earlier.)
-
If you find bugs, please tell me by
email <http://sjbyrnes.com>_ orgithub issue board <https://github.com/sbyrnes321/numericalunits/issues>_. -
If you get overflows or underflows, you can edit the unit initializations. For example, the package sets the meter to a random numerical value between 0.1 and 10. Therefore, if you're doing molecular simulatio
Related Skills
node-connect
349.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.2kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
