Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extracting the real and imaginary part of a complex number #288

Open
Dr-Wizard opened this issue May 12, 2024 · 4 comments
Open

Extracting the real and imaginary part of a complex number #288

Dr-Wizard opened this issue May 12, 2024 · 4 comments

Comments

@Dr-Wizard
Copy link

The real and imaginary part of a complex number are extracted as follows:

public var real: RealType {
@_transparent
get { isFinite ? x : .nan }

@_transparent
set { x = newValue }

}

public var imaginary: RealType {
@_transparent
get { isFinite ? y : .nan }

@_transparent
set { y = newValue }

}

By checking for isFinite can give wrong values, since infinity is not returned correctly as eg. 1/0 is not .nan but .inf. In a complex number, one part can have a regular value while the other is infinite or nan. With the isFinite check, nan is returned for both parts as soon as one of the two parts is not a regular number. (inf or nan) I suggest returning x and y without the isFinite check.

@stephentyrone
Copy link
Member

stephentyrone commented May 13, 2024

This is a deliberate design choice, see the documentation for these properties:

If z is not finite, z.real is .nan.
If z is not finite, z.imaginary is .nan.

and README.md for Complex:

C and C++ attempt to define semantics that interpret the signs of infinity and zero. This is occasionally useful, but it also results in a lot of extra work. The Swift Numerics Complex type does not assign any semantic meaning to the sign of zero and infinity; (±0,±0), are all considered to be encodings of the value zero. Similarly, (±inf, y), (x, ±inf), (nan, y) and (x, nan) are all considered to be encodings of a single exceptional value with infinite magnitude and undefined phase.

Because the phase is undefined, the real and imaginary properties return .nan for non-finite values.

If you have a specific use for the raw values in mind, we can consider removing the underscore for the existing _rawX and _rawY properties or otherwise exposing those values as API.

@Dr-Wizard
Copy link
Author

I understand the simplification. Mathematically, however, it must be possible to distinguish between NaN and Inf and also between the real and imaginary parts of these two exceptions. For example, the angle of (Inf,y) is by definition 0, of (-Inf,y) equal to -pi. The angle of (Inf,Inf) is pi/4, so the simplification is not allowed and Swift handles these exceptions (NaN, Inf) correctly. For example, sin(inf)=NaN.
The distinction between +/-0 is mandatory in my opinion.
Access to the raw values (x and y) can be a step in the right direction and help. However, it must be ensured that the functions within the library also use them correctly.

@stephentyrone
Copy link
Member

stephentyrone commented May 13, 2024

For example, the angle of (inf,y) is by definition 0, of (-inf,y) equal to -pi.

No; a type defines its semantics. The angle of (inf, y) is undefined, because the type specifies it as such.

There is no unique "mathematical" definition to appeal to here. In the traditional complex plane, points at infinity simply do not exist. For the Alexandroff compactification (aka Riemann sphere) of the complex plane, there is a single point at infinity with undefined phase (because it sits at the limit of every ray from the origin). C's complex type attempts to extend IEEE 754's two-point compactification of the reals to the complex plane with mixed results (it preserves more information, but the resulting arithmetic is not really consistent in a way that you can make useful claims about). Fortran mostly pretends that complex infinities don't exist.

@Dr-Wizard
Copy link
Author

I agree, that infinity does not exist for complex numbers in the gaussian complex plane and that you cannot conclude the real and imaginary part for extended complex numbers on the Riemann sphere. Anyhow, setting both real and imaginary part to nan if the complex number is not finite hides important information about what the complex number to not be finite. In engineering and system theory complex numbers are commonly interpreted as two vectors, one on the real axis and one on the imaginary axis. Consider for example the rotating pointer of a three-phase-current system, a Laplace transform or a transfer function in control systems. They all are based on complex numbers and in that context it is important to know, if either the real or the imagiary part or both reached infinity. That's the reasons, why numerical software packages like Matlab or Octave return this information and let the interpretation up to the user.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants