[ANN] UnitfulAngles: a unitful units package for angles

Hello people!
So, after a few iterations (1, 2, and 3) and some thought, here is a supplemental units package for Unitful.jl that deals with angles: UnitfulAngles.jl.

I want to register it as soon as I solve issue #1.

Thoughts, comments, etc are very much appreciated!

3 Likes

Nice work.

If you let tan(1u"octant") map to tand(45) instead of tan((1//4)Ď€), you will get better accuracy.

I’m not sure why you introduce myRad and my°. Why not use the radians and degrees already provided by Unitful?

Good catch on the tand (I only took care of the cosd and sind).

I didn’t base my angular system on the one already provided in Unitful.jl because tons of the units here can be expressed as a rational number of the full turn. Unitful.jl’s approach was to base the angles on radians. While that makes total sense, it feels like a shame to lose accuracy by using the radians from Unitful.jl.

The degree from Unitful does not lose accuracy. (For example, sin(180u"°") returns 0.0.) It should be safe to define a turn as 360 of Unitful’s degrees.

I played around, and you are of course right. But I don’t understand:
We can divide the full turn by integers OR by irrational numbers. The first choice must be more accurate because we can accurately represent it in Julia. If I set the base unit for angles as radians (which is not accurately represented as a float), then all the units will be slightly off. If I base it on the full-turn, then only radians and diameter-parts will be slightly off (which they are already).
I’m obviously wrong here somewhere… What am I missing? :confused:

When you represent a “degree” as π/180 and a “turn” as 2π, the conversion from turns to degrees will still be exact, because the conversion factor, computed as (2π)/(π/180) still comes out to 360.0 exactly.

Conversion in the other direction might not be exact, because 1/360 is not exactly representable in floating point. If you want to do exact unit conversion with rational numbers, I guess you could define additional methods for Unitful.convfact. (Or just submit a PR to Unitful, asking them to make a “turn” the reference unit for angles.)

Note that your current implementation gives problems whenever someone tries to convert between Unitful’s degrees or radians and your units. For example: uconvert(u"rad", 1*u"myRad") comes out to 0.15915494309189535 rad.

When I think about it, probably the best thing would be to make all of this a PR to Unitful, instead of a separate package.

1 Like

The argument for a PR would be that these angular goodies would be as useful for everyone as other things in pkgdefaults.jl. The argument against it would be that 14 additional degree units warrants its own package.
I’m really OK with whichever. Maybe @ajkeller34 can weight in on this?

I’m also in favor of complete integration into Unitful, it is designed in such a way that the number of units available doesn’t really pose any problems.

I disagree with this. Unitful has been designed with the goal of making it possible for the user to define their own units easily. Adding a bunch of esoteric units to the default package just increases the likelihood that the unit abbreviations will collide. The user currently doesn’t have any real control over what is added to the u"..." macro namespace.

3 Likes

Maybe some middle-ground would make sense?

Make a PR for Unitful.jl with these:

  • halfTurn “π”
  • the sinpi versions of the trigonometric functions for this halfTurn unit
  • the inverse functions returning angle units

and keep the following in a separate UnitfulAngles.jl package:

  • Turn, Quadrant, Sextant, Octant, ClockPosition, HourAngle, CompassPoint, Hexacontade, BinaryRadian, DiameterPart, Gradian, Arcminute, and Arcsecond.
  • the sinpi and asin for those
  • time - angle conversion

Too fragmented? Perfect?

I would prefer to keep these definitions in UnitfulAngles.jl, pretty much for the reasons @Michael_Eastwood mentioned. Also, I’m wary to maintain/test a lot of units that I may never use personally, which is one of several reasons why I made it possible to extend Unitful using additional packages. I imagine people in need of specialty angle units wouldn’t mind the additional using UnitfulAngles.

1 Like

Well then, I’ll fix up UnitfulAngles.jl and register it then. Thanks for all the input people!

@ajkeller34 Would you still accept a PR changing the angle reference from 1 radian to 2Ď€ radians? That would make it possible for 3rd party packages like UnitfulAngles to provide exact conversion between rational numbers with units that are expressed in fractions of a turn.

1 Like

“Reference units” are only used in Unitful when you define a new dimension, as an implementation detail. Angles are dimensionless, so there are no reference units for angles. I defined 1u"rad" == 1 because anything else would give incorrect results (if I converted 2π*u"rad" * 1u"m" into units of m, that had better be equal to 2π*u"m"). I think @yakir12 realized this in his most recent commit. He could have equivalently defined a turn as 2π instead of 2π*u"rad" if he wanted independence from units defined in Unitful, but I don’t think there is a difference in the resulting behavior.

1 Like