# Bug? shuffle() breaks normalisation test

**URL:** https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976
**Category:** Internals & Design
**Tags:** bug
**Created:** [October 16, 2019, 9:12am UTC](https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976 "2019-10-16T09:12:10Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![dcastel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dcastel/32/10692_2.png) [@dcastel](https://discourse.julialang.org/u/dcastel)
#### Post date: [October 16, 2019, 9:12am UTC](https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976/1 "2019-10-16T09:12:10Z")

</div>

Hi all,

I think I found a Julia bug (Version 1.1.0) I stumbled upon when writing a function for checking whether a tensor is normalized. I wrote tests for it and it seems (somewhat, sometimes) reproducible.

It comes down to this:  
I generate some ‘random’ numbers that should be normalized, and they are, up to the point that the shuffle function is called, then they no longer seem normalized according to (some) of my tests.

My code and tests can be found here:  
[https://gist.github.com/dietercastel/541f3228b18ccf1820c916a83ebc5aaf](https://gist.github.com/dietercastel/541f3228b18ccf1820c916a83ebc5aaf)

If this is due to numerical errors (most likely I think) how can I get around it? What’s a better, more Julia friendly, approach to write these tests or code?

I tried the same code in 3 different ways (Orig file, REPL, minimal file linked): 2/3 made the fourth test fail. And I’ve seen the second test fail as well (ocasionally).

I haven’t tried with a seeded random number or a fixed tensor, but no time atm for that. I’ll come back to it later though! I’ll also give it a try in v1.2 soon.

Looking forward to your responses.

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [October 16, 2019, 9:22am UTC](https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976/2 "2019-10-16T09:22:49Z")

</div>

you just need this line for you `isNorm` instead:

```julia
isStrictPos(tensor) & (sum(tensor) ≈ 1)

```

doc:  
[https://docs.julialang.org/en/v1/base/math/#Base.isapprox](https://docs.julialang.org/en/v1/base/math/#Base.isapprox)

---

<div class="post-metadata">

### Author: ![dcastel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dcastel/32/10692_2.png) [@dcastel](https://discourse.julialang.org/u/dcastel)
#### Post date: [October 16, 2019, 9:51am UTC](https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976/3 "2019-10-16T09:51:34Z")

</div>

Well that works indeed. Thanks!

Is that something that has to be done in general in Julia? Replace all == with ≈ ?  
Are there some guidelines/reading material about when too and when not to use it. It feels a bit weird but of course at least it’s explicitly possible in Julia. Do you do it only in tests or always throughout your code?

Is there also an infix notation for isapprox() ?

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [October 16, 2019, 9:55am UTC](https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976/4 "2019-10-16T09:55:44Z")

</div>

my line up there uses infix already, no?

well, my understanding is that usually, you use `==` (or even `===` when possible for better performance etc). But if you’re testing using/against real-world data, or you have some fitted/normalized data, or you’re aggregating many floats and expect to get some answer (usually a mathematical one, for example, normalization, or zero), you use approx. Although usually at this step you’re returning the result, so I say usage in a test is also common?

---

<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: [October 16, 2019, 10:39am UTC](https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976/5 "2019-10-16T10:39:38Z")

</div>

> [@dcastel](#):
>
> Is that something that has to be done in general in Julia? Replace all == with ≈ ?

I am not sure that is a good idea, those functions serve a different purpose. And of course `≈` is not transitive.

> [@dcastel](#):
>
> Are there some guidelines/reading material about when too and when not to use it.

The underlying issue is floating point, so maybe this is helpful:

> [@PSA: floating-point arithmetic](https://discourse.julialang.org/t/psa-floating-point-arithmetic/8678):
>
> Sometimes people are surprised by the results of floating-point calculations such as julia\> 5/6 0.8333333333333334 # shouldn't the last digit be 3? julia\> 2.6 - 0.7 - 1.9 2.220446049250313e-16 # shouldn't the answer be 0? These are not bugs in Julia. They’re consequences of the IEEE-standard 64-bit binary representation of floating-point numbers that is burned into computer hardware, which Julia and many other languages use by default. Brief explanation You can t…

> [@dcastel](#):
>
> Is there also an infix notation for isapprox() ?

`≈`

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [October 16, 2019, 1:29pm UTC](https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976/6 "2019-10-16T13:29:36Z")

</div>

It’s important to understand what `≈` does: by default it checks to see if two floating point values are equal for the first half of their significant digits. That’s pretty lenient but also quite standard. To be used with caution but also essential when checking results that can depend on numerical round off. I’m afraid the only answer here is to have some grasp of numerical analysis and to use judgement. Replacing all equality checks with `≈` is definitely not a good idea. Nor would it even be sufficient: `0.0` is never approximately equal to any non-zero value since it has no scale so you can’t know which bits should be considered significant or not. As the docs for `≈` say:

> [@](#):
>
> Note that `x ≈ 0` (i.e., comparing to zero with the default tolerances) is equivalent to `x == 0` since the default `atol` is `0`. In such cases, you should either supply an appropriate `atol` (or use `norm(x) ≤ atol`) or rearrange your code (e.g. use `x ≈ y` rather than `x - y ≈ 0`). It is not possible to pick a nonzero `atol` automatically because it depends on the overall scaling (the “units”) of your problem: for example, in `x - y ≈ 0`, `atol=1e-9` is an absurdly small tolerance if `x` is the [radius of the Earth](https://en.wikipedia.org/wiki/Earth_radius) in meters, but an absurdly large tolerance if `x` is the [radius of a Hydrogen atom](https://en.wikipedia.org/wiki/Bohr_radius) in meters.

In particular, summation, even though it seems like an innocuous operation is sensitive to data ordering. In fact, you can sum the same set of numbers in different orders and get basically any possible result:

> [@Array ordering and naive summation](https://discourse.julialang.org/t/array-ordering-and-naive-summation/1929):
>
> One of the first things you learn in numerical analysis is that floating-point operations are not associative. A classic example is this: julia\> (0.1 + 0.2) + 0.3 0.6000000000000001 julia\> 0.1 + (0.2 + 0.3) 0.6 I was thinking of ways to make floating-point summation independent of the order of the summands without making the performance much worse (this is a hobby of mine). Julia currently uses a pairwise summation algorithm, which is much better than naive left-to-right reduction while havin…

We don’t use naive summation by default in Julia, so things aren’t quite that bad, and if you’re only adding up positive values it’s not possible to have such a pathological situation, but keep this in mind.

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [October 16, 2019, 3:31pm UTC](https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976/7 "2019-10-16T15:31:23Z")

</div>

> [@StefanKarpinski](#):
>
> We don’t use naive summation by default in Julia,

Except for generators…

```julia
julia> sum(x for x in ones(Float32, 100_000_000))
1.6777216f7

```

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [October 16, 2019, 3:52pm UTC](https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976/8 "2019-10-16T15:52:26Z")

</div>

True.

---

<div class="post-metadata">

### Author: ![dcastel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dcastel/32/10692_2.png) [@dcastel](https://discourse.julialang.org/u/dcastel)
#### Post date: [October 21, 2019, 5:53pm UTC](https://discourse.julialang.org/t/bug-shuffle-breaks-normalisation-test/29976/9 "2019-10-21T17:53:08Z")

</div>

Ah yes, but I meant _another_ infix notation. That wasn’t clear indeed, scusi! The thing is, I don’t like how subtle the difference is visually. (== and the expanded \approx)

I’ve been looking around a bit and custom infix notations are not around I guess, or did I overlook? Was trying to ‘fix’ it with some macro but they seem to break with UTF8 chars (I’ll report more in depth later).

Anyway, thanks for the kind help all! 🙂
