Unit Conversion#
This tutorial covers converting quantities between different units, extracting numeric values, and working with dimensionless quantities.
import brainunit as u
import jax.numpy as jnp
Converting Between Units with to_decimal()#
The to_decimal() method converts a Quantity to a plain numeric array expressed in the target unit.
It extracts the mantissa scaled to the given unit.
distance = 5.0 * u.kmeter
print('Original:', distance)
print('In meters:', distance.to_decimal(u.meter))
print('In centimeters:', distance.to_decimal(u.cmeter))
Original: 5. km
In meters: 5000.0
In centimeters: 500000.0
voltage = jnp.array([100., 200., 300.]) * u.mV
print('Original:', voltage)
print('In volts:', voltage.to_decimal(u.volt))
print('In microvolts:', voltage.to_decimal(u.uvolt))
Original: [100. 200. 300.] mV
In volts: [0.1 0.2 0.3]
In microvolts: [100000. 200000. 300000.]
Converting to an incompatible unit raises an error:
try:
distance.to_decimal(u.second)
except Exception as e:
print(type(e).__name__, ':', e)
UnitMismatchError : Cannot convert to the decimal number using a unit with different dimensions. (units are km and s).
Rescaling with in_unit()#
Unlike to_decimal() which returns a plain array, in_unit() returns a new Quantity
expressed in the target unit — preserving the unit information.
t = 1500.0 * u.ms
print('Original:', t)
print('In seconds:', t.in_unit(u.second))
print('In microseconds:', t.in_unit(u.usecond))
Original: 1500. ms
In seconds: 1.5 s
In microseconds: 1.5e+06 us
# in_unit preserves Quantity type
t_sec = t.in_unit(u.second)
print('Type:', type(t_sec))
print('Unit:', t_sec.unit)
print('Mantissa:', t_sec.mantissa)
Type: <class 'saiunit.Quantity'>
Unit: s
Mantissa: 1.5
Dimensionless Quantities#
When you divide two quantities with the same dimension, the result is dimensionless.
Dimensionless results are automatically returned as plain jax.Array values.
ratio = (3.0 * u.kmeter) / (4.0 * u.meter)
print('Ratio:', ratio)
print('Type:', type(ratio))
Ratio: 750.0
Type: <class 'float'>
# Since the result is already a plain number, you can convert directly
print('As float:', float(ratio))
print('As int:', int(ratio))
As float: 750.0
As int: 750
When dividing quantities with different scales but same dimension, brainunit automatically handles the scale conversion:
print('km / m:', (6.0 * u.kmeter) / (2.0 * u.meter)) # = 3000
print('ms / us:', (1.0 * u.ms) / (500.0 * u.usecond)) # = 2.0
print('mV / V:', (100.0 * u.mV) / (2.0 * u.volt)) # = 0.05
km / m: 3000.0
ms / us: 2.0
mV / V: 0.05
Converting Quantities to Python Scalars#
Only dimensionless quantities can be converted to Python scalars with float() or int().
Quantities with units will raise a TypeError.
# This works: first convert to decimal, then to float
voltage = 3.0 * u.mV
print('As volts (float):', float(voltage.to_decimal(u.volt)))
As volts (float): 0.003
# Direct float() on a quantity with units fails
try:
float(3.0 * u.mV)
except TypeError as e:
print('TypeError:', e)
TypeError: Only dimensionless scalar quantities can be converted to Python scalars. But got 3. mV
Extracting Mantissa and Unit#
You can decompose a Quantity into its numeric part and unit using split_mantissa_unit()
or the .mantissa and .unit attributes.
q = jnp.array([1.0, 2.0, 3.0]) * u.newton
# Using attributes
print('Mantissa:', q.mantissa)
print('Unit:', q.unit)
print('Dimension:', q.dim)
Mantissa: [1. 2. 3.]
Unit: N
Dimension: m kg s^-2
# Using split_mantissa_unit
mantissa, unit = u.split_mantissa_unit(q)
print('Mantissa:', mantissa)
print('Unit:', unit)
Mantissa: [1. 2. 3.]
Unit: N
# Reconstruct the quantity
q_reconstructed = mantissa * unit
print('Reconstructed:', q_reconstructed)
Reconstructed: [1. 2. 3.] N
Checking Dimension Compatibility#
Before converting, you can check if two quantities or units have compatible dimensions.
print('meter and km compatible?', u.have_same_dim(u.meter, u.kmeter))
print('meter and second compatible?', u.have_same_dim(u.meter, u.second))
print('mV and volt compatible?', u.have_same_dim(u.mV, u.volt))
print('newton and kg*m/s^2?', u.have_same_dim(u.newton, u.kilogram * u.meter / u.second**2))
meter and km compatible? True
meter and second compatible? False
mV and volt compatible? True
newton and kg*m/s^2? True
# is_dimensionless checks if a value has no physical dimension
print('Scalar is dimensionless?', u.is_dimensionless(3.14))
print('Ratio is dimensionless?', u.is_dimensionless((5.0 * u.meter) / (2.0 * u.meter)))
print('Quantity with unit is dimensionless?', u.is_dimensionless(5.0 * u.meter))
Scalar is dimensionless? True
Ratio is dimensionless? True
Quantity with unit is dimensionless? False
Unit Display with display_in_unit()#
You can display a quantity in a specific unit without losing the Quantity type.
distance = 2500.0 * u.meter
print('Display in km:', u.display_in_unit(distance, u.kmeter))
print('Display in cm:', u.display_in_unit(distance, u.cmeter))
Display in km: 2.5 km
Display in cm: 250000. cm
Conversion Between Unit Systems#
brainunit supports both SI and non-SI units, allowing conversions between systems.
# Length conversions
d = 1.0 * u.mile
print('1 mile in meters:', d.to_decimal(u.meter))
print('1 mile in km:', d.to_decimal(u.kmeter))
print('1 mile in feet:', d.to_decimal(u.foot))
1 mile in meters: 1609.344
1 mile in km: 1.609344
1 mile in feet: 5280.0
# Pressure conversions
p = 1.0 * u.atmosphere
print('1 atm in Pascal:', p.to_decimal(u.pascal))
print('1 atm in bar:', p.to_decimal(u.bar))
print('1 atm in mmHg:', p.to_decimal(u.mmHg))
1 atm in Pascal: 101325.0
1 atm in bar: 1.01325
1 atm in mmHg: 760.0
# Energy conversions
e = 1.0 * u.joule
print('1 joule in calories:', e.to_decimal(u.calorie))
print('1 joule in eV:', e.to_decimal(u.electron_volt))
print('1 joule in erg:', e.to_decimal(u.erg))
1 joule in calories: 0.2390057361376673
1 joule in eV: 6.241509074460762e+18
1 joule in erg: 10000000.0
Summary#
Method |
Returns |
Use Case |
|---|---|---|
|
|
Extract numeric value in target unit |
|
|
Convert to target unit, keeping Quantity type |
|
|
Get raw numeric value (current unit scale) |
|
|
Decompose into parts |
|
|
Format for display |
|
|
Check compatibility before conversion |