views:

2056

answers:

6

I am trying to create a function that will swap a specific number in a matrix with a specific number in the same matrix. For examlpe, if I start with A = [1 2 3;1 3 2], I want to be able to create B = [2 1 3; 2 3 1], simply by telling matlab to swap the 1's with the 2's. Any advice would be appreciated. Thanks!

A: 

I don't have a copy of MatLab installed, but I think you can do some thing like this;

for i=1:length(A)
   if (A(i)=1), B(i) = 2, B(i)=A(i) 
end

Note, that's only convert 1's to 2's and it looks like you also want to convert 2's to 1's, so you'll need to do a little more work.

There also probably a much more elegant way of doing it given you can do this sort of thing in Matlab

>> A = 1:1:3
A = [1,2,3]
>> B = A * 2
B = [2,4,6]

There might be a swapif primitive you can use, but I haven't used Matlab in a long time, so I'm not sure the best way to do it.

tarn
+2  A: 

Not sure why you would to perform that particular swap (row/column interchanges are more common). Matlab often denotes ':' to represent all of something. Here's how to swap rows and columns:

To swap rows:

A = A([New order of rows,,...], :)

To Swap columns:

A = A(:, [New order of columns,,...])

To change the entire i-th column:

A(:, i) = [New; values; for; i-th; column]

For example, to swap the 2nd and 3rd columns of A = [1 2 3;1 3 2]

A = A(:, [1, 3, 2])
Mitch Wheat
+1 because it seems like a very strange thing to have to do... there may be a way to get around it entirely.
David Zaslavsky
A: 

In reference to tarn's more elegant way of swapping values you could use a permutation matrix as follows:

>> a =[1 2 3];
>> T = [1 0 0;
        0 0 1;
        0 1 0];
>> b = a*T
ans =
    1 3 2

but this will swap column 2 and column 3 of the vector (matrix) a; whereas the question asked about swapping the 1's and 2's.

Update

To swap elements of two different values look into the find function

ind = find(a==1);

returns the indices of all the elements with value, 1. Then you can use Mitch's suggestion to change the value of the elements using index arrays. Remeber that find returns the linear index into the matrix; the first element has index 1 and the last element of an nxm matrix has linear index n*m. The linear index is counted down the columns. For example

>> b = [1 3 5;2 4 6];
>> b(3) % same as b(1,2)
ans = 3
>> b(5) % same as b(1,3)
ans = 5
>> b(6) % same as b(2,3)
ans = 6
Azim
Hello everyone, I just finished up writing the code. I wanna thank you all for your help.
+2  A: 

If you have the following matrix:

A = [1 2 3; 1 3 2];

and you want all the ones to become twos and the twos to become ones, the following would be the simplest way to do it:

B = A;
B(find(A == 1)) = 2;
B(find(A == 2)) = 1;

EDIT:

As Kenny suggested, this can even be further simplified as:

B = A;
B(A == 1) = 2;
B(A == 2) = 1;
gnovice
The use of find() isn't necessary but this works.
KennyMorton
Jason S
Agreed. I updated the answer. I had actually first done it the way Doug had (storing the index first so that I could just modify A), but then realized that the OP wanted to make a new matrix anyway. When I simplified it I forgot to remove the finds.
gnovice
To clarify, when I store indices like Doug did in his example, I have fallen into the habit of using FIND. Lately, I've been dealing with very large matrices for which the logical indices would be very sparse. In such a case, storing linear indices takes up less memory than a full logical array.
gnovice
+1  A: 
A = [1 2 3; 1 3 2]

alpha = 1;
beta = 2;

indAlpha = (A == alpha);
indBeta  = (A == beta);

A(indAlpha) = beta;
A(indBeta ) = alpha

I like this solution, it makes it clearer what is going on. Less magic numbers, could easily be made into a function. Recycles the same matrix if that is important.

MatlabDoug
+1  A: 

Another way to deal with the original problem is to create a permutation vector indicating to which numbers should the original entries be mapped to. For the example, entries [1 2 3] should be mapped respectively to [2 1 3], so that we can write

A = [1 2 3; 1 3 2];
perm = [2 1 3];
B = perm(A)

(advantage here is that everything is done in one step, and that it also works for operations more complicated than swaps ; drawback is that all elements of A must be positive integers with a known maximum)

Fanfan

related questions