Producing a NaN only where there is a NaN, zero otherwise
4 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
This interesting question came up for me today. I was looking for a simple expression that can be used in a function handle, one that produces a NaN only for elements that are already NaN, but I want it to return 0 for any other element, including +/- inf.
X = [-inf, -1, -eps, 0, realmin, 2, 1+i, pi, flintmax, realmax, inf, NaN];
That should qualify as a good list of the possible numbers in MATLAB that might be of interest.
I want my function to generate a result as the vector: [0 0 0 0 0 0 0 0 0 0 0 NaN].
For example, this fails:
broken1 = @(X) 0*X;
broken1(X)
Though it is close. It suffers because 0*inf generates a NaN. An as pretty one is:
broken2 = @(X) X - X;
broken2(X)
It fails for a similar reason, because inf-inf produces NaN.
A valid solution should work for arrays of any shape or size of course. Yes, it is trivial to write if I do it in an m-file. Thus...
nanZ(X)
function res = nanZ(X)
% returns a NaN ONLY for elements of X that are NaN. All other elements will generate zero.
res = zeros(size(X));
res(isnan(X)) = NaN;
end
As I said, trivial if I use an m-flle. More difficult if I wish to use a function handle. It may be a blind spot on my part. But as a puzzle, can you write a simple, robust one line expression to produce my desired result, expressed as a function handle? Vectorized, of course.
And yes, I'll admit this question has essentially zero value, since a valid solution exists in an m-file form. Have fun! (I'll post a spoiler as an answer if people cannot find a better solution than the one I found. My final solution required only 9 characters, but it was definitely non-obvious.)
2 Kommentare
Antworten (6)
Stephen23
am 22 Feb. 2021
X = [-inf, -1, -eps, 0, realmin, 2, 1+i, pi, flintmax, realmax, inf, NaN];
Y = 0./(X==X)
4 Kommentare
the cyclist
am 22 Feb. 2021
Bearbeitet: the cyclist
am 22 Feb. 2021
0./eq(X,X)
is a nice variant of this, but one additional character
Gustavo Lunardon
am 24 Mär. 2021
Added as an answer rather than a comment now
X = [-inf, -1, -eps, 0, realmin, 2, 1+i, pi, flintmax, realmax, inf, NaN];
broken1 = @(X) 0./X.^0;
broken1(X)
Also works, 7 characters
X = [-inf, -1, -eps, 0, realmin, 2, 1+i, pi, flintmax, realmax, inf, NaN];
broken1 = @(X) 0*X.^0;
broken1(X)
Works as well with 6 characters
Advantage is that you can put any number different than zero in the other elements by changing the multiplier
1 Kommentar
the cyclist
am 24 Mär. 2021
Very nice!
It's a darn shame that
not(NaN)
does not yield NaN, because "NaN cannot be converted to logical". If it did, then
~X.^0
would be a sublime 5-character solution.
the cyclist
am 22 Feb. 2021
Bearbeitet: the cyclist
am 22 Feb. 2021
First attempt:
X = [-inf, -1, -eps, 0, realmin, 2, 1+i, pi, flintmax, realmax, inf, NaN];
broken = @(x) 1./((isnan(x)-1)/0); % 19 characters
broken(X)
0 Kommentare
the cyclist
am 22 Feb. 2021
Second attempt ...
X = [-inf, -1, -eps, 0, realmin, 2, 1+i, pi, flintmax, realmax, inf, NaN];
broken = @(x) 0./(isnan(x)-1); % 15 characters
broken(X)
2 Kommentare
the cyclist
am 23 Feb. 2021
I overlooked the obvious improvement to this one:
broken = @(x) 0./~isnan(x); % 12 characters
I like the fact that this one avoids the annoying denominator parentheses
Jan
am 24 Mär. 2021
X = [-inf, -1, -eps, 0, realmin, 2, 1+i, pi, flintmax, realmax, inf, NaN];
V = [0, NaN];
F = @(X) V(isnan(X) + 1);
F(X)
0 Kommentare
John D'Errico
am 22 Feb. 2021
Bearbeitet: John D'Errico
am 22 Feb. 2021
2 Kommentare
Gustavo Lunardon
am 24 Mär. 2021
Bearbeitet: Gustavo Lunardon
am 24 Mär. 2021
X = [-inf, -1, -eps, 0, realmin, 2, 1+i, pi, flintmax, realmax, inf, NaN];
broken1 = @(X) 0./X.^0;
broken1(X)
Also works, 7 characters
X = [-inf, -1, -eps, 0, realmin, 2, 1+i, pi, flintmax, realmax, inf, NaN];
broken1 = @(X) 0*X.^0;
broken1(X)
Works as well with 6 characters
Advantage is that you can put any number different than zero in the other elements by changing the multiplier
Siehe auch
Kategorien
Mehr zu Logical finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!