Methods to create arrays of NaN

조회 수: 21 (최근 30일)
Michael Brown
Michael Brown 2022년 6월 15일
답변: Steven Lord 2022년 6월 16일
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
vec1 = 10×1
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
arr1 = zeros(10,10)+NaN % matrix, zeros+NaN method
arr1 = 10×10
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
However, I recently discovered the "nan" function, which is certainly more straight forward:
vec2 = nan(10,1) % vector, nan method
vec2 = 10×1
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
arr2 = nan(10,10) % matrix, nan method
arr2 = 10×10
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
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.
  댓글 수: 4
KSSV
KSSV 2022년 6월 15일
Yes it should be.
dpb
dpb 2022년 6월 15일
To amplify, just a little; the use of NaN in in any math operation converts the output of whatever was there, finite or not, to NaN. It's a wasted operation and may trigger an extra memory copy, but the result will be the same.

댓글을 달려면 로그인하십시오.

답변 (3개)

Rik
Rik 2022년 6월 15일
편집: Rik 2022년 6월 16일
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
John D'Errico 2022년 6월 15일
편집: John D'Errico 2022년 6월 15일
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.
num2hex(A1(1))
ans = 'fff8000000000000'
num2hex(A2(1))
ans = 'fff8000000000000'
num2hex(A3(1))
ans = 'fff8000000000000'
num2hex(A4(1))
ans = 'fff8000000000000'
num2hex(A5(1))
ans = 'fff8000000000000'
num2hex(A6(1))
ans = 'fff8000000000000'
num2hex(A7(1))
ans = 'fff8000000000000'
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(@() NaN(n))
ans = 0.1568
timeit(@() zeros(n) + NaN)
ans = 0.3420
timeit(@() ones(n)*NaN)
ans = 0.1804
timeit(@() sin(inf(n)))
ans = 0.3695
timeit(@() zeros(n)./zeros(n))
ans = 0.3822
timeit(@() inf(n) - inf)
ans = 0.1785
timeit(@() (-inf)./inf(n))
ans = 0.1791
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
Steven Lord 2022년 6월 16일
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)
x = 1×5
NaN NaN NaN NaN NaN
y = NaN(1, 5)
y = 1×5
NaN NaN NaN NaN NaN
isequal(x, y) % false
ans = logical
0
isequal(x, x) % false, the variable x is not equal to itself because of NaN
ans = logical
0
isequaln(x, y) % true
ans = logical
1

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

제품


릴리스

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by