hgrecco / pint

Operate and manipulate physical quantities in Python
http://pint.readthedocs.org/
Other
2.36k stars 466 forks source link

Angle has no "physical definition" #1877

Open nmadura opened 10 months ago

nmadura commented 10 months ago

using the term "physical definition" as defined at https://pint.readthedocs.io/en/stable/advanced/defining.html

https://github.com/hgrecco/pint/blob/f9e139e226f1a1196bf15493c1f3e7520e6f080c/pint/default_en.txt#L116C7-L116C7

radian isn't defined as the reference unit for angle, additionally there is no physical definition of angle. it seems like radian should be defined this way radian = [angle] = rad

currently there is no way to check if a unit is an angle using the following quantity.check('[angle]')

inside default_en.txt it seems like radians is the defacto reference unit for all angles.

# Angle
turn = 2 * π * radian = _ = revolution = cycle = circle
degree = π / 180 * radian = deg = arcdeg = arcdegree = angular_degree
arcminute = degree / 60 = arcmin = arc_minute = angular_minute
arcsecond = arcminute / 60 = arcsec = arc_second = angular_second
milliarcsecond = 1e-3 * arcsecond = mas
grade = π / 200 * radian = grad = gon
mil = π / 32000 * radian
andrewgsavage commented 10 months ago

This was last discussed here, where I also suggested defining angle as a base unit. https://github.com/hgrecco/pint/issues/1288

We could add something about angle acknowledging it isn't a base unit to https://pint.readthedocs.io/en/stable/user/angular_frequency.html

Could also suggest people try defining angle as you have if behaviour isn't as expected.

nmadura commented 10 months ago

We could add something about angle acknowledging it isn't a base unit to https://pint.readthedocs.io/en/stable/user/angular_frequency.html

Could also suggest people try defining angle as you have if behaviour isn't as expected.

RE: Documentation That is interesting, I flipped past that page a dozen times in the last week, and never registered it as the source of my concern. I might recommend changing the header to Angles and Angular Velocity

RE: angle as a physical definition I read through the aforementioned ticket quickly, and I must confess that if I saw someone write 1 rad/s == 1 rotation/s I would be greatly confused as 1 rad != 1 rotation, 2pi rad == 1 rotation. But I don't really want to wade into that discussion.

I wonder if it wouldn't make sense to have a flag in the UnitRegistry like rad_as_angle or rad_as_unitless

Personally I imagine treating radians as an angle is more common, my 9th grader learned about it this year in discussions of Unit Circles. the need for 1 Hz = 1rad/s (I imagine) is a more specialized need. However, I understand that isn't my decision.

andrewgsavage commented 10 months ago

I wonder if it wouldn't make sense to have a flag in the UnitRegistry like rad_as_angle or rad_as_unitless

I like that idea, 1-2 lines of code to change the UnitRegistry would be somewhat easier than copying the definition file and changing that one line and reloading it manually.

from pint import UnitRegistry

ureg = UnitRegistry()
ureg.define('radian = [angle] = rad')

Q_ = ureg.Quantity

a=Q_(1,"rad")
a.dimensionality
<UnitsContainer({})>

Unfortunately ureg.define doesn't override existing definitions. I can see this being troublesome to change as you'd need to deal with all the definitions that rely on angle too.

An arguement when initialising the registry that creates a default registry with the angle line changed could work well, ie ureg = UnitRegistry(angle_base_unit=True)

nmadura commented 10 months ago

I found out that defining [angle] as a base unit had a drawback when breaking a velocity out into it's component values I received an exception

# A registry file with the modification --  radian = [angle] = rad
>>> ureg = UnitRegistry('support/pint.default_en.txt')
>>> ang = 75 * ureg.degree
>>> ang.check('[angle]')
True
>>> speed = 30 * ureg.kph
>>> y_speed = speed * math.sin(ang.to('rad'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\264872\bin\VPD3\.venv\Lib\site-packages\pint\facets\plain\quantity.py", line 576, in __float__
    raise DimensionalityError(self._units, "dimensionless")
pint.errors.DimensionalityError: Cannot convert from 'radian' to 'dimensionless'
andrewgsavage commented 10 months ago

np.sin worked when I tried that

nmadura commented 10 months ago

Can confirm np.sin correctly handles the above case, math.sin does not