Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Note that NaN values in rows and columns that are not all NaN are retained.

How to expand this to multiple dimensions? For example if A has three dimensions:

>> A = NaN(5,4,3)           
>> A(2:4,2:3,2) = [1 2; 3 4; 5 6]
>> A(2,2,2) = NaN                
>> A(4,3,2) = NaN                
A(:,:,1) =
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
A(:,:,2) =
   NaN   NaN   NaN   NaN
   NaN   NaN     2   NaN
   NaN     3     4   NaN
   NaN     5   NaN   NaN
   NaN   NaN   NaN   NaN
A(:,:,3) =
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN

How do I then get

ans =
   NaN     2
     3     4
     5   NaN

I'd like to do this in four dimensions, and with much larger matrixes than the example matrix A here.

Did you know you can just do A = NaN(5,4)? In Matlab, NaN is both a double and a matrix-generating command – Rody Oldenhuis Aug 19, 2012 at 18:28

My solution to the problem based on the input A as posted by OP:

>> [i,j,k] = ind2sub(size(A),find(~isnan(A)));
>> l = min([i j k]);
>> u = max([i j k]);
>> B=A(l(1):u(1),l(2):u(2),l(3):u(3))
   NaN     2
     3     4
     5   NaN
>> size(B)
ans =
     3     2

Since you stated that you want to do this on much larger matrices I'm not sure about the performance of @ronalchn's solution - that is all the all-calls. But I have no idea to what extend that matters - maybe someone can comment...

s is not defined in your solution. You obviously don't know how to estimate algorithmic performance. The all calls will probably take less time than the isnan calls - algorithmic complexity equal, MATLAB probably implements bitsets. – ronalchn Aug 19, 2012 at 21:56
A(~all(all(all(isnan(A),2),3),4),...
  ~all(all(all(isnan(A),1),3),4),...
  ~all(all(all(isnan(A),1),2),4),...
  ~all(all(all(isnan(A),1),2),3))

Basically, the rule is for N dimensions:

  • on all N dimensions you do the isnan() thing.

  • Then wrap it in with the all() function N-1 times,

  • and the 2nd argument each of the all() functions for the ith dimension should be numbers 1 to N in any order, but excluding i.

  • Since Theodros Zelleke wants to see whose method is faster (nice way of saying he thinks his method is so fast), here's a benchmark. Matrix A defined as:

    A = NaN*ones(100,400,3,3);
    A(2:4,2:3,2,2) = [1 2; 3 4; 5 6];
    A(2,2,2,2) = NaN;A(4,3,2,2) = NaN;
    A(5:80,4:200,2,2)=ones(76,197);
    

    His test defined as:

    for i=1:100 [i,j,k,z] = ind2sub(size(A),find(~isnan(A))); l = min([i j k z]); u = max([i j k z]); B=A(l(1):u(1),l(2):u(2),l(3):u(3),l(4):u(4));

    With results:

    Elapsed time is 0.533932 seconds.
    Elapsed time is 0.519216 seconds.
    Elapsed time is 0.575037 seconds.
    Elapsed time is 0.525000 seconds.
    

    My test defined as:

    for i=1:100 isnanA=isnan(A); ai34=all(all(isnanA,3),4); ai12=all(all(isnanA,1),2); B=A(~all(ai34,2),~all(ai34,1),~all(ai12,4),~all(ai12,3));

    With results:

    Elapsed time is 0.224869 seconds.
    Elapsed time is 0.225132 seconds.
    Elapsed time is 0.246762 seconds.
    Elapsed time is 0.236989 seconds.
                    apologies for questioning the performance of your solution, thx for making that clear...So, I learned that all is so fast that its irrelevant here... but then my code loses the time in the ind2sub call, right?
    – tzelleke
                    Aug 20, 2012 at 9:19
                    The time difference is actually quite unimportant and contrived. Any number of factors alters how fast it performs, even for the same size matrix. Actually, the faster method depends on how many NaN values there are and where the NaN/non-NaN values are. What is important is that both have the same "algorithmic complexity", and roughly the same constant. Ie. they both take similar amounts of time (time differs by no more than 3x)
    – ronalchn
                    Aug 20, 2012 at 9:27
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.