How to find value from matrix - matlab

Let say I have a matrix
A=[0.8 0.9 0.7 0.5 0.3 0.8 0.2 0.1]; % 8 points
where A come from logical 1 from B
B=[1 0 1 0 0 1 0 1 0 1 1 0 1 1];
As I want to find location C that satisfies
C=find(A<0.6 & A>0.35)
where the ans is C=4. My question is how to get the true location in B=8?

Unless you do not have the indices stored away somewhere, I cannot see that you have much of a choice here.
tmp = find(B);
idx = tmp(C);
In case you actually want to use this mapping more than once, I would suggest that you store the indices instead of a binary vector. This will also be more memory efficient in case the binary vector is sparse (or not a boolean vector), since you will need less entries.
In case you also need the binary vector, you should store both in case memory allows. When I have done this kind of mapping in Matlab I have actually used both a binary vector (a mask) and an index vector. This have saved me from first mapping the mask to index and then index to filtered position (so to say, skipping the tmp = find(B); idx = tmp(C); part every time and go directly to idx = allIdx(C)).

This will get you the index in B
A=[0.8 0.9 0.7 0.5 0.3 0.8 0.2 0.1];
B=[1 0 1 0 0 1 0 1 0 1 1 0 1 1];
C=find(A<0.6 & A>0.35);
temp=0;
for i=1:size(B,2)
temp=temp+B(i);
if(temp==C)
break;
end
end
locationB=i;
locationB

Related

How to compare 2 matrices and keep greatest values in Matlab

I am using Matlab and have 2 matrices:
A =
0 0 1
1 0 1
1 1 0
and
B =
0 0 1.1
1.0 0 0.8
1.2 0.8 0
My goal is to compare the 2 matrices and get the highest values of each i,j element and store such results into a third matrix C.
I am able to achieve such result by applying a for loop that checks every single element and then stores it into the matrix but i would like to have a more efficient and elegant way to do so. Can you suggest me some better way?
The result should be like:
C =
0 0 1.1
1 0 1
1.2 1 0
C = max(A,B)
Source on documentation

How does Y = eye(K)(y, :); replace a "for" loop? Coursera

Working on an assignment from Coursera Machine Learning. I'm curious how this works... From an example, this much simpler code:
% K is the number of classes.
K = num_labels;
Y = eye(K)(y, :);
seems to be a substitute for the following:
I = eye(num_labels);
Y = zeros(m, num_labels);
for i=1:m
Y(i, :)= I(y(i), :);
end
and I have no idea how. I'm having some difficulty Googling this info as well.
Thanks!
Your variable y in this case must be an m-element vector containing integers in the range of 1 to num_labels. The goal of the code is to create a matrix Y that is m-by-num_labels where each row k will contain all zeros except for a 1 in column y(k).
A way to generate Y is to first create an identity matrix using the function eye. This is a square matrix of all zeroes except for ones along the main diagonal. Row k of the identity matrix will therefore have one non-zero element in column k. We can therefore build matrix Y out of rows indexed from the identity matrix, using y as the row index. We could do this with a for loop (as in your second code sample), but that's not as simple and efficient as using a single indexing operation (as in your first code sample).
Let's look at an example (in MATLAB):
>> num_labels = 5;
>> y = [2 3 3 1 5 4 4 4]; % The columns where the ones will be for each row
>> I = eye(num_labels)
I =
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
>> Y = I(y, :)
Y =
% 1 in column ...
0 1 0 0 0 % 2
0 0 1 0 0 % 3
0 0 1 0 0 % 3
1 0 0 0 0 % 1
0 0 0 0 1 % 5
0 0 0 1 0 % 4
0 0 0 1 0 % 4
0 0 0 1 0 % 4
NOTE: Octave allows you to index function return arguments without first placing them in a variable, but MATLAB does not (at least, not very easily). Therefore, the syntax:
Y = eye(num_labels)(y, :);
only works in Octave. In MATLAB, you have to do it as in my example above, or use one of the other options here.
The first set of code is Octave, which has some additional indexing functionality that MATLAB does not have. The second set of code is how the operation would be performed in MATLAB.
In both cases Y is a matrix generated by re-arranging the rows of an identity matrix. In both cases it may also be posible to calculate Y = T*y for a suitable linear transformation matrix T.
(The above assumes that y is a vector of integers that are being used as an indexing variables for the rows. If that's not the case then the code most likely throws an error.)

How to count non zero elements in a vector and replace this values based the number of occurences [duplicate]

This question already has answers here:
Finding islands of zeros in a sequence
(6 answers)
Closed 7 years ago.
I'm a new matlab user and in my case i have a vector let say:
v = [0 0 0 0.1 0.2 0.3 0.4 0.5 0 0 0 0 0 0 0.1 0.2]
I want to count consecutive non zero values i.e in my vector have first five nonzero values [0.1 0.2 0.3 0.4 0.5] and two last nozeros values [0.1 0.2]
what I want is:
count the consecutive non zero values and put a condition i.e. if the length of nonzeros is greater then 3 (count>3) then the respective values of vector V(i) remain v(i) if the length consecutive values is less than three (count<3) then respective values of v(i) = 0
I want to get a new vector let say v1 derivated from vector v where:
v1 = [0 0 0 0.1 0.2 0.3 0.4 0.5 0 0 0 0 0 0 0 0]
Any help would be appreciated.
If you have the MATLAB Image Processing Toolbox, you can use the power of morphological operations. The morphological opening (imopen) removes objects which are smaller than the structuring element from an image. We can use this in 2D and use [1,1,1] as structuring element to remove objects, i.e. sequences of nonzero elements, which are shorter than 3:
First we make the sequence binary: zero or nonzero.
w = v~=0;
Then we zero-pad the sequence, so short nonzero sequences at the borders get eliminated. As we use [1,1,1] as structuring element, zero-padding by 1 is sufficient:
w = [0,w,0];
Now we do the opening to remove all small nonzero sequences
w1 = imopen(w, [1,1,1]);
The vector w1 now contains 0 if the corresponding element in v is or should be set to 0 and 1 if the value should be kept. To get the result v1, we can ignore the first and last entry (those are the elements from the zero-padding), and multiply that by the input, as e.g. 1 * 0.1 = 0.1:
v1 = w1(2:end-1) .* v;
Which gives the correct result without any for loop, if statement or such stuff! Only 4 simple operations: morphology and a bit of multiplication and zero-padding.
buffer=0 %Buffer to remember non zero values
v=[0 0 0 0.1 0.2 0.3 0.4 0.5 0 0 0 0 0 0 0.1 0.2];
v1=[];
for i=1:length(v)
if v(i)~=0
buffer=buffer+1;
v1(i)=v(i);
end
if v(i)==0
switch buffer
case 1 % case 1 corresponds to only 1 non zero value in a single sequence
v1(i-1)=0;
buffer=0;
case 2 % case 2 corresponds to only 2 non zero value in a single sequence
v1(i-1)=0;
v1(i-2)=0;
buffer=0;
otherwise
buffer=0;
end
end
end
switch buffer % Test for the last two values
case 1
v1(length(v))=0;
case 2
v1(length(v))=0;
v1(length(v)-1)=0;
end
This should do the trick.

How to replace non-zero elements randomly with zero?

I have a matrix including 1 and 0 elements like below which is used as a network adjacency matrix.
A =
0 1 1 1
1 1 0 1
1 1 0 1
1 1 1 0
I want to simulate an attack on the network, so I must replace some specific percent of 1 elements randomly with 0. How can I do this in MATLAB?
I know how to replace a percentage of elements randomly with zeros, but I must be sure that the element that is replaced randomly, is one of the 1 elements of matrix not zeros.
If you want to change each 1 with a certain probability:
p = 0.1%; % desired probability of change
A_ones = find(A); % linear index of ones in A
A_ones_change = A_ones(rand(size(A_ones))<=p); % entries to be changed
A(A_ones_change) = 0; % apply changes in those entries
If you want to randomly change a fixed fraction of the 1 entries:
f = 0.1; % desired fraction
A_ones = find(A);
n = round(f*length(A_ones));
A_ones_change = randsample(A_ones,n);
A(A_ones_change) = 0;
Note that in this case the resulting fraction may be different to that intended, because of the need to round to an integer number of entries.
#horchler's point is a good one. However, if we keep it simple, then you can just multiple your input matrix to a mask matrix.
>> a1=randint(5,5,[0 1]) #before replacing 1->0
a1 =
1 1 1 0 1
0 1 1 1 0
0 1 0 0 1
0 0 1 0 1
1 0 1 0 1
>> a2=random('unif',0,1,5,5) #Assuming frequency distribution is uniform ('unif')
a2 =
0.7889 0.3200 0.2679 0.8392 0.6299
0.4387 0.9601 0.4399 0.6288 0.3705
0.4983 0.7266 0.9334 0.1338 0.5751
0.2140 0.4120 0.6833 0.2071 0.4514
0.6435 0.7446 0.2126 0.6072 0.0439
>> a1.*(a2>0.1) #And the replacement prob. is 0.1
ans =
1 1 1 0 1
0 1 1 1 0
0 1 0 0 1
0 0 1 0 1
1 0 1 0 0
And other trick can be added to the mask matrix (a2). Such as a different freq. distribution, or a structure (e.g. once a cell is replaced, the adjacent cells become less likely to be replaced and so on.)
Cheers.
The function find is your friend:
indices = find(A);
This will return an array of the indices of 1 elements in your matrix A and you can use your method of replacing a percent of elements with zero on a subset of this array. Then,
A(subsetIndices) = 0;
will replace the remaining indices of A with zero.

Algorithm for best-effort classification of vector

Given four binary vectors which represent "classes":
[1,0,0,0,0,0,0,0,0,0]
[0,0,0,0,0,0,0,0,0,1]
[0,1,1,1,1,1,1,1,1,0]
[0,1,0,0,0,0,0,0,0,0]
What methods are available for classifying a vector of floating point values into one of these "classes"?
Basic rounding works in most cases:
round([0.8,0,0,0,0.3,0,0.1,0,0,0]) = [1 0 0 0 0 0 0 0 0 0]
But how can I handle some interference?
round([0.8,0,0,0,0.6,0,0.1,0,0,0]) != [1 0 0 0 0 1 0 0 0 0]
This second case should be a better match for 1000000000, but instead, I have lost the solution entirely as there is no clear match.
I want to use MATLAB for this task.
Find the SSD (sum of squared differences) of your test vector with each "class" and use the one with the least SSD.
Here's some code: I added a 0 to the end of the test vector you provided since it was only 9 digits whereas the classes had 10.
CLASSES = [1,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,1
0,1,1,1,1,1,1,1,1,0
0,1,0,0,0,0,0,0,0,0];
TEST = [0.8,0,0,0,0.6,0,0.1,0,0,0];
% Find the difference between the TEST vector and each row in CLASSES
difference = bsxfun(#minus,CLASSES,TEST);
% Class differences
class_diff = sum(difference.^2,2);
% Store the row index of the vector with the minimum difference from TEST
[val CLASS_ID] = min(class_diff);
% Display
disp(CLASSES(CLASS_ID,:))
For illustrative purposes, difference looks like this:
0.2 0 0 0 -0.6 0 -0.1 0 0 0
-0.8 0 0 0 -0.6 0 -0.1 0 0 1
-0.8 1 1 1 0.4 1 0.9 1 1 0
-0.8 1 0 0 -0.6 0 -0.1 0 0 0
And the distance of each class from TEST looks like this, class_diff:
0.41
2.01
7.61
2.01
And obviously, the first one is the best match since it has the least difference.
This is the same thing as Jacob did, only with four different distance measures:
Euclidean distance
City-block distance
Cosine distance
Chebychev distance
%%
CLASSES = [1,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,1
0,1,1,1,1,1,1,1,1,0
0,1,0,0,0,0,0,0,0,0];
TEST = [0.8,0,0,0,0.6,0,0.1,0,0,0];
%%
% sqrt( sum((x-y).^2) )
euclidean = sqrt( sum(bsxfun(#minus,CLASSES,TEST).^2, 2) );
% sum( |x-y| )
cityblock = sum(abs(bsxfun(#minus,CLASSES,TEST)), 2);
% 1 - dot(x,y)/(sqrt(dot(x,x))*sqrt(dot(y,y)))
cosine = 1 - ( CLASSES*TEST' ./ (norm(TEST)*sqrt(sum(CLASSES.^2,2))) );
% max( |x-y| )
chebychev = max( abs(bsxfun(#minus,CLASSES,TEST)), [], 2 );
dist = [euclidean cityblock cosine chebychev];
%%
[minDist classIdx] = min(dist);
Pick the one you like :)
A simple Euclidean distance algorithm should suffice. The class with the minimum distance to the point would be your candidate.
http://en.wikipedia.org/wiki/Euclidean_distance