# Return NaN instead of DomainError

**URL:** <https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493>\
**Category:** General Usage\
**Created:** [September 25, 2018, 10:25pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493 "2018-09-25T22:25:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [September 25, 2018, 10:25pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/1 "2018-09-25T22:25:02Z")

</div>

I could not find a way to make function calls like `sqrt(-2)` return `NaN` instead of raising an error. Is that possible?

It would be quite useful, at least sometimes, to just let the `NaN` propagate to the final result. Also this would save a comparison with zero which is always present is `sqrt` code now.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 25, 2018, 10:26pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/2 "2018-09-25T22:26:20Z")

</div>

> **[GitHub - JuliaMath/NaNMath.jl: Julia math built-ins which return NaN and...](https://github.com/JuliaMath/NaNMath.jl)**
>
> Julia math built-ins which return NaN and accumulator functions which ignore NaN - GitHub - JuliaMath/NaNMath.jl: Julia math built-ins which return NaN and accumulator functions which ignore NaN

---

<div class="post-metadata">

**Author:** ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)\
**Post date:** [September 25, 2018, 10:34pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/3 "2018-09-25T22:34:17Z")

</div>

If your input are floats, then you can use `@fastmath`, but it will not work with other types:

```julia
julia> @fastmath sqrt(-1.0)
NaN

julia> @fastmath sqrt(-1)
ERROR: DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
Stacktrace:
 [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31
 [2] sqrt at ./math.jl:479 [inlined]
 [3] sqrt at ./math.jl:505 [inlined]
 [4] sqrt_fast(::Int64) at ./fastmath.jl:361
 [5] top-level scope at none:0

julia> @fastmath sqrt(-1//1)
ERROR: DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
Stacktrace:
 [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:31
 [2] sqrt at ./math.jl:479 [inlined]
 [3] sqrt at ./math.jl:505 [inlined]
 [4] sqrt_fast(::Rational{Int64}) at ./fastmath.jl:361
 [5] top-level scope at none:0
```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [September 25, 2018, 10:36pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/4 "2018-09-25T22:36:05Z")

</div>

Wow, I would never guess that `@fastmath` changes the visible behaviour that much. At least the docs give impression that it only enable less precision.

Edit: the docs indeed contain the info about NaNs, a few pages below.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 25, 2018, 10:37pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/5 "2018-09-25T22:37:00Z")

</div>

```julia
julia> isnan(x) = @fastmath isnan(x)
isnan (generic function with 1 method)

julia> isnan(NaN)
false

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 25, 2018, 10:42pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/6 "2018-09-25T22:42:13Z")

</div>

No. Don’t do that!!! It’s undefined behavior when you have `NaN` in `@fastmath`.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [September 25, 2018, 10:48pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/7 "2018-09-25T22:48:42Z")

</div>

The package looks like it does what’s needed. And even through they wrap the `Base.sqrt` function, the compiler probably is smart enough not to perform the comparison twice. And by the way, their trig functions differ from `Base` ones not only in `NaN` handling: they just use `libm` functions, while `Base` has Julia implementations. Not sure why the case for `sqrt` is different.

---

<div class="post-metadata">

**Author:** ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)\
**Post date:** [September 25, 2018, 10:54pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/8 "2018-09-25T22:54:46Z")

</div>

Good to know that.  
Just to be sure I understand you correctly: you are saying that using `NaN` values as **input** ta a `@fastmath` function will lead to undefined behavior, right? Not that `@fastmath sqrt(-1.0)` leads to undefined behavior, correct?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 25, 2018, 11:14pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/9 "2018-09-25T23:14:06Z")

</div>

No I’m saying that what you suggested is undefined behavior, i.e. `@fastmath sqrt(-1.0)` is undefined behavior. `@fastmath` assumes `NaN` doesn’t exist anywhere. It’s a mere implementation detail that `@fastmath sqrt(-1.0)` return `NaN`. It could throw an error or even crash.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [November 20, 2018, 11:11pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/10 "2018-11-20T23:11:01Z")

</div>

The suggested solution with NaNMath package is ok and works, but:  
Is there any way to make all math functions return NaN in a large block of code? Like I have a block like this:

```julia
for i in ...:
    a[i] = sqrt(f(i))
    ...
    if ...:
        arr = [sqrt(f(j)) for j in ...]
        b[i] = log(f(arr))
    ...
end

```

And would really like all functions like `sqrt` and `log` here to just produce nans. The only way I see is manually find offending function and replace them with `NaNMath` implementations. Oh, and what to do if `f(...)` - some external function - also contains `sqrt` and others, and thus throws domainerror instead of just returning nan? And if I forget some function, which just happens not to throw when run on test data, it will explode at some unexpected time later.

Note that in this example it’s not easily possible to put `catch`es in relevant locations. Even for simpler examples, this looks far from an expected quick solution…

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [July 25, 2019, 3:50pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/11 "2019-07-25T15:50:20Z")

</div>

Bumping this thread - any new thoughts on the NaN propagation, in light of almost a year of Julia and ecosystem evolution? The main issue is that it’s very painful to just propagate all the nans to the end, compared to basically any other used language. Actually, that’s almost impossible to do reliably from the first try with many functions calling each other. Something like a global/local option for that would be really useful. If it worked like

```julia
propagate_nan() do
  # code called here silently propagates nans, no matter what functions are called and how nested they are
end

```

this would be even better than other languages, because in other parts of code unexpected nans would still error.

---

<div class="post-metadata">

**Author:** ![wiktorkujawa](https://avatars.discourse-cdn.com/v4/letter/w/bc8723/32.png) [@wiktorkujawa](https://discourse.julialang.org/u/wiktorkujawa)\
**Post date:** [July 25, 2019, 7:39pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/12 "2019-07-25T19:39:18Z")

</div>

Maybe that would work:

```julia
try
  a=sqrt(-2)
catch
  a=0/0
end

```

You also can do something like this:

```julia
julia> sqrt(-2+0im)
0.0 + 1.4142135623730951im

```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [July 25, 2019, 8:09pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/13 "2019-07-25T20:09:56Z")

</div>

Oh, there are so many things going bad or wrong with this kind of partial solution 🙂 A few examples below, where we assume that `f` function is 3rd-party, from some other project, and definitely don’t want to edit its code.

```julia
f(x) = sqrt(log(x))
g(x) = try f(x) catch; NaN end
a = rand(10_000);

@btime f.($(2 .+ a));
  93.934 μs (2 allocations: 78.20 KiB)

@btime g.($(2 .+ a));
  483.374 μs (7 allocations: 78.31 KiB)
# 5 times slower!

@btime g.($(0.5 .+ a));
  221.003 ms (65249 allocations: 3.06 MiB)
# 2000 times slower!

g(2f0) |> typeof
Float32

g(0f0) |> typeof
Float64
# wrong type

```

```julia
f(x) = (sqrt(log(x)), sin(x))

f(2)
(0.8325546111576977, 0.9092974268256817)

g(2)
(0.8325546111576977, 0.9092974268256817)
# so far so good

g(0.5)
NaN
# how to get (NaN, 0.909)?

```

This gets only more complicated when called functions are more and more nested or modular.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 26, 2019, 4:29am UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/14 "2019-07-26T04:29:44Z")

</div>

> [@aplavin](#):
>
> code called here silently propagates nans, no matter what functions are called and how nested they are

I am not sure how this would make sense for generic code. `NaN` propagation is for floating point computations, you can stretch it to `<:Real` conceptually in some cases, but why would eg `getproperty` “propagate” `NaN` when in normal use scenarios neither argument is a `NaN`?

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [July 26, 2019, 5:59am UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/15 "2019-07-26T05:59:36Z")

</div>

I’m talking about floating-point code only, and all examples in this thread involve simple math floating point functions.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 26, 2019, 6:16am UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/16 "2019-07-26T06:16:52Z")

</div>

I think you just have to use NaNMath functions everywhere. Alternatively, you could define a wrapper type

```julia
struct NaNProp{T}
    value::T
end
# and define all methods you need, eg
Base.log(x::NaNProp) = NaNProp(NaNMath.log(x.value))

```

where defining the methods would of course be easier with a macro (look for `@eval` blocks [like this one](https://github.com/mlubin/NaNMath.jl/blob/a6dbfd5de38353a3852d79a38e3b25f1c49ecdcc/src/NaNMath.jl#L8) as examples).

Then for black box `f` functions you can just wrap the input and have it propagate.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [July 26, 2019, 6:34am UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/17 "2019-07-26T06:34:32Z")

</div>

This seems the best way suggested in this thread so far! The wrapper type should cover more cases and hopefully (?) be close to zero-cost in performance. Not sure if it will SIMD, for example.

One obvious drawback is that it requires to track and define all mathematical functions, and also stuff like `show`, `parse`, `convert`, and so on for all float-related functions used in the code. Sounds like a complicated and error prone task.  
Another practical limitation is that if a 3rd-party library calls C (or other) function or external program, and performs some calculations on this output, one cannot inject the wrapper.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 26, 2019, 7:48am UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/18 "2019-07-26T07:48:00Z")

</div>

> [@aplavin](#):
>
> Sounds like a complicated and error prone task.

I don’t think so, you can just follow the examples of similar packages that redefine arithmetic. IMO this is something you can hammer out in an afternoon.

Frankly, I find it amazing that this is even _possible_, let alone that it is so easy.

> [@aplavin](#):
>
> if a 3rd-party library calls C (or other) function or external program

Of course, you have to unwrap things, but you can [automate this to a large extent](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Auto-conversion:-1). You just have to rewrap once done.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [July 26, 2019, 1:48pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/19 "2019-07-26T13:48:31Z")

</div>

> [@Tamas\_Papp](#):
>
> Of course, you have to unwrap things, but you can [automate this to a large extent](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Auto-conversion:-1). You just have to rewrap once done.

This implies modifying a 3rd-party library, unfortunately.

It also feels very strange for me, that a performance-oriented language like julia doesn’t give the option (at least) to just silently propagate nans without any exceptions. This is one of the really few things which are much more convenient to handle in python, and for me in particular it means that the corresponding code cannot be easily and performantly ported to Julia.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [July 26, 2019, 2:05pm UTC](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493/20 "2019-07-26T14:05:22Z")

</div>

I am not sure it does, but I don’t know your context. If you are looking for specific solutions, an MWE would help.

[Next page](https://discourse.julialang.org/t/return-nan-instead-of-domainerror/15493.md?page=2)
