using logical arrays to select certain elements into another matrix - matlab

I believe the answer to this is simple but my brain will not function.
Say I have a m x n matrix which is of type double & lets call it A. I also have a matrix B, which is m x n and is all NaN's.
I then want to find out which numbers are say equal to some number, let say 100. I can do the following,
A_index = A == 100;
So I now have a logical array, A_index. This is all fine.
My question is how do I select the elements from A where A_index is true into matrix B?
Some made up matrices
A= [ 50 100 75 90 100; 0 50 60 30 10; 100 25 80 250 100; 5 100 0 100 90];
A_index = A == 100;
B= zeros(4,5) * NaN;

Something like:
A= [ 50 100 75 90 100; 0 50 60 30 10; 100 25 80 250 100; 5 100 0 100 90];
A_index = A == 100;
B= zeros(4,5) * NaN;
B(A_index) = 100
This way you will get 100 in the entries of B where A is equal to 100
See the section on logical indexing in the MATLAB docs

Related

how to access values of one matrix coresponding to the matrix of other values

data=[ 20 25 30 35 40]; and a vector u of specific values for my data vector, where is u=[0.5 0.8 1]; and I want to access values from vector u
for each element of data vector to calculate values of a and c where
b=data+u
c=data.*u
I wrote this program in MATLAB
data=[ 20 25 30 35 40];
u=[0.5 0.8 1];
i=0;
if (data(i+1)<=25)
u=0.5;
elseif (data(i+1)>25 || data(i+1)<35)
u=0.8;
else (data(i+1)>35)
u=1;
end
b=data+u
c=data.*u
but i did not find right answer can u help me to write it properly?
data=[ 20 25 30 35 40];
u=[0.5 0.8 1];
for i = 1:length(data)
if (data(i)<=25)
u_idx=1
elseif (data(i)>25 & data(i)<=35)
u_idx=2;
else (data(i)>35)
u_idx=3;
end
b(i)=data(i)+u(u_idx);
c(i)=data(i).*u(u_idx);
end

Extract Sequence of Rows in Column (MATLAB)

I am trying to extract a sequence of rows from a column of data in MATLAB. For example, my data looks like this in one column:
10
20
30
40
50
60
70
80
90
100
110
120
130
I want to select a sequence of rows and store these rows in a column vector A that looks like this after extracting the first 3 rows skipping 2 rows then selecting the next 3 rows and skipping 2 rows and selecting the next 3 to the end of the column.
Finally, the data should look like this with 9 rows and 1 column:
10
20
30
60
70
80
110
120
130
Thank you!
Let
x = [10 20 30 40 50 60 70 80 90 100 110 120 130].'; %'// data
m = 3; %// keep
n = 2; %// skip
Then
y = x(mod(0:end-1,m+n)<=m-1);
or equivalently
y = x(mod(0:numel(x)-1,m+n)<=m-1);
How this works: generate the sequence 0,1,2,... numel(x)-1. Each number corresponds to a position in x. To keep m and skip n cyclically, you apply mod(...,m+n) to that sequence. For example, for m=3, n=2 the result is sequence 0,1,2,3,4,0,1,2,.... You then select those numbers (that is, the corresponding entries of x) that are <=m-1. This results in the periodic pattern "keep, keep, keep, skip, skip".
To first skip and then keep (reverse from above): just reverse the inequality:
y = x(mod(0:end-1,m+n)>=m-1);
or
y = x(mod(0:numel(x)-1,m+n)>=m-1);
Try this, assuming a is your input column vector -
r_accept = 3; %// number of rows to accept
r_reject = 2; %// number of rows to reject
ind1 = bsxfun(#plus,1:r_accept+r_reject:numel(a),[0:r_accept-1]') %//'
out = a(ind1(ind1(:)<=numel(a))) %// desired output
I just figured out another way to compliment the nice solutions using find function.
If my data is:
x = [10; 20; 30; 40; 50; 60; 70; 80; 90; 100; 110; 120; 130]
and I want to extract a repeating sequence of rows then:
Develop an index of the repeating pattern or row sequence of keeps (3) and skips (2) rows. My index would be then:
index = [1:5 1:5 1:5]
or
index = 123451234512345
Then use the find function to logically index the "keep" sequence.
a = find(index<4)
which gives:
a = 1 2 3 6 7 8 11 12 13
then:
b = x(a)
produces
b = 10 20 30 60 70 80 110 120 130

Sorting a matrix in MATLAB

I have this problem that I need to sort a matrix in MATLAB.
Input:
[20 10 0 50 0;
300 100 50 50 100]
And I'd like the output to be:
[0 0 10 20 50;
50 100 100 300 50]
So I'd like it to sort the first column but the rows remain unchanged. Help is needed!
You did write the answer yourself, try sort
A = [20 10 0 50 0; 300 100 50 50 100];
[A(1,:) idx] = sort(A(1,:),2);
A(2,:) = A(2,idx);
You could also use sortrows and get the desired result in one line:
result = sortrows(A.',1).';

MATLAB: get equally spaced entries of Vector

How would it be possible to get equally spaced entries from a Vector in MATLAB, e.g. I have the following vector:
0 25 50 75 100 125 150
When I chose 2 I want to get:
0 150
When I chose 3 I want to get:
0 75 150
When I chose 4 I want to get:
0 50 100 150
Chosing 1, 5 or 6 shouldn't work and I even need a check for an if-clause for that but I can't figure this out.
You can generate the indices with linspace and round:
vector = [0 25 50 75 100 125 150]; % // data
n = 4; % // desired number of equally spaced entries
ind = round(linspace(1,length(vector),n)); %// get rounded equally spaced indices
result = vector(ind) % // apply indices to the data vector
If you want to force that values 1, 5 or 6 for n don't work: test if n-1 divides length(vector)-1). If you do that you don't need round to obtain the indices:
if rem((length(vector)-1)/(n-1), 1) ~= 0
error('Value of n not allowed')
end
ind = linspace(1,length(vector),n); %// get equally spaced indices
result = vector(ind) % // apply indices to the data vector
Use linspace:
>> a
a =
0 25 50 75 100 125 150
>> a(linspace(1,length(a),4))
ans =
0 50 100 150
>> a(linspace(1,length(a),3))
ans =
0 75 150
>> a(linspace(1,length(a),2))
ans =
0 150
Note that, except for 1, the invalid values raise an error:
>> a(linspace(1,length(a),5))
error: subscript indices must be either positive integers or logicals
>> a(linspace(1,length(a),6))
error: subscript indices must be either positive integers or logicals

Pulling a subset of a matrix in MATLAB

I want to cluster an array, this array contain some angle I want to calculate the difference between of these degree and select one group between this array, this group should have maximum number and the difference between the member of that should not be larger than specific number.
for example if specific number is 30
and array is
[10 20 30 40 100 120 140]
answer should be
[10 20 30 40]
100-30 >= 30 so it is not included.
A one-line solution:
a = [10 20 30 40 100 120 140];
s = 30;
b = a( abs(a-s) < s )
a = [10 20 30 40 100 120 140]; #initial array
b = []; #result array
s = 30;
for i = 1:length(a)
if abs(a(i) - s) < s
b = [b a(i)];
end
end