Methods to create arrays of NaN
6 views (last 30 days)
I often need to create arrays of NaNs, e.g. for preallocation. I have always done that by using the zeros function, and adding NaN, e.g:
vec1 = zeros(10,1)+NaN % vector, zeros+NaN method
arr1 = zeros(10,10)+NaN % matrix, zeros+NaN method
However, I recently discovered the "nan" function, which is certainly more straight forward:
vec2 = nan(10,1) % vector, nan method
arr2 = nan(10,10) % matrix, nan method
I feel a bit silly that I've only just recently discovered the "nan" function given my reliance on arrays of NaNs. I can only surmise that as I was learning Matlab using colleagues' code as reference, I saw the zeros()+NaN method and it stuck. Regardless, are the outputs (vs. syntax, execution time, readability) of the two methods identical? It appears that they yield identical results, but I have come to learn that there can be nuances with NaNs and how they are represented etc., and just wanted to confirm. Apologies if this is a silly question, and thank you for the sanity check.
Rik on 15 Jun 2022
Edited: Rik on 16 Jun 2022
In very old releases (prior to v7 (R14)) it was not possible to create arrays with NaN and inf. In those releases you had to use tricks like zeros(a,b)+NaN; to create arrays of NaNs.
But, as already mentioned, the results are identical. The JIT/EE could optimize away the overhead cause by the extra operations, but as the timings John showed in his answer, this is not (yet) the case.
So there is only a benefit if you need to keep your code compatible with very old releases. If not, you can shave a few milliseconds off every time you need a NaN array by calling it as a function.
John D'Errico on 15 Jun 2022
Edited: John D'Errico on 15 Jun 2022
A NaN is a nan. A NaN by any other name, is still just a NaN.
But there are faster and slower ways to make them, and surely the nan function is the fastest, since it needs only allocate the memory and stuff NaNs into it. You could have done many things to create a NaN array. For example
A1 = NaN(100);
A2 = zeros(100) + NaN;
A3 = ones(100)*NaN;
A4 = sin(inf(100));
A5 = zeros(100)./zeros(100);
A6 = inf(100) - inf;
A7 = (-inf)./inf(100);
Many equally strange ways to do the job. All are identical to the first though.
As you can see, a NaN really is just a NaN. The result is not dependent on how you get there. I could not even create a negative NaN.
Is there a time differential between the various schemes? Probably. Let me see...
n = 7500;
timeit(@() zeros(n) + NaN)
timeit(@() inf(n) - inf)
So there are clearly some dumbish, yet creative ways to try to create a NaN. I'm not sure exactly why some of the methods above are much slower, but they do seem to be consistently all slower then the NaN function itself, as you would hope. In the end, the NaN function is easily the best, and for good reason.
Steven Lord on 16 Jun 2022
You can check that the outputs of those two approaches are equal. The isequal function will return false since it does not consider NaN to be equal to anything, even another NaN (or the same NaN.) The isequaln function is the same as isequal except it considers NaN to be equal to NaN.
x = NaN + ones(1, 5)
y = NaN(1, 5)
isequal(x, y) % false
isequal(x, x) % false, the variable x is not equal to itself because of NaN
isequaln(x, y) % true