Discussion:
Angle Units For Trig Functions
(too old to reply)
Lawrence D'Oliveiro
2024-10-20 03:47:13 UTC
Permalink
I see that the Fortran 2023 spec has added a bunch of parallel trig
functions that work in degrees.

I find this sort of thing unnecessary. It seems conventional to add
functions for converting between degrees and radians, but a simpler way is
to simply define a conversion factor for each angle unit. One conversion
factor is simpler than two functions for each angle unit.

So trig functions always work in radians. Supposing we have

real, parameter :: DEG = PI / 180
real, parameter :: CIRCLE = 2 * PI
real, parameter :: RAD = 1

Then

sin(x) -- sin of x in radians
sin(x * DEG) -- x is in degrees
atan2(y, x) -- arctangent is in radians
atan2(y, x) / DEG -- arctangent is in degrees

and we can furthermore have equivalences like

sin(90 * DEG) = sin(0.25 * CIRCLE) = sin(PI / 2)

(to within rounding error, of course)

and it is easy enough to add other units, e.g.

real, parameter :: GRAD = PI / 200

Anybody remember those?
yeti
2024-10-20 04:27:57 UTC
Permalink
Post by Lawrence D'Oliveiro
and it is easy enough to add other units, e.g.
real, parameter :: GRAD = PI / 200
Anybody remember those?
Sure.

<https://en.wikipedia.org/wiki/Gradian>
--
Invisible default signature.
Steven G. Kargl
2024-10-20 05:35:25 UTC
Permalink
Post by Lawrence D'Oliveiro
I see that the Fortran 2023 spec has added a bunch of parallel trig
functions that work in degrees.
No. Fortran does not contain "a bunch of parallel trig functions
that work in degrees." It contains a bunch of elemental functions.
Post by Lawrence D'Oliveiro
I find this sort of thing unnecessary. It seems conventional to add
functions for converting between degrees and radians, but a simpler way is
to simply define a conversion factor for each angle unit. One conversion
factor is simpler than two functions for each angle unit.
program foo
real x, y
x = 30+360*1111
y = x * (4 * atan(1.) / 180)
print *, sind(x), sin(y)
end program foo

% gfcx -o z a.f90 && ./z
0.500000000 0.500089288

One of these values is exact, and one of these raises FE_INEXACT.
--
steve
Lawrence D'Oliveiro
2024-10-22 04:26:59 UTC
Permalink
% gfcx -o z a.f90 && ./z 0.500000000 0.500089288
One of these values is exact, and one of these raises FE_INEXACT.
Does it work for 29° and 31° as well? What’s so special about 30°?
Steven G. Kargl
2024-10-22 07:14:22 UTC
Permalink
Post by Lawrence D'Oliveiro
% gfcx -o z a.f90 && ./z 0.500000000 0.500089288
One of these values is exact, and one of these raises FE_INEXACT.
Does it work for 29° and 31° as well? What’s so special about 30°?
Really? This is high school trig.

For units of degree, mathematically sin(30) = 1/2, exactly!.
sin(30+n*360) = 1/2 is also exact.
--
steve
Lawrence D'Oliveiro
2024-10-22 20:50:27 UTC
Permalink
Post by Steven G. Kargl
Post by Lawrence D'Oliveiro
% gfcx -o z a.f90 && ./z 0.500000000 0.500089288
One of these values is exact, and one of these raises FE_INEXACT.
Does it work for 29° and 31° as well? What’s so special about 30°?
Really? This is high school trig.
For units of degree, mathematically sin(30) = 1/2, exactly!.
sin(30+n*360) = 1/2 is also exact.
What’s so special about 30°? Does that extend to 29° and 31° as well?
Steven G. Kargl
2024-10-22 22:32:34 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by Steven G. Kargl
Post by Lawrence D'Oliveiro
% gfcx -o z a.f90 && ./z 0.500000000 0.500089288
One of these values is exact, and one of these raises FE_INEXACT.
Does it work for 29° and 31° as well? What’s so special about 30°?
Really? This is high school trig.
For units of degree, mathematically sin(30) = 1/2, exactly!.
sin(30+n*360) = 1/2 is also exact.
What’s so special about 30°? Does that extend to 29° and 31° as well?
Did you take a high school trigonometry class?
--
steve
Lawrence D'Oliveiro
2024-10-22 23:53:54 UTC
Permalink
Post by Steven G. Kargl
Did you take a high school trigonometry class?
Pro tip: answering a question with a question can be seen as an attempt to
deflect from the issue.
Steven G. Kargl
2024-10-23 00:45:08 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by Steven G. Kargl
Did you take a high school trigonometry class?
Pro tip: answering a question with a question can be seen as an attempt
to deflect from the issue.
In this case, my question, quoted above, is trying to gauge the
educational level of the recipient of an answer. Too much effort
may be required to bring the recipient to elementary school level.

Instead of seeking such information, so that an informed answer
could be formulated, I suppose I should simply ask the impolite
question: "Where you born stupid, or did you have to work at?"
--
steve
Louis Krupp
2024-10-23 00:14:14 UTC
Permalink
Post by Lawrence D'Oliveiro
% gfcx -o z a.f90 && ./z 0.500000000 0.500089288
One of these values is exact, and one of these raises FE_INEXACT.
Does it work for 29° and 31° as well? What’s so special about 30°?
https://en.wikipedia.org/wiki/Niven%27s_theorem

Louis
Lawrence D'Oliveiro
2024-10-23 00:57:23 UTC
Permalink
Post by Louis Krupp
Post by Lawrence D'Oliveiro
% gfcx -o z a.f90 && ./z 0.500000000 0.500089288
One of these values is exact, and one of these raises FE_INEXACT.
Does it work for 29° and 31° as well? What’s so special about 30°?
https://en.wikipedia.org/wiki/Niven%27s_theorem
So a whole set of extra functions, just to get a nice result for one
value?
David Jones
2024-10-23 04:06:26 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by Louis Krupp
Post by Lawrence D'Oliveiro
% gfcx -o z a.f90 && ./z 0.500000000 0.500089288
One of these values is exact, and one of these raises FE_INEXACT.
Does it work for 29° and 31° as well? What’s so special about 30°?
https://en.wikipedia.org/wiki/Niven%27s_theorem
So a whole set of extra functions, just to get a nice result for one
value?
Did you take a high school trigonometry class?
Lawrence D'Oliveiro
2024-10-23 04:41:29 UTC
Permalink
Post by Steven G. Kargl
Did you take a high school trigonometry class?
You seem obsessed with that.
R Daneel Olivaw
2024-10-23 05:59:24 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by Steven G. Kargl
Did you take a high school trigonometry class?
You seem obsessed with that.
You have avoided answering that question so far.
Lawrence D'Oliveiro
2024-10-23 06:25:02 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by Steven G. Kargl
Did you take a high school trigonometry class?
You seem obsessed with that.
So your favourite functions return an exact result for sin 30°. Do they
return an exact result for cos 30° as well?

.

.

.

.

.

.

(crickets)

.

.

.

.

.
Steven G. Kargl
2024-10-23 14:38:17 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by Lawrence D'Oliveiro
Post by Steven G. Kargl
Did you take a high school trigonometry class?
You seem obsessed with that.
So your favourite functions return an exact result for sin 30°. Do they
return an exact result for cos 30° as well?
Nope. For REAL x, COSD(x) returns an exact result for all N >= 0
that satisfies 60+N*360 < 2**23.
--
steve
Neil
2024-10-23 21:21:41 UTC
Permalink
Post by Steven G. Kargl
Post by Lawrence D'Oliveiro
Post by Lawrence D'Oliveiro
Post by Steven G. Kargl
Did you take a high school trigonometry class?
You seem obsessed with that.
So your favourite functions return an exact result for sin 30°. Do they
return an exact result for cos 30° as well?
Nope. For REAL x, COSD(x) returns an exact result for all N >= 0
that satisfies 60+N*360 < 2**23.
Could you give an example of where sind and cosd might be of use in a
piece of numerical software?
Steven G. Kargl
2024-10-23 22:22:48 UTC
Permalink
Post by Neil
Post by Lawrence D'Oliveiro
Post by Lawrence D'Oliveiro
Post by Steven G. Kargl
Did you take a high school trigonometry class?
You seem obsessed with that.
So your favourite functions return an exact result for sin 30°. Do
they return an exact result for cos 30° as well?
Nope. For REAL x, COSD(x) returns an exact result for all N >= 0 that
satisfies 60+N*360 < 2**23.
Could you give an example of where sind and cosd might be of use in a
piece of numerical software?
I don't use degree trig functions in my codes. Conversion of lat/long
to UTM may be a place one might use sind and/or cosd. Seattle is
at 47.6061° N, 122.3328° W. I've never seen someone refer to the
location as 0.83088 N, 2.13511 W.
--
steve
Louis Krupp
2024-10-23 22:38:41 UTC
Permalink
Post by Neil
Post by Lawrence D'Oliveiro
Post by Lawrence D'Oliveiro
Post by Steven G. Kargl
Did you take a high school trigonometry class?
You seem obsessed with that.
So your favourite functions return an exact result for sin 30°. Do they
return an exact result for cos 30° as well?
Nope. For REAL x, COSD(x) returns an exact result for all N >= 0
that satisfies 60+N*360 < 2**23.
Could you give an example of where sind and cosd might be of use in a
piece of numerical software?
===
program scd
implicit none

real angle_in_degrees, ad_sin, ad_cos

do while (.true.)
    write(*, *) 'Enter angle in degrees, enter 0 to quit'
    read(*, *) angle_in_degrees
    if (angle_in_degrees .eq. 0) then
        exit
    end if
    ad_sin = sind(angle_in_degrees)
    ad_cos = cosd(angle_in_degrees)
    write(*, *) 'Sine: ', ad_sin, '  Cosine: ', ad_cos
end do

end program scd
===

Seriously, though, if you're interfacing with people, degrees are easier
and more familiar than radians. Aircraft headings are set and reported
in degrees, and who really wants to remember that runway 26 is at an
approximate heading of 4.54 radians?

If your input values are in degrees, and if you don't have to convert
them to radians, why go to the trouble of stripping off multiples of 360
before multiplying by (your approximation of) PI divided by 180?

Louis
Louis Krupp
2024-10-24 01:17:11 UTC
Permalink
Post by Louis Krupp
Seriously, though, if you're interfacing with people, degrees are easier
and more familiar than radians.
But trig calculations are easier in radians. And it is easy to convert
back and forth, as I explained in the posting that started this thread.
Are trig calculations really easier in radians?

And keep in mind that radians are fractions or multiples of PI, but PI
multiplied by a non-zero algebraic number is transcendental and cannot
be represented exactly on a computer. The 360 degrees of a circle, on
the other hand, can be divided by first and second powers of 3 and by 5
and by several powers of 2 and the result can be represented without
loss of precision.

Radians make total sense in math ("e to the power of (i times 180
degrees) equals -1" doesn't have the same ring to it); in computing,
it's not as clear.

Louis
Lawrence D'Oliveiro
2024-10-24 04:43:59 UTC
Permalink
Post by Louis Krupp
Are trig calculations really easier in radians?
Consider the Euler identity:


e + 1 = 0

That only takes that simple form in radians.

Do you know the Taylor series for e^x? You can use that, and the above
formula, to derive Taylor series for sin and cos.

Also, you have useful properties like

sin x ≃ x as x → 0

Again, this only works in radians.
Steven G. Kargl
2024-10-24 02:17:15 UTC
Permalink
Post by Louis Krupp
Seriously, though, if you're interfacing with people, degrees are easier
and more familiar than radians.
But trig calculations are easier in radians. And it is easy to convert
back and forth, as I explained in the posting that started this thread.
Easier?

program foo
real*8 x, y
real*8, parameter :: deg2rad = 4 * atan(1.d0) / 180
x = 137*180
y = x * deg2rad
print *, sind(x), sin(y)
end program foo

% gfcx -o z -Wall a.f90 && ./z
-0.0000000000000000 -9.8590724568376608E-016

One of these values is wrong.

For x = (n + 1) * 180 and n < 2**23, sind(x) = +-0, exactly.
For y = x * pi / 180, sin(x) never equals +-0.

You seem to be missing that argument reduction for sind(x)
is much easier than argument reduction for sin(x).
--
steve
Lawrence D'Oliveiro
2024-10-24 04:47:06 UTC
Permalink
Post by Steven G. Kargl
One of these values is wrong.
Only if you assume the input numbers were somehow “exact” or “perfect” to
begin with.

There’s an old principle in computing: “Garbage In, Garbage Out”.
Post by Steven G. Kargl
You seem to be missing that argument reduction for sind(x)
is much easier than argument reduction for sin(x).
But that only worked for one angle, and for nothing else.
Steven G. Kargl
2024-10-24 05:06:37 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by Steven G. Kargl
One of these values is wrong.
Only if you assume the input numbers were somehow “exact” or “perfect” to
begin with.
There’s an old principle in computing: “Garbage In, Garbage Out”.
People discussing Fortran normally use floating point math when
computing sin(x) or any other function of a "real" quantity.
Post by Lawrence D'Oliveiro
Post by Steven G. Kargl
You seem to be missing that argument reduction for sind(x)
is much easier than argument reduction for sin(x).
But that only worked for one angle, and for nothing else.
ROFL.

For sin(x), argument reduction will give sin(0) = 0, exactly.
That's one angle.

For sind(x), argument reduction will give sind(x) = 0, exactly,
for countable many angles.
--
steve
Lawrence D'Oliveiro
2024-10-24 05:22:53 UTC
Permalink
For sin(x), argument reduction will give sin(0) = 0, exactly. That's one
angle.
More generally, it gives sin(x) ≃ x, for uncountably many angles.
For sind(x), argument reduction will give sind(x) = 0, exactly,
for countable many angles.
But it never gives sind(x) anywhere close to x.
Steven G. Kargl
2024-10-24 05:31:13 UTC
Permalink
Post by Lawrence D'Oliveiro
For sin(x), argument reduction will give sin(0) = 0, exactly. That's one
angle.
More generally, it gives sin(x) ≃ x, for uncountably many angles.
For sind(x), argument reduction will give sind(x) = 0, exactly,
for countable many angles.
But it never gives sind(x) anywhere close to x.
Never claimed sind(x) for x near 0 was exact.

It is, however, for floatin point arithmetic,
correct to less than or equal to 0.5 ULP. Now,
got read Goldberg.
--
steve
Lawrence D'Oliveiro
2024-10-24 05:46:53 UTC
Permalink
It is, however, for floatin point arithmetic, correct to less than or
equal to 0.5 ULP.
After making such a big deal about exactness, now you’re talking
acceptable rounding error, which radians-based functions are quite capable
of supplying?
Louis Krupp
2024-10-24 10:41:34 UTC
Permalink
Post by Lawrence D'Oliveiro
For sin(x), argument reduction will give sin(0) = 0, exactly. That's one
angle.
More generally, it gives sin(x) ≃ x, for uncountably many angles.
Are you sure about that? Is sin(x) = x for any value of x besides 0?
Post by Lawrence D'Oliveiro
For sind(x), argument reduction will give sind(x) = 0, exactly,
for countable many angles.
But it never gives sind(x) anywhere close to x.
Are you sure? sind(x) = sin(A * x) where A is PI/180, and if x is zero,
sin(A * 0) = sin(0) = 0 = x.

What sind(x) doesn't do is satisfy the condition that the limit as x
approaches zero of sin(x)/x is 1. For sind(x), that limit, as far as I
can tell, is A.

Louis

Lawrence D'Oliveiro
2024-10-23 23:14:11 UTC
Permalink
Post by Neil
Could you give an example of where sind and cosd might be of use in a
piece of numerical software?
Something about high-school trig classes, I think it was.
Louis Krupp
2024-10-23 11:14:02 UTC
Permalink
Post by Lawrence D'Oliveiro
Post by Louis Krupp
% gfcx -o z a.f90 && ./z 0.500000000 0.500089288
One of these values is exact, and one of these raises FE_INEXACT.
Does it work for 29° and 31° as well? What’s so special about 30°?
https://en.wikipedia.org/wiki/Niven%27s_theorem
So a whole set of extra functions, just to get a nice result for one
value?
For arguments in degrees, functions taking arguments in degrees are
slightly more accurate than functions taking arguments converted to
radians. Here's an expanded version of Steve's program:
===
subroutine s_real
    implicit none
    real x, y
    x = 30+360*1111
    y = x * (4 * atan(1.) / 180)
    print *, 'single precision', sind(x), sin(y)
end subroutine s_real

subroutine s_double
    implicit none
    double precision x, y
    x = 30+360*1111
    y = x * (4 * datan(1.d0) / 180)
    print *, 'double precision', dsind(x), dsin(y)
end subroutine s_double

program foo
    implicit none

    call s_real
    call s_double
end program foo
===

The output using gfortran:
===
 single precision  0.500000000      0.500089288
 double precision  0.50000000000000000       0.50000000000024070
===

For 30° plus a large multiple of 360°, the degree-argument function is
(1) demonstrably exact and (2) more accurate using single precision
values than the radian-argument function using converted double
precision values. For just plane 30° (i.e., x = 30), the results are
slightly surprising: === single precision 0.500000000 0.500000000 double
precision 0.50000000000000000 0.49999999999999994 === So you *could*
write your own sind function, converting the argument to its equivalent
modulo 360 (and handling negative arguments properly) and then to
radians and finally calling the radian sine function, or you could just
use the sind intrinsic that's provided. No one is forcing you to do one
or the other, and if your angle is already in radians, no one is
suggesting that you convert it to degrees just so you can call the
degree sine function. What makes 30° special? Along with 0° and 90°, it
has a rational sine (0.5) that can also be represented exactly in IEEE
floating point. The cosine of 30°, as I'm sure you know, is (in Fortran)
sqrt(3.0) / 2.0, which is irrational and not as obviously correct or
incorrect as the sine of 30°. Louis
Loading...