Matlab : Confusion over find() function - arrays

find() function returns the indices where the elements are non-zero. I tried with different array sizes but both give error :
In an assignment A(I) = B, the number of elements in B and I must be the same.
I am confused because when the array size is same, still I am getting this error.
This is just to understand what went wrong:
LEt,
Example 1: Same array size
A = [20;21;3;45;5;19;1;8;2;1];
B = A;
for i =1:length(B)
pos(i) = find(A == B(i));
end
I should have got pos = [1,2,3,4,5,6,7,8,9,10]. But the loops exits after i = 7, giving `pos = [1,2,3,4,5,6]'
Example 2: Dissimilar array size
C = [20;1;10;3];
for i =1:length(C)
pos(i) = find(A == C(i));
end
Can somebody please explain what is wrong in my understanding and an illustration of how I can work with same and different array length of A and B? Thank you.

The problem is that find(A == 1) returns two indexes, both 7 and 10, and that can't be stored in pos(i), since pos(i) can only hold a single number.
Unfortunately, the generic error message happened to have the same name for the matrices as two of your matrices, which can be confusing before you'we seen it a few times.

Related

Unexpected behavior while using end to grow arrays

while building a video array from a directory of images I encounter unexpected behavior. Original code:
vid = [];
for i =startframe:endframe
image = [directoryOfImages ,'\', images_names{1,i}];
vid(:,:,:,end+1) = imread(image);
waitbar((i-startframe) / (endframe-startframe));
end
Then I ran this code to check thing up:
a = []; size(a)
a(end+1) = 1; size(a)
The first size was [0, 0] and the second size was [1, 1]. The same expected behavior I got in this code:
b = []; size(b)
b(:,end+1) = 1; size(b)
The first size was [0, 0] and the second size was [1, 1]. But in this code, something weird happened:
c = []; size(c)
c(:,:,end+1) = 1; size(c)
while here the first size was [0,0] and the second one was [1,1,2].
This was very unexpected. I printed c and I got this:
>>c
c(:,:,1) =
0
c(:,:,2) =
1
Finally, I ran this script:
c=[]; c(:,:,end)=1; size(c)
and I got [1, 1].
can someone explain what is going on here? when I use c=[] do I get an empty array with the size of [0,0,1]? so how come size(c) doesn't mention it? and why when I use c(:,:,end)=1; its size is not [1,1,1]? and what about when I use c(:,:,:,end)=1?
This is just MATLAB choosing what to display.
In MATLAB, matrices are infinite dimensional. As a nice example, lets try your b:
b = [];
b(:,end+1) = 1;
As you know, you can query the size of an specific dimension with size. E.g. size(b,2) returns 1. But what does size(b,12345) return?, well, it returns 1 also, as matrices are infinite dimensional. In the 12345th dimension, the size of b is 1.
However, what horrible would the display function be, if every time you type size(b) it outputs an infinite amount of dimensions! Thus when displaying, MATLAB defaults to displaying 2 dims OR N-dims, where N is the furthest dimension with data on it (non-singleton dimension).
Thus, what you are seeing with your c example is weird behaviour by the display function, not the size function. size(c,3) returns 1. This is caused also by the [] only setting the size of the first two dimensions to zero, to avoid having a MxPx0 variable when filling it up (c(:,:,end)=img, what happens with end ?), which is essentially an empty variable.

MATLAB - Equivalent logical indexing leading to two different results

I'm writing a piece of code for submission through an online grader, as showcased below. B is some given array filled any/all integers 1 through K, and I want to extract the corresponding logical indices of matrix X and perform some operations on those elements, to be put into a return array:
for i = 1:K
A = X(B == i, :);
returnArr(i, :) = sum(A) / length(A);
end
This did not pass the grader at all, and so I looked to change my approach, instead indexing array X indirectly via first using the "find" function, as below:
for i = 1:K
C = find(B == i);
returnArr(i,:) = sum(X(C,:)) / length(C);
end
To my surprise, this code passed the grader without any issues. I know there are a plethora of variations between graders, and one might handle a particular function differently than another, but from a MATLAB functionality/coding perspective, what am I missing in terms of discrepancies between the two approaches? Thanks!
I think the problem is that:
length(C) == sum(B == i)
while
length(A) == max([sum(B == i) , size(X , 2)])
In other words, to obtain the same result of the second example with the first one, you should modify it like this:
A = X(B == i , :);
returnArr(i, :) = sum(A) / size(A,1);
The function length returns the length of largest array dimension

how to check in matlab if a 3D array has at least one non zero element?

I tried to check if a 3D array is not all zeros using the next code:
notAll_n0_GreaterThan_ni=1;
while notAll_n0_GreaterThan_ni
notAll_n0_GreaterThan_ni=0;
mask=(n0<ni);
numDimensions=ndims(mask);
for dim_ind=1:numDimensions
if any(mask,dim_ind)
notAll_n0_GreaterThan_ni=1;
break;
end
end
if notAll_n0_GreaterThan_ni
n0(mask)=n0(mask)+1;
end
end
It seems I have error in the code because at the end I get for example: n_0(11,3,69)=21 while ni(11,3,69)=21.1556.
I can't find the error. I'll appreciate if someone shows me where I'm wrong and also if there is a simpler way to check existence of nonzero elements in a 3D array.
Let x denote an n-dimensional array. To check if it contains at least one non-zero element, just use
any(x(:))
For example:
>> x = zeros(2,3,4);
>> any(x(:))
ans =
0
>> x(1,2,2) = 5;
>> any(x(:))
ans =
1
Other, more exotic possibilities include:
sum(abs(x(:)))>0
and
nnz(x)>0
This is what you looking for
B = any(your_Array_name_here(:) ==0); no need for loops
the (:) turns the elements of your_Array into a single column vector, so you can use this type of statement on an array of any size
I 've tested this and it works
A = rand(3,7,5) * 5;
B = any(A(:) ==0);

Array is filled with undefined values (Erlang)

Updated Question; Original below.
I am trying to create an array which represents a grid of cells, which have tuples containing the walls they are surrounded by.
I have come up with this:
rooms(Array) ->
Size = array:size(Array),
if
Size == ?HSIZE * ?VSIZE ->
Array;
true ->
HFactor = Size rem ?VSIZE,
VFactor = Size div ?HSIZE,
Room = {1+HFactor+11*VFactor,
7+HFactor+11*VFactor,
12+HFactor+11*VFactor,
6+HFactor+11*VFactor},
rooms(array:set(Size, Room, Array))
end.
When I run this with rooms(array:new()). I get the following array back:
{array,25,100,undefined,
{{{1,7,12,6},
{2,8,13,7},
{3,9,14,8},
{4,10,15,9},
{5,11,16,10},
{12,18,23,17},
{13,19,24,18},
{14,20,25,19},
{15,21,26,20},
{16,22,27,21}},
{{23,29,34,28},
{24,30,35,29},
{25,31,36,30},
{26,32,37,31},
{27,33,38,32},
{34,40,45,39},
{35,41,46,40},
{36,42,47,41},
{37,43,48,42},
{38,44,49,43}},
{{45,51,56,50},
{46,52,57,51},
{47,53,58,52},
{48,54,59,53},
{49,55,60,54},
undefined,undefined,undefined,undefined,undefined},
10,10,10,10,10,10,10,10}}
Which is quite close to the desired result, but there are two things I can't quite put my finger on (The numbers are correct). Why does it look like it is split up into multiple subarrays? What are those undefineds and 10's doing there? These are mostly due to my lack of erlang knowledge, because array:get produces the expected results, but I couldn't find anything which explains where they come from.
Original Question
rooms(Array) ->
Size = array:size(Array),
if
Size == 5 ->
Array;
Size rem 5 == 0 ->
rooms(array:set(Size, array:new(), Array));
true ->
In_Array = array:get(array:size(Array), Array),
In_Size = array:size(In_Array),
Room = {1+In_Size+11*In_Size,
7+In_Size+11*In_Size,
12+In_Size+11*In_Size,
6+In_Size+11*In_Size},
New_In = array:set(In_Size, Room, In_Array),
rooms(array:set(Size, New_In, Array))
end.
I call it with rooms(array:new()). but the result is
** exception error: bad argument
in function array:size/1 (array.erl, line 317)
in call from framework_kamer:rooms/1 (framework_kamer.erl, line 195)
Which makes sense because In_Array is not an array, but undefined. However, I can't figure out why.
Side question, is there an easier/cleaner/better way to do this?
You are (in the second call of the recursion) trying
In_Array = array:get(array:size(Array), Array),
As array is zero-indexed this will always fail, as the access will be always be off by one. Change this line to
In_Array = array:get(array:size(Array) - 1, Array),
and you are fine.
A few comments on your code:
Conventional variable naming in Erlang would be CamelCase without underscores (i.e. InArray)
Expressing a 2-dimensional array as nested arrays is almost never a good idea. Linearalise it by writing simple wrappers that recalculate a one-dimensional index from x and y as index = y * max_x + x.

How to build an array by function handle

I am trying to produce something like this in MATLAB with function handle
f=#(x,y)(x(1)*x(2)+y);
c=[2 3 4;5 9 2];
h=[5 1 2];
f(c,h)
The answer should be:
15 11 12
But when I write this code below, it just builds a number not an array.
f=#(x)(x(1)*x(2))
f(c)
answer:
10
Can someone explain me where I went wrong?
I do not know what you expected here. The cause of the problem is quite clear.
a = 1;
b = 2;
c = [3 4];
d = a*b+c;
is a scalar + vector operation which always returns
ans = [a*b+c(1), a*b+c(2)];
however scalar*scalar which was the second case always returns a scalar. What you do is that you multiply the first matrix element of x (or c) with the second element. That is to say element c(1,1)*c(2,1) since matlab works columnwise. If you looks at your values you would probably notice the answer is incorrect as well, if you are trying to do what I think you are. You could try this instead,
f=#(x,y)(x(1,:).*x(2,:)+y);
c=[2 3 4;5 9 2];
h=[5 1 2];
f(c,h)
which multipies the elements on the first row of x with the same column on the second row and then adds y. An anonymous function takes a number of inputs and perform a defined operation, the same as ordinary functions or ordinary codes. You can see them as functions that does not require a call to another m file. The main differences (except that ordinary functions gives more freedom), are how they are handled by matlab and not in the syntax.

Resources