# Inverse trigonometric tangent

**URL:** https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734
**Category:** Users
**Created:** [August 28, 2024, 4:04am UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734 "2024-08-28T04:04:27Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)
#### Post date: [August 28, 2024, 4:04am UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/1 "2024-08-28T04:04:27Z")

</div>

The category should probably read Documentation.

I like brief in doco but sometimes it will bite you. This should be an issue  
but I am unsure how to word it properly. So I just put it down here while it  
is in my head.

Currently **atan2** () says

```Chapel
This is equivalent to the arc tangent of y / x except
that the signs of y and x are used to determine the
quadrant of the result.

```

... not reeeeeally

It is not the equivalent of the arctangent. It **IS** the arctangent. If the  
intended meaning was that it was the equivalent of **atan** () then it is  
most definitely wrong because **atan** () returns a result in [-pi/2,+pi/2]  
whereas **atan2** () returns a result in [-pi,+pi].

How about something like:

```Chapel
This is the arc (or inverse) tangent of y / x which lies in
the inclusive range [-pi,+pi] where the signs of y and x are
used to determine the quadrant of the result.

```

Somebody might have better words.

The words for **atan** () should qualify the range of its result.

Is this a bigger issue which means all ranges should be mentioned??

Sorry if I am making work for somebody.

---

<div class="post-metadata">

### Author: ![lydia](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@lydia](https://chapel.discourse.group/u/lydia)
#### Post date: [August 28, 2024, 3:13pm UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/2 "2024-08-28T15:13:55Z")

</div>

Hi Damian,

That all seems reasonable to me, thanks for pointing it out!

Lydia

---

<div class="post-metadata">

### Author: ![lydia](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@lydia](https://chapel.discourse.group/u/lydia)
#### Post date: [August 28, 2024, 3:35pm UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/3 "2024-08-28T15:35:04Z")

</div>

PR is here if you'd like to take a look!

> <https://github.com/chapel-lang/chapel/pull/25832>
>
> On Discourse, Damian pointed out that the documentation for \`atan2\` was not as a…ccurate as it could be - atan2 is not the equivalent of the arctangent, it is the arctanget. He also suggested adding information about the range of the result for it and \`atan\`.
> 
> Double checked the built documentation looked right

Lydia

---

<div class="post-metadata">

### Author: ![tbzy](https://avatars.discourse-cdn.com/v4/letter/t/bcef8e/32.png) [@tbzy](https://chapel.discourse.group/u/tbzy)
#### Post date: [August 28, 2024, 7:55pm UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/4 "2024-08-28T19:55:22Z")

</div>

Just FYI, here are the words used in some help commands for [atan2 (wikipedia)](https://en.wikipedia.org/wiki/Atan2). In the case of Julia (`atan()` overloaded for 1 and 2 args),

```julia
> ?atan
  atan(y)
  atan(y, x)

  Compute the inverse tangent of y or y/x, respectively.

  For one argument, this is the angle in radians between
  the positive x-axis and the point (1, y), returning a value
  in the interval [-\pi/2, \pi/2].

  For two arguments, this is the angle in radians between
  the positive x-axis and the point (x, y), returning a value
  in the interval [-\pi, \pi]. This corresponds to a standard atan2
  (https://en.wikipedia.org/wiki/Atan2) function. Note that
  by convention atan(0.0,x) is defined as \pi and atan(-0.0,x)
  is defined as -\pi when x < 0.

```

and Python (`np.arctan2()`):

```python
>>> help(np.arctan2)
    arctan2(x1, x2, ...)

    Element-wise arc tangent of ``x1/x2`` choosing
    the quadrant correctly.
    
    The quadrant (i.e., branch) is chosen so that ``arctan2(x1, x2)``
    is the signed angle in radians between the ray ending
    at the origin and passing through the point (1,0), and the ray
    ending at the origin and passing through the point (`x2`, `x1`).
    (Note the role reversal: the "`y`-coordinate" is the first
    function parameter, the "`x`-coordinate" is the second.)
    By IEEE convention, this function is defined for `x2` = +/-0 and
    for either or both of `x1` and `x2` = +/-inf (see Notes for
    specific values).
    ...

```

BTW, I feel the de facto standard (?) order of the arguments  
in many libraries ("y first, x second") is rather confusing (e.g. the above help page in Python)  
and so wonder why the initial Fortran implementation chose such order historically...

PS: The above wikipage had some explanations [(Argument order)](https://en.wikipedia.org/wiki/Atan2#Argument_order).

---

<div class="post-metadata">

### Author: ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)
#### Post date: [August 29, 2024, 3:29am UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/5 "2024-08-29T03:29:14Z")

</div>

I was mainly worried about that use of _equivalent_ and the fact that any wording needed to very forcefully remind people that **atan** () and **atan2** () return a result with a very different range.

For the latter reason, I was thinking the **atan2** () name should probably be preserved. But that puts me at odds with Stephen Wolfram and that's only a tiny step down from arguing with Donald Knuth. So, no, not going there. I will stick to arguing with Brad Chamberlain (and even then, I am probably wrong).

---

<div class="post-metadata">

### Author: ![tbzy](https://avatars.discourse-cdn.com/v4/letter/t/bcef8e/32.png) [@tbzy](https://chapel.discourse.group/u/tbzy)
#### Post date: [August 29, 2024, 3:47am UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/6 "2024-08-29T03:47:34Z")

</div>

For clarity, I have no problem with `atan2()` as-is (i.e. the y -\> x order), but was just curious about the history for this choice (and I am sorry to have derailed the topic somewhat...)  
In practice, I guess it would be even more confusing to change the order at this stage, even if it were possible... (because almost all other languages and libraries use the y-\> x order).

BTW, I found the `phase()` function for complex variables, which may be similar to atan2() for the range of the result (not tried yet).  
[https://chapel-lang.org/docs/modules/standard/Math.html#Math.phase](https://chapel-lang.org/docs/modules/standard/Math.html#Math.phase)

---

<div class="post-metadata">

### Author: ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)
#### Post date: [August 29, 2024, 4:23am UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/7 "2024-08-29T04:23:37Z")

</div>

The **phase** () functions just calls **atan2** (). It is defined that way in the C Standard.

If you are bored, and you want to know why the reason for the argument ordering, read on.

In Fortran II (and I have the manuals), all the 20 intrinsic functions and the basic ones (which post 1959 or so were provided by the user group), i.e. LOG, SIN, COS, EXP, SQRT, ATAN, and TANH, called their arguments, **Arg1** (and **Arg2** where there was a second argument).

When it came to introducing the ATAN2() routine in Fortran between then and when it seems to have been published in 1961, that naming convention still held so it would have been written as

```Chapel
ATAN2(Arg1, Arg2)

```

and it would documented as returning

```Chapel
Arg1 / Arg2

```

Perfectly consistent. None of this _x_ and _y_ stuff to worry about alphabetical ordering.

Below are the definitions from the Reference Manual for the IBM 714 Data Processing Manual 1958 C28-6000-2. This was a minor revision of C28-6100-1 (which had a typo for SIGNF). This is the 1958 list (where I have added the (Arg1,Arg2) parameter list)

```Chapel
  MODF(Arg1,Arg2) Arg1 - [Arg1/Arg2] where [x] = integral part of x
  MAX1F(Arg1,Arg2,..) Max(Arg1, Arg2, ...)
  MIN1F(Arg1,Arg2,..) Min(Arg1, Arg2, ...)
  SIGNF(Arg1,Arg2) Sign of Arg2 times |Arg1|
  DIMF(Arg1,Arg2) Arg1 - Min(Arg1, Arg2)

```

And ATAN2F(Arg1,Arg2) came along sometime in the next 3 years, appearing in the manual of 1961. Those routines all lost their trailing **F** in the early 1960s.

---

<div class="post-metadata">

### Author: ![tbzy](https://avatars.discourse-cdn.com/v4/letter/t/bcef8e/32.png) [@tbzy](https://chapel.discourse.group/u/tbzy)
#### Post date: [August 29, 2024, 7:28am UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/8 "2024-08-29T07:28:33Z")

</div>

Thanks very much for the detailed explanation! I see, so the original definition partly arises from the naming convention at that time ("Arg1", "Arg2", and so on) and also from the correspondence of `atan2( arg1, arg2 )` to `atan( arg1 / arg2 )` (so both 1 -\> 2, with comma corresponding to slash). Given that `atan2()` was introduced as a variant of `atan()` (as its name suggests), I guess more emphasis was put on the formal similarity between the two functions, rather than as a function for returning the polar angle from 2D Cartesian coordinates (x,y).

(I guess my feeling about the order of `atan2()` is probably similar to the OP of the following question, because I also made a mistake when using `atan2()` much, much ago... To prevent such a mistake, I think I could define an alias like `polar_angle(x, y) = atan2(y, x)` etc, if really necessary.)

> <https://stackoverflow.com/questions/1045630/why-are-the-arguments-to-atan2-y-x-rather-than-x-y>

Also, thanks very much for the info about `phase()`! It is good to know that it uses `atan2()`,  
so the result should be the same. I also searched the net a bit more, and the cmath module in Python also says their functions are also equivalent (apart from real versus complex arguments).

> **[cmath — Mathematical functions for complex numbers](https://docs.python.org/3/library/cmath.html#conversions-to-and-from-polar-coordinates)**
>
> This module provides access to mathematical functions for complex numbers. The functions in this module accept integers, floating-point numbers or complex numbers as arguments. They will also accep...

```Chapel
cmath.phase(x)

Return the phase of `x` (also known as the argument of `x`),
as a float. `phase(x)` is equivalent to `math.atan2(x.imag, x.real)`.
The result lies in the range [-π, π], and the branch cut for this
operation lies along the negative real axis.

```

---

<div class="post-metadata">

### Author: ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)
#### Post date: [August 29, 2024, 8:30am UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/9 "2024-08-29T08:30:09Z")

</div>

It is amazing how many concepts trace their history to FortranII or Algol60 of the late 1950s. Way before my time!

With reference to that _stackoverflow_ question which you quoted, those who answered it did not look back far enough to find the real reason for the ordering. Mind you, there is a big lack of available evidence (that I can find) of why things were done in Fortran during the early 1960s. No idea why this is the case. Some of it would be in the proceedings of the annual conferences of SHARE, the IBM user group, who wielded a lot of clout. The only copies of those which existed belonged to people who went to the conferences who are probably in their 80s or 90s now and have probably long ago binned them.

---

<div class="post-metadata">

### Author: ![lydia](https://avatars.discourse-cdn.com/v4/letter/l/34f0e0/32.png) [@lydia](https://chapel.discourse.group/u/lydia)
#### Post date: [August 29, 2024, 2:36pm UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/10 "2024-08-29T14:36:20Z")

</div>

Hi Takeshi,

Yeah, that's part of why we didn't make the change when stabilizing the  
function - the strong precedence from other languages meant that  
changing the ordering to be alphabetical would have been confusing (and  
likely led to bugs for anyone using explicit argument naming)

Lydia

---

<div class="post-metadata">

### Author: ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)
#### Post date: [August 30, 2024, 5:30am UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/11 "2024-08-30T05:30:08Z")

</div>

Instead of your _polar\_angle_ function which accepts arguments of _x_ and _y_ which I will assume are **real** , you can choose to say

```chapel
phase(x + y:imag)

```

which will return the value of **atan2** (y, x). If you want to use my **cmplx**  **proc** s, you could also say

```chapel
phase(cmplx(x, y))

```

---

<div class="post-metadata">

### Author: ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)
#### Post date: [September 4, 2024, 5:05am UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/12 "2024-09-04T05:05:03Z")

</div>

> [@tbzy](#):
>
> BTW, I feel the de facto standard (?) order of the arguments  
> in many libraries ("y first, x second") is rather confusing (e.g.  
> the above help page in Python) and so wonder why the initial  
> Fortran implementation chose such order historically...

It is simply a case where the convention of trying to use a small list of names as a memory aid for the arguments (or parameters) breaks down. None of them are perfect. Too often they have limited domain to which they apply (like a lot of functions I guess!!)

---

<div class="post-metadata">

### Author: ![tbzy](https://avatars.discourse-cdn.com/v4/letter/t/bcef8e/32.png) [@tbzy](https://chapel.discourse.group/u/tbzy)
#### Post date: [September 4, 2024, 3:35pm UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/13 "2024-09-04T15:35:21Z")

</div>

> [@damianmoz](#):
>
> With reference to that _stackoverflow_ question which you quoted, those who answered it did not look back far enough to find the real reason for the ordering. Mind you, there is a big lack of available evidence (that I can find) of why things were done in Fortran during the early 1960s

Yes, when it comes to a question about the history, I have experienced a similar situation not only for StackOverflow but for other forums, i.e., people need to guess or speculate because of the lack of available references. (The notorious [implicit (or implied) save](https://stackoverflow.com/questions/3352741/fortran-assignment-on-declaration-and-save-attribute-gotcha) feature in Fortran might be such a case, for which people think about various reasons why it was introduced back in ~1990, but available references seem very scarce.) So, I guess it may be nice to add an additional answer (explanation) to the above Stackoverflow page about `atan2()` if you possibly have an account on that site 😉

> [@damianmoz](#):
>
> None of them are perfect. Too often they have limited domain to which they apply (like a lot of functions I guess!!)

Yeah, I completely agree. I think if one makes some parts of the design more convenient for a given purpose, other parts can become inconvenient for different purposes. The situation may be similar for various language features...

PS. I have some questions related to the `phase()` above, but will post it in separate threads or possibly on StackOverflow for Chapel (in case it is a more general question).

---

<div class="post-metadata">

### Author: ![damianmoz](https://yyz2.discourse-cdn.com/free1/user_avatar/chapel.discourse.group/damianmoz/32/319_2.png) [@damianmoz](https://chapel.discourse.group/u/damianmoz)
#### Post date: [September 4, 2024, 10:40pm UTC](https://chapel.discourse.group/t/inverse-trigonometric-tangent/36734/14 "2024-09-04T22:40:45Z")

</div>

In the past, I have had problems posting to Stack Overflow.. It said I had to have some rating or score. Very weird. I never look at Stack Overflow as a matter of course. I find its format somewhat unreadable, not least because it uses different fonts.

Happy to answer any questions you have about phase. It is a very simple concept.

```chapel
inline proc phase(z : complex(?w))
{
    return atan2(z.im, z.re);
}

```
