PainterQubits / Unitful.jl

Physical quantities with arbitrary units
Other
613 stars 112 forks source link

multiple issues with ratios of logarithmic units #587

Open MattEttus opened 2 years ago

MattEttus commented 2 years ago

logarithmic units in the following don't simplify properly, and sometimes dividing a by b works, but it's inverse does not.

See example using power flux densities:

max_PFD = (-100)u"dBm/m^2/MHz"

tx_power = @dB 10W/mW r = 1000u"km" tx_gain = 30u"dB" bandwidth = 10u"MHz"

pfd_on_ground = tx_power tx_gain / (4π r^2) / bandwidth

Units in this first ratio don't simplify properly to dimensionless or plain dB, but the calculation is correct

ratio = max_PFD/pfd_on_ground

This second ratio is the inverse of the first and should also be dimensionless:

inv_ratio = pfd_on_ground/max_PFD

But it throws a dimension error instead: julia> inv_ratio = pfd_on_ground/max_PFD ERROR: DimensionError: m² mW km⁻² and 7.957747154594767e8 mW⁻¹ are not dimensionally compatible.

sostock commented 2 years ago

Units in this first ratio don't simplify properly to dimensionless or plain dB, but the calculation is correct

ratio = max_PFD/pfd_on_ground

The package doesn’t automatically simplify different units (1 m/m gets simplified to 1, but 1 mm/m does not get simplified). This is because sometimes you actually want to keep units like mm/m. To get a unitless number, you can convert to the NoUnits unit:

julia> ratio = max_PFD/pfd_on_ground
[-89.00790135977903 dBm] km^2 m^-2 mW^-1

julia> ratio |> NoUnits
0.0012566370614359175

However, we could consider adding an exception for logarithmic units, so that dBm / mW would get simplified, because I don’t think someone would want to keep dBm / mW as a unit. (We still wouldn’t automatically simplify km^2 m^-2, i.e., the result would be 1.2566370614359174e-9 km^2 m^-2). In a way, one could think of dBm and mW as "the same unit".

sostock commented 2 years ago

This second ratio is the inverse of the first and should also be dimensionless:

inv_ratio = pfd_on_ground/max_PFD

But it throws a dimension error instead

I think we could allow this, but we would have to decide what units the result should have. Unfortunately, we don’t have something like "inverse decibels" right now. I see several possibilities:

  1. implement inverse logarithmic units (but I think something like [1.0 dBm]^-1 mW m^2 km^-2 would be rather confusing to handle)
  2. Return the result of something / dBm in units of something / mW (i.e., always convert the logarithmic unit to the linear one). But consider that, e.g., the reference level of dBu is sqrt(0.6)V, not 1V. Should something / dBu be in units of something / V?
  3. Always simplify mW / dBm away. Then we must decide what to do in the case W / dBm.
MattEttus commented 2 years ago

I think mW/dBm and W/dBm should always be simplified away, so I would lean towards 3. W/dBm is dimensionless. 1W divided by 0dBm should return either 1000 or 30dB.

Really, I think dB and other log units are more about presentation rather than meaning, while meters, watts, etc. are about meaning. If it were up to me I would always do all calculation and storage in the linear units and keep dB and the other log units as merely a flag to tell what the default presentation was.