Vincent
Vincent

Reputation: 60371

Why cexp(+infinity+I*infinity)=+/-infinity+I*NaN in the C langage?

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

Upvotes: 6

Views: 288

Answers (2)

oseiskar
oseiskar

Reputation: 3372

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.

Upvotes: 2

Brett Hale
Brett Hale

Reputation: 22318

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.

Upvotes: 0

Related Questions