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

Potential bug in complex exp() function #103

Closed
JorisDeRidder opened this issue May 6, 2022 · 2 comments
Closed

Potential bug in complex exp() function #103

JorisDeRidder opened this issue May 6, 2022 · 2 comments

Comments

@JorisDeRidder
Copy link
Contributor

The following code

use num::complex::Complex;

fn main() {

    let z = Complex::<f64>::new(f64::NEG_INFINITY, f64::INFINITY);
    println!("z = {:?}", z);
    println!("exp(z) = {:?}", z.exp());
}

returns

z = Complex { re: -inf, im: inf }
exp(z) = Complex { re: NaN, im: NaN }

while its C++ equivalent

#include <iostream>
#include <complex>

using namespace std;

int main() {

    complex<double> z(-INFINITY, INFINITY);
    cout << "z = " << z << endl;
    cout << "exp(z) = " << exp(z) << endl;

    return 0;
}

returns a different outcome:

z = (-inf,inf)
exp(z) = (0,0)

Might it be that the special values are not properly implemented in num?

@cuviper
Copy link
Member

cuviper commented May 7, 2022

You're right, it is not trying to handle "special" values at all, directly computing: ea + i b = ea (cos(b) + i sin(b))

bors bot added a commit that referenced this issue Jun 17, 2022
104: Adapted complex exp() function so that it can handle inf and nan arguments as well r=cuviper a=JorisDeRidder

### Why this PR?

The current version of the complex exp() function is not able to handle arguments that contain +/- inf or NaN in their real or imaginary part. This impacts other complex functions that use the exp() function. 

For example, for the most widely used implementation of the complex Faddeeva function `w()`, the current `exp()` implementation leads to `w(1e160 - 1e159*i) = NaN + NaN *i` , while the correct value is  `-5.586035480670854e-162 + 5.5860354806708545e-161 * i`. The underlying reason is that the current `exp()` implementation erroneously returns  `exp(-inf + inf *i) = NaN + Nan *i` instead of the correct `0 + 0*i`.

Cf also issue #103. 

### Contents of this PR

- I propose a modified complex exp() function that does deal with inf and nan. The added logic was strongly inspired by the one implemented in the `<complex>` C++ header that comes with clang++.
- I added extra unit tests. The relevant values were taken from [this page](https://en.cppreference.com/w/cpp/numeric/complex/exp).
- For the unit tests I also implemented `close_naninf()` and `close_naninf_to_tol()` as the existing functions `close()` and `close_to_tol()` are not able to deal with inf and nan.


Co-authored-by: Joris De Ridder <joris.deridder@kuleuven.be>
Co-authored-by: Joris De Ridder <5747893+JorisDeRidder@users.noreply.github.com>
@cuviper
Copy link
Member

cuviper commented Jun 17, 2022

Fixed by #104.

@cuviper cuviper closed this as completed Jun 17, 2022
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