0

I have a column vector X of size N-by-1 with two values: 10 and 25. I want to switch those values, i.e. every element with value 10 should become 25 and vice versa.

Pseudo-code:

A = [ 10; 25; 25; 10; 25; 25; 10]
NewNew = find(A == 10)
NewNew2 =  find(A == 25)

NewNew3 = [ ];

for NewNew3
if NewNew
    NewNew=25
else NewNew2
    NewNew2=10
end

I tried this now still no success:

for B = 1:size(A)
if  A == 10
    A = 25
elseif  A == 25
    A = 10
end
end

How can I switch values?

Adriaan
  • 17,741
  • 7
  • 42
  • 75

3 Answers3

3
N=10;
X = randi([1 2],N,1);
A = zeros(size(X)); % create output vector
A(X==2)=1; % whenever X==2, set A=1
A(X==1) = 2; % whenever X==1, set A=2

[X A]

ans =

     1     2
     2     1
     2     1
     1     2
     2     1
     1     2
     1     2
     2     1
     2     1
     2     1

You can do this with logical indexing. Just make sure to get a separate output vector, as setting X(X==1)=2 will make your whole vector 2, and then calling X(X==2)=1 sets the whole vector to 1. If necessary, use X=A at the end.

Final advice: your for loop needs indexing, which is about as basic as MATLAB goes. You can solve this problem with a for loop, although I'd recommend using logical indexing as per the above. I strongly suggest you to either take a basic course in MATLAB, or read the MathWork's own tutorial on MATLAB.

Adriaan
  • 17,741
  • 7
  • 42
  • 75
3

If you only have two values, why not subtracting from their addition:

A = 35 - A;
Iban Cereijo
  • 1,675
  • 1
  • 15
  • 28
1

There are some other options you can consider.

1.) (Irrelevant option. Use ibancg's option, cleaner and faster.) If you have just those two values, a simpler and faster solution would be to initialize to one of these two numbers and flip just a subset of the numbers:

A = [ 10; 25; 25; 10; 25; 25; 10];
X = ones(size(A)) * 10; % initialize X with 10.
X(A == 10) = 25; % Set values where A is 10 to 25.

2.) (irrelevant, too slow): Another possibility if you know that some numbers will never appear is to use temporary third number and avoid creating a new matrix - operate kind of similar to the typical "swap two numbers" recipe.

A(A == 10) = 1; % Temp value
A(A == 25) = 10;
A(A == 1) = 25;

3.) Finally, the third option would be to save logical matrix and then overwrite A.

Ais10 = A==10;
Ais25 = A==25;
A(Ais10) = 25;
A(Ais25) = 10; 

Now, for the benchmarks: I used very simple script, varying N and M.

tic
for i = 1 : M
X1 = randi([1 2],N,1);
... % depends on test cases. Result can be in X or A.
toc

Therefore, it also times randi, but as it is a part of every code it should only mask the relative speed differences, keeping absolute ones the same. Computer is i7 4770k, 32GB RAM. Row vector has 1000 elements, 1M runs; 100M elements, 10 runs; 1B elements, 1 run; 3B elements, 1 run

  1. Codes that rely on having just 2 values:

    • 1I): 18.3 s; 20.7 s; 20.3 s; 63.6 s
    • 1Z): 33.0 s; 38.2 s; 38.0 s; NA (out of memory)
  2. Code relies on lacking one value that can be used for swap:

    • 2Z): 54.0 s; 60.5 s; 60.0 s; 659 s
  3. Code handles arbitrary data, swapping 2 values.

    • 3A): 45.2 s; 50.5 s; 49.0 s; NA (out of memory)
    • 3Z): 41.0 s; 46.1 s; 45.8 s; NA (out of memory)

So, to summarize, Ibancg's option is much faster and simpler than the rest and should be used if possible (= just those 2 different values in the vector). My 2nd option is far too slow to be relevant. Rather do step by step swap on the vector using any of the general methods. Either general option is fine.

Adriaan
  • 17,741
  • 7
  • 42
  • 75
Zizy Archer
  • 1,392
  • 7
  • 11