Set max and min values of a matrix - matlab

I have a matrix 640-by-480 where each element has data. I want to set the values of the element to zero where the original values are not between two numbers. For example, A is a 640-by-480 matrix. For the i-th element A(i), if the value of A(i) is between 10 and 20 leave it, if not then set A(i)=0. Could anyone suggest a simple way instead of using loops?

Try this for values between 10 and 20:
A(A < 10 | A > 20) = 0;
The expression "A < 10 | A > 20" creates a logical mask, then the values under this mask are set to zeros.

Related

Produce 6 different number by only use "randi" and some loops

I want to only use "randi" this function to produce the 6 different number randomly in matlab ,and the range of these 6 number is 1 ~ 12.
number=randi([1,12],1,6)
c=0;
for n=1:6%when "n" is 1 to 6
while c <= 6 %while c is less equal than 6,do the program below
c = c + 1; %c=c+1
if number(n) == number(c) %when the nth element is equal to cth element
number(n) = randi(12); %produce a random integer in the nth element
c = 0; %the reason why i set c=0 again is because i want to check again whether the new random integer is the same as cth element or not
end
end
end
final_number=number
but the result still show me like
1 "2" 6 11 "2" 3
5 "8" "8" 12 3 1
How do i improve my code to produce 6 different numbers.i don't want to always rely on the convenient matlab instruction too much,so my tags will also write c.hoping someone can help me to improve this
If you're trying to reproduce randsample (or randperm), why not just reproduce the algorithm MATLAB uses? (As far as we can tell...)
This is the Fisher-Yates shuffle. If you have a vector v, each iteration selects a random, previously unused element and puts it at the end of the unselected elements. If you do k iterations, the last k elements of the list are your random sample. If k equals the number of elements in v, you've shuffled the entire array.
function sample = fisher_yates_sample(v, k)
% Select k random elements without replacement from vector v
% if k == numel(v), this is simply a fisher-yates shuffle
for n = 0:k-1
randnum = randi(numel(v)-n); % choose from unused values
% swap elements v(end-n) and v(randnum)
v([end-n, randnum]) = v([randnum, end-n]);
end
sample = v(end-k+1:end);
end
Unlike MATLAB's version, mine requires a vector as input, so to get 6 random values in the range 1:12 you'd call the function like this:
>> fisher_yates_sample(1:12,6)
ans =
5 11 6 10 8 4
Since you're re-selecting single random numbers, when there is one occuring multiple times, why not just re-selecting all numbers at once?
% Initial selecting of random numbers.
number = randi([1, 12], 1, 6)
% While the amount of unique elements in numbers is less than 6:
while (numel(unique(number)) < 6)
% Re-select random numbers.
number = randi([1, 12], 1, 6)
end
And since you wrote, you specifically want to use the randi method, I guess there is a reason, you don't want to use randperm(12, 6)!?
What you are looking for is randperm. It produces a random permutation of a range of integers, so that if you select the first k numbers, you are sure that you get k unique integers in the range [1;n].
In your case, simply call:
randperm(12,6)

How to obtain indices of repetitive values based on condition

I am trying with following code, but get indice of last value only
A=[ 3 4 1 2 4 4 4]
B=unique(A)
[b1 b2]=max(B)
while i<=numel(A)
if A(i)==A(b2)
ID=A(i)
end
end
Is there any way other in matlab to get all indices of value 4 (max value).
If you want to find the indices of the largest value in your matrix, there is no need for unique at all. It's superfluous. Just use find and max simultaneously:
ID = find(A == max(A));
max(A) returns the largest value in A. A == max(A) returns a logical vector where 1 corresponds to a value in A matching the largest value in A and 0 otherwise. Finally, find determines the locations in the input that are non-zero, so in effect we are finding the locations that match the largest value in A.

How to check my matrix if its divisible by 12

im new to matlab and i've run into a slight problem. I want to check my matrix that generated random number if they are divisible by 12. Then i want to list number of digit divisible by 12 and the total sum of those.
clc
clear
format compact
a=4
b=0
N=50+a
R=randi([100+a,159+b], 1, N) % generate random no. from 100+a to 159 on a matrix 1xN
s1=0
N1=0
for i = 1
for j= 1:N
if rem(R,12)==0
N1=N1+1;
s1=s1+R(i,j);
else
N1=N1+0;
s1=s1+0;
end
end
end
numberof1=N1
sum1=s1
Your code isn't working because your are calling rem(R, 12) (remainder of all elements) as opposed to the remainder of the specific element (rem(R(i,j), 12)).
The better approach though would be to remove the for loop and generate a logical matrix the size of R that is true when that number is divisible by 12 and false otherwise by passing the entire matrix to rem.
is_divisible_by_12 = rem(R, 12) == 0;
Then we can use this to compute the sum of these by using this logical array as an index into R
subset = R(is_divisible_by_12);
number = numel(subset);
s1 = sum(subset);

sum matrix using logical matrix - index exceeds matrix dimensions

I have two matrices.
mcaps which is a double 1698 x 2
index_g which is a logical 1698 x 2
When using the line of code below I get the error message that Index exceeds matrix dimensions. I don't see how this is the case though?
tsp = nansum(mcaps(index_g==1, :));
Update
Sorry I should have mentioned that I need the sum of each column in the mcaps vector
** Example of data **
mcaps index_g
5 6 0 0
4 3 0 0
6 5 1 1
4 6 0 1
8 7 0 0
There are two problems here. I missed one. Original answer is below.
What I missed is that when you use the logical index in this way, you are picking out elements of the matrix that may have different numbers of elements in each column, so MATLAB can't return a well formed matrix back to nansum, and so returns a vector. To get around this, use the fact that 0 + anything = 0
% create a mask of values you don't want to sum. Note that since
% index_g is already logical, you don't have to test equal to 1.
mask = ~index_g & isnan(mcaps)
% create a temporary variable
mcaps_to_sum = mcaps;
% change all of the values that you don't want to sum to zero
mcaps_to_sum(mask) = 0;
% do the sum
sum(mcaps_to_sum,1);
This is basically all that the nansum function does internally, is to set all of the NaN values to zero and then call the sum function.
index_g == 1 returns a 1698 x 2 logical matrix, but then you add in an extra dimension with the colon. To sum the columns, use the optional dim input. You want:
tsp = nansum(mcaps(index_g == 1),1);

Matlab min function and 'lt' operator

I'm using min function to find minimum value in Complex Double array and set return value to slider Min property.
when user change slider value, find values that little than slider value.
but min and lt operator return different result.
for example looks below code.
array=[-5.61160893699794 + 1.29692613840634i , -0.000211300000000000 - 1.85290000000000e-06i; -1.91125106282203 + 1.60401019880518i,-0.768982324325300 + 0.732360902857864i]
vmin=min(min(array));
res=array(array<vmin);
result:
vmin= -2.1130e-04 - 1.8529e-06i
res= -5.6116 + 1.2969i
-1.9113 + 1.6040i
-0.7690 + 0.7324i
According to the MATLAB documentation:
min
When X is complex, the minimum is computed using the magnitude
min(ABS(X)). In the case of equal magnitude elements, then the phase
angle min(ANGLE(X)) is used.
lt
lt compares only the real part of the elements in A.
You can reproduce this behavior:
>> 1 < -2i
ans = 0
>> min([1,-2i])
ans = 1
The expression array < vmin creates the logical array:
>> array < vmin
ans =
1 0
1 1
where the 1s indicate that those elements of array have a real part that is less than the minimum value's real part.
And when you use that logical output as a logical index like array(array<vmin), the output is a column vector of the elements of array that are true. So everything is working as it should.
If array were wrapped in abs, the resulting logical array would be all false:
>> abs(array) < vmin
ans =
0 0
0 0
which may be a more intuitive result.
I don't know if this is important, but I will note that the min function finds the value with the smallest magnitude (in absolute value) for complex entires while lt only tests the real part.