6
votes

If we look at the comittee draft of the C langage : n1570 and particularly to the Annex G concerning the behaviour of the complex mathematical functions, we can see that the complex exponential has the following behaviour at infinity:

cexp(+infinity+I*infinity)=+/-infinity+I*NaN
(where the sign of the real part of the result is unspecified).

My question is: why ?

From a mathematical point of view, if we approach the infinity of the real and imaginary part in the same way, the limit is a complex infinity (see Wolfram Alpha for example), which corresponds to an infinite modulus and undefined argument.

Moreover, if we look to the behaviour of the cexp function, it is quite comparable for its real and imaginary part (see 3D plots on Wolfram Alpha).

So, I would have expected:

cexp(+infinity+I*infinity)=+/-infinity+/-I*infinity

instead of:

cexp(+infinity+I*infinity)=+/-infinity+I*NaN

I know that there is an excellent reason for this but I do not understand it. Could someone explain me the logic behind this?

EDIT: here is a summary of the links:

Summary

2
Section G.5.1 of the document "Rationale for International Standard -- Programming Languages -- C" appears to contain some relevant comments on the handling of special values for complex functions including cexp(). You can find it here: open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf - njuffa
Thanks for this link. It's very instructive but it does not bring the answer concerning the case cexp(infinity+I*infinity). - Vincent
The only document that I am aware of that explains the thought process of the standards committee is the rationale document. Unless you can locate relevant committee meeting notes (no idea whether ISO committees provide public notes) or have access to a committee member I am afraid the question as to why the standard says what it says will remain unanswered. - njuffa

2 Answers

2
votes

The motivation is indeed given in the document linked by njuffa, http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf :

7.3.9.4 The cproj function

Two topologies are commonly used in complex mathematics: the complex plane with its continuum of infinities, and the Riemann sphere with its single infinity. The complex plane is better suited for transcendental functions, the Riemann sphere for algebraic functions. The complex types with their multiplicity of infinities provide a useful (though imperfect) model for the complex plane. The cproj function helps model the Riemann sphere by mapping all infinities to one, and should be used just before any operation, especially comparisons, that might give spurious results for any of the other infinities.

Note that a complex value with one infinite part and one NaN part is regarded as an infinity, not a NaN, because if one part is infinite, the complex value is infinite independent of the value of the other part. For the same reason, cabs returns an infinity if its argument has an infinite part and a NaN part.

There is also a similar remark in G.5.1:

... In order to support the one-infinity model, C99 regards any complex value with at least one infinite part as a complex infinity (even if the other part is a NaN), and guarantees that operations and functions honor basic properties of infinities, and provides the cproj function to map all infinities to a canonical one. ...

The relevant search term was "Riemann" as in Riemann sphere, the mathematical model for the extended complex plane with a single infinity, which is used in Mathematica / Wolfram Alpha, but not universally in mathematics.

0
votes

One reason for NaN is that there is no representation of the 'direction' this infinite value takes. With the real numbers, lim a->inf : exp(a) -> + infinity. The well-defined directions give an intuitive meaning as to why:

1/(+0) = +inf, 1.0 / (-0.0) = -inf and:

1/(+inf) = +0, 1/(-inf) = -0

Extending this to the complex plane: cexp([-]inf + b.I) = [-]inf.{cos(b) + I.sin(b)}

Even though the result has infinite magnitude, there is still a notion of direction, e.g., if b = - PI/2 -> cexp(+inf + b.I) = +inf.(-I)

If b = [-]inf, then the direction in which infinity is approached is indeterminant. There are an infinite number of directions, and the values for cos(b) and sin(b) are undefined. Not surprisingly, the real valued cos[f|l] and sin[f|l] functions return a NaN if the argument is an infinity.

This isn't a very formal answer, I'm afraid - just a 'feel' for the idea. My understanding is that there are other good reasons for this behaviour, like the use of branch cuts in complex analysis.