pythonpint

DimensionalityError when calculating an exponential value "exp(x)" with pint units


I am trying to calculate an exponential value exp with a python pint variable that includes a unit.

import pint
var = 0.5 * unit_reg.minute
math.exp(-var)

with this I get the error: DimensionalityError: Cannot convert from 'minute' to 'dimensionless'

This also seems the case when I calculate it directly

import pint
var = 0.5 * unit_reg.minute
math.e ** -var

as well as use numpy

import pint
import numpy as np
var = 0.5 * unit_reg.minute
np.exp(-var)

Maybe I am missing something here. But is there another way of doing the calculations rather than extracting the magnitude and units from the variable and set things together again?

With this way there is no DimensionalityError

import pint
var = 0.5 * unit_reg.minute
math.exp(-var.magnitude) * var.units

I am guessing, that math.exp is expecting a dimensionless variable as specified in example 11 on the pint numpy description


Solution

  • Units matter! On good physical grounds. 1000 mm = 1 m, but exp(-1000) is obviously very different from exp(-1).

    Mathematical functions like exp, log, sin, cos, ... expect pure numbers as their arguments. (And they give pure numbers as outputs as well - don't try to assign them units just because their arguments were measured in specific units.)

    If you have a formula that implies a specific set of units then (a) you should state that explicitly; (b) where you are using units you can code it by simply dividing by that unit.

    You might want to look up "dimensional analysis" (and also note that "dimensions" are not "units").

    import pint
    import math
    ureg = pint.UnitRegistry()
    
    var = 0.5 * ureg.minute
    # print( math.exp(-var) )                    # this fails because the result depends on the units that var is measured in
    print( math.exp(-var/ureg.minute) )          # this is OK
    print( math.exp(-var/(60 * ureg.second) ) )  # this is also OK (and gives the same result)