2

I have a tensor T

T=ones(2,2,2)

T(:,:,1) =

 1     1
 1     1

T(:,:,2) =

 1     1
 1     1

Now I want to add an element by doing

T(3,3,3)=100

and I get the following result

T(:,:,1) =

 1     1     0
 1     1     0
 0     0     0

T(:,:,2) =

 1     1     0
 1     1     0
 0     0     0

T(:,:,3) =

 0     0     0
 0     0     0
 0     0   100

As you can see matlab automatically inserts 0 for the new row and column elements. I know that I can convert the zeros using T(T==0)=NaN. But I'm looking for a way where NaN is inserted immediately so I won't have to do the additional conversion.

  • Is there a way that matlab automatically inserts NaN instead of 0 for those elements?

Desired result:

T(:,:,1) =

 1     1    NaN
 1     1    NaN
NaN   NaN   NaN

T(:,:,2) =

 1     1    NaN
 1     1    NaN
NaN   NaN   NaN

T(:,:,3) =

NaN   NaN   NaN
NaN   NaN   NaN
NaN   NaN   100

Appreciate your help.

SeanKw
  • 63
  • 1
  • 7
  • 1
    Padding with zeros is the default. Create a nan matrix using `nan(dim1,dim2,...)` and fill it if this is what you want to have. – patrik Mar 27 '14 at 09:37

1 Answers1

2

Code

T=ones(2,2,2)
T(3,3,3)=100
T(T==0)=NaN 
%%// T(~T)=NaN would work too, but not a good practice as T is not logical 

Or

T=ones(2,2,2)
T1 = NaN(3,3,3)
T(1:2,1:2,1:2) = T;
T1(3,3,3)=100

Or

T1 = NaN(3,3,3)
T1(1:2,1:2,1:2)=1;
T1(3,3,3)=100
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • Is this more efficient than T(T==0)=NaN? EDIT: my intention was not to have an additional step, is this somehow possible? – SeanKw Mar 26 '14 at 22:32
  • `T(~T)=NaN` and `T(T==0)=NaN` must be identical in terms of being efficient and their performance, at least I would think so. – Divakar Mar 26 '14 at 22:33
  • is it somehow possible to configure matlab so that it uses NaN itself instead of 0? – SeanKw Mar 26 '14 at 22:35
  • 1
    @SeanKw I don't think so. Padding with `zeros` seems to be it's default nature in many cases, including a case like this one. – Divakar Mar 26 '14 at 22:37
  • ok thank you @Divakar, I just wanted to check. Appreciate your help – SeanKw Mar 26 '14 at 22:39
  • I think I'm fine with T(T==0)=NaN. Or are any of your suggestions more efficient? – SeanKw Mar 26 '14 at 22:45
  • @SeanKw If I have to choose, probably the third one, because the memory allocation is done only once, as compared to the other two methods, where that is done twice. Memory allocation in one go is what is prefered. – Divakar Mar 26 '14 at 22:48
  • 1
    @SeanKw Considering your method, with `T=ones(2,2,2)`, you allocate 8 locations and then when you do `T(3,3,3)=100`, you allocate for (27-8) = 19 more locations. The memory space would be the same, but the process of memory allocating is done twice. – Divakar Mar 26 '14 at 22:54
  • But again, you are accessing many memory locations with the third method at `T1(1:2,1:2,1:2)=1;`. So, I would say, do your benchmark with your own datasize and see it for yourself. – Divakar Mar 26 '14 at 23:03
  • The code snippet `T=ones(2,2,2); T(3,3,3)=100; T(~T)=NaN;` should **NEVER EVER** be used for applications like this! This is a the perfect way to screw up your code and may lead to hours of unnecessary debugging. There will be a problem if at least one of the existing elements is 0. – patrik Mar 27 '14 at 09:26
  • @patrik Of course it's not a great practice, because MATLAB would allocate memory and assign zeros there on it's own without the programmer doing it. But in this particular case we are doing - `T=ones(2,2,2); T(3,3,3)=100;` and thus, the only zeros would be in the extended region except the end element where 100 was assigned. This guarantees that we are not tinkering with the original data of `ones` and `100` and assigning the extended region as NaNs except the end element. – Divakar Mar 27 '14 at 10:09
  • @patrik Read up the question carefully. Do I need to scream too for that? I hope not. OP had these lines in the code - `T=ones(2,2,2); T(3,3,3)=100;` My answer comes after that, suggesting this - `T(~T)=NaN`. As far as my MATLAB knowledge goes, my suggested answer alone isn't wrong or a bad practice. – Divakar Mar 27 '14 at 11:25
  • @Divakar Please think about it a bit more. You should never write unsatble code, this is always bad practice. There is a reason that `~` is supposed to be used on logicals since `0` can be used on a double while it still does not mean `not`. It is a bad practice to use this on anything that can be `0` without meaning `not`. And random solutions like this will make the code nearly impossible to maintain. – patrik Mar 27 '14 at 11:38
  • @patrik Sure you have a point there. Edited in the code, thanks! – Divakar Mar 27 '14 at 11:44
  • 1
    @Divakar well it is slighly better, but I would go for alternative 2 since this one is the only stable solution. That is the only solution where one of the tensor elements may be `0` and would still not crash or give a wrong answer (though alternative 3 would still be ok). A tensor can typically be defined in in inertial system which would give the tensor a shape closer to `eye(3)`, but that would not necessarily mean that elements `T(2,1)` and `T(1,2)` need to be nan. Especially since most matrix operations would have nans in dimension 1 or 2 then. This is a pain to debug – patrik Mar 27 '14 at 12:07
  • 1
    I think alternative 3 (preallocate with NaN() and update selected elements) is actually what you want: it'll be faster because it preallocates the whole matrix so it'll be faster and you don't have to do comparison tests, so the logic is simpler, and you don't run in to problems with elements that actually are supposed to be zero. (The performance difference is big enough that `mlint` will warn you off the first two approaches.) – Andrew Janke Mar 27 '14 at 14:04
  • @Divakar ok I get your point concerning the memory allocation. So now I'm going to use your third proposal - creating a Nan Tensor with the correct dimensions and then I fill in my values. This is bascially what patrik suggests in his comment above. Thank you guys (sorry can't upvote you due to my low reputation) – SeanKw Mar 27 '14 at 14:08
  • @SeanKw Glad we could help. You can always come back, when you get enough rep for that :) – Divakar Mar 27 '14 at 14:23