Why is this MATLAB 'if' statement not working?

I am new to MATLAB and I cannot figure out why my if statement and condition are not working. I have a 100 by 4 matrix ( randQ

). Columns 1

thru 3

are random integers and column 4 contains either 1 or 2 in each row.

I want to change everything 1

to 0

and everything 2

to 1

in a column 4

in this 100 by 4 matrix. What I do:

if randQ(:,4) == 1
    randQ(:,4) = 0
elseif randQ(:,4) ==2
    randQ(:,4) = 1
end

      

It doesn't throw any errors, but the matrix doesn't change and the conditions make sense in my opinion. I don't know why it doesn't work. Any explanations would be appreciated.

+3


source to share


4 answers


Renouncement

Some of the other answers contain incorrect / imprecise statements:

As an example,

if [1, 1, 1] == 1
    disp("True")
end

      

will display "True"

. Below is an explanation.


You write

I cannot figure out why my "if" statement and condition are not working

What's really going on is pretty subtle. You need to develop an understanding of several things:

  • what the expression returns randQ(:,4) == 1

    ,
  • what the if if statement does when presented with a predicate that is not a scalar but an array,
  • what randQ(:,4) = 0

    does it do.

Also, you need to use logical indexing for this kind of operations .

What randQ(:,4) == 1

returns

Assuming it randQ

is a 100 by 4 randQ(:,4) == 1

array , the expression returns a boolean array , i.e. complete (logical) zeros and ones:

  • if the i-th record of this array is (boolean) 1

    , it means that the record (i, 4) randQ

    is 1

    ;
  • if the i-th element of this array is (boolean) 0

    , it means that the record (i, 4) is randQ

    not equal 1

    .

Array as a predicate



Now that you know you are using an array for an if statement predicate, let's see what happens. If the predicate of your if statement is an array, MATLAB will execute the if clause only if all entries in that array evaluate to boolean1

.

For example,

if [1, 2; 3, 4]
    disp("True")
else
   disp("False")
end

      

will display "True"

because all records [1,2;3,4]

are returned as boolean 1

, which causes the predicate to evaluate to boolean 1

(true). Nevertheless,

if [1, 2; 3, 0]
    disp("True")
else
   disp("False")
end

      

display "False"

, because the record (2.2) from [1,2;3,0]

receives as logic 0

that causes the predicate is evaluated as a logical 0

(false). Therefore, if at least one entry in randQ(:,4)

is equal to zero, if

it will not be executed.

Assignment attributes are wrong anyway

Assignment operator

randQ(:,4) = 0

      

will overwrite all entries in the 4th column with using 0

, which is not what you want.

Better approach: use boolean indexing

You write

I want to change all 1 to 0 and all 2 to 1 in column 4 in this 100 by 4 matrix.

A more idiomatic approach for this, as pointed out by giuseppe , is to use boolean indexing :

randQ(randQ(:,4) == 1, 4) = 0;
randQ(randQ(:,4) == 2, 4) = 1;

      

There is no need to use the function find

because it randQ(:,4) == 1

already returns what you want: a 100-by-1 boolean array indicating which entries in the 4th column randQ

are equal 1

.

+6


source


You are asking if your vector is not == 1.



There are more ways to do this, but you can loop over each value using the for parameter.

0


source


The result randQ(:,4)

is a vector with length 100. Then you try to compare it to a scalar, which will only be true if all the terms of the vector (or matrix) are equal to the scalar.

> M=[1 1; 2 1; 3 2]
M =                                            

   1   1
   2   2
   3   1

> M(:,1)
ans =

   1
   2
   3

      

Also, the way you are trying to change the values ​​is wrong, if you do randQ(:,4) = 1

then the whole 4th th column will get the value 1:

>M(:,2)=0
M =

   1   0
   2   0
   3   0

      

The easiest way to achieve what you want is to loop through the matrix line by line, check the value and then change it.

0


source


Like the other answers, you are trying to compare a vector to a scalar, this will never be true.

Instead, you can achieve your goal with the Find function , this function actually implements element comparison.

randQ(find(randQ(:,4) == 1),4) = 0;
randQ(find(randQ(:,4) == 2),4) = 1;

      

0


source







All Articles