logical operation within vector range expression in MATLAB - matlab

can I have something like
A=1:10;
A(1:2 && 5:6)=0;
meaning I want to zero out specific ranges within my vector index expression in one line
Is that possible?
And what if I wanted to zero out all the rest like
A(~[1:2]) = 0
What's the way of logical NOT within vector indexing?
Thanks

The following should work:
idx = [1:2,5:6];
A(idx) = 0
If you want to zero the complement of the vector of indices:
idx = [1:2,5:6];
A(~ismembc(1:length(A),idx)) = 0
Where ismembc is a faster, lightweight version of ismember that assumes the array is sorted and non-sparse with no NaN elements. (Credit goes to this question.)

Just do A([1:2 5:6]). I.e., just create a vector of the indices you want to zero out.

Related

MATLAB: Use Logical indexing to replace the values in the matrix by its value divided by 2?

So I have a matrix A. And I can find the values of greater than 7 with logical indexing of A>7.
How can I then, replace all the values of A>7 by the numbers divided by 2?
I tried:
A(A>7) = [num1/2, num2/2, etc]
But I'd want the math done without me inputting the nums/2 values to be replaced accordingly.
You can do it easily by using the same indices likes the following:
indices = A > 7;
A(indices) = A(indices)/2;

Find column-count inbetween integers row-wise in matrix (matlab)

I have a stupid problem, I can't find the answer to ^^.
I have a 100x10000 double matrix containing integers from 1 to 4 and want to find row-wise the column-count between every single integer
My first idea was to use:
storage_ones = cell(100,1);
for n = 1:100;
[row col] = find(matrix(n,:)==1);
storage_ones{n,1} = col;
end
And then substract them in another loop. But with find I get following Answer:
Empty matrix: 1-by-0
Does anybody have an idea how I can solve this problem?
Thanks in advance!!
Your issue is potentially due to one of two things:
Since you're using a double datatype, it is possible that you're encountering floating point errors where the values aren't going to be 1 exactly. If this is the case consider not checking for exact equality and instead check if it is very close to 1 using a small epsilon (here I used 1e-12).
[row, col] = find(abs(matrix(n,:) - 1) < 1e-12);
If you really have an integer datatype, consider using uint8 to store your data rather than double and then you can perform exact comparisons.
matrix = uint8(matrix);
% Then for your comparison
find(matrix(n,:) == 1)
You may just not have any 1's in that column. If find can't find any matches, it returns an empty array.
find([1 2 3] == 4)
% Empty matrix: 1-by-0

Finding all rows in a pair of vectors where both entries are non-zero (Octave)

I have a n x 2 matrix in Octave, and I would like to find every row where the matrix(row, 1) and matrix(row, 2) elements are non-zero. I could use a for loop like this:
[nrows, ncols] = size(data);
for i = 1:nrows
if(data(i, 1) ~= 0 && data(i, 2) ~= 0)
% Do something
end
end
The issue with that is that n is about 3 million, and iteration in Octave takes for ever. I feel like there is a way to do it with find, but I haven't been able to figure it out yet.
Anyone have any advice?
Thanks!
You can create use logical indexing:
idx = all(data(:,1:2)~=0, 2);
The resulting vector idx contains 1s in every row where both cells are non-zero and 0 otherwise.
I think in this case (since it is related with zero values) the following also should work
idx=(data(:,1).*data(:,2)~=0)
But #H.Muster's solution is the one that works in all cases, hence a better one.
If performance is the issue: maybe try converting both columns to logical:
useful = and(logical(data(:,1)),logical(data(:,2)))
Then you can again use logical indexing:
filtered = data(useful,:)

How to extract a part of a matrix with condition in Matlab

I have a sat of matrices and I want to extract only a part of the matrix that satisfy a condition.
For example: values of the 150x180 matrix goes from 0 to 2.80 and I only want those between 1.66 and 1.77
I want to keep the values within the rang in their original location in the original matrix and set the other to zero.
can anybody help me please.
Thank you
You can use logical indexing. First, find A entries that do not satisfy your conditions. Next, using A(idx) change them to 0:
% example matrix
A = 2.8*rand(150, 180);
% find entries meeting some criterion
idx = A<1.66 | A>1.77;
A(idx) = 0;
Or simpler, as Rody Oldenhuis suggested, you can include the logical expression directly in the matrix reference:
A(A<1.66 | A>1.77) = 0;
This yields a shorter and cleaner code, but not a faster code: MATLAB still explicitly creates the logical index variable, but clears it afterwards.

Find highest/lowest value in matrix

very basic question: How can I find the highest or lowest value in a random matrix.
I know there is a possibility to say:
a = find(A>0.5)
but what I'm looking for would be more like this:
A = rand(5,5)
A =
0.9388 0.9498 0.6059 0.7447 0.2835
0.6338 0.0104 0.5179 0.8738 0.0586
0.9297 0.1678 0.9429 0.9641 0.8210
0.0629 0.7553 0.7412 0.9819 0.1795
0.3069 0.8338 0.7011 0.9186 0.0349
% find highest (or lowest) value
ans = A(19)%for the highest or A(7) %for the lowest value in this case
Have a look at the min() and max() functions. They can return both the highest/lowest value, and its index:
[B,I]=min(A(:)); %# note I fixed a bug on this line!
returns I=7 and B=A(7)=A(2,2). The expression A(:) tells MATLAB to treat A as a 1D array for now, so even though A is 5x5, it returns the linear index 7.
If you need the 2D coordinates, i.e. the "2,2" in B=A(7)=A(2,2), you can use [I,J] = ind2sub(size(A),I) which returns I=2,J=2, see here.
Update
If you need all the entries' indices which reach the minimum value, you can use find:
I = find(A==min(A(:));
I is now a vector of all of them.
For matrices you need to run the MIN and MAX functions twice since they operate column-wise, i.e. max(A) returns a vector with each element being the maximum element in the corresponding column of A.
>> A = rand(4)
A =
0.421761282626275 0.655740699156587 0.678735154857773 0.655477890177557
0.915735525189067 0.0357116785741896 0.757740130578333 0.171186687811562
0.792207329559554 0.849129305868777 0.743132468124916 0.706046088019609
0.959492426392903 0.933993247757551 0.392227019534168 0.0318328463774207
>> max(max(A))
ans =
0.959492426392903
>> min(min(A))
ans =
0.0318328463774207
Note that this only works for matrices. Higher dimensional arrays would require running MIN and MAX as many times as there are dimensions which you can get using NDIMS.
Try this out
A=magic(5)
[x,y]=find(A==max(max(A))) %index maximum of the matrix A
A_max=A(x,y)
[x1,y1]=find(A==min(max(A))) %index minimum of the matrix A
A_min=A(x1,y1)