4
$\begingroup$

Question

Is there elegant code like m[[{2, 3;;4}]] = m[[{3;;4, 2}]]?


Example

  1. Swapping column 2 with columns 3 to 4:

In:

o = 2; t = -2;
lis = Array[x, {2, 5}];
% // MatrixForm
Transpose@Insert[Transpose@Drop[lis, None, {o}], lis[[All, o]], t];
% // MatrixForm

Out:


  1. Swapping columns 2~3 with columns 4~5:

In:

lis = Array[x, {2, 6}];
% // MatrixForm
Transpose@Insert[Transpose@Drop[lis, None, {2, 3}], lis[[All, 2 ;; 3]], 4];
% // MatrixForm

Out:

P.S. As for question "How to avoid/remove the redundant {}?"
— Answers are in another post: How to avoid the redundant curly brackets {} when using list parameters/arguments?

$\endgroup$
1
$\begingroup$

Swapping column 2 with columns 3 to 4

lis[[All, {1, 3, 4, 2, 5}]]

or

lis[[All, Permute[Range[5], Cycles[{{2, 4, 3}}]]]]

Edit: Original Answer

lis.SparseArray[Thread[Rule[Transpose[{{1, 3, 4, 2, 5}, Range[5]}], 1]], {5, 5}]
//MatrixForm

$$\left( \begin{array}{ccccc} x(1,1) & x(1,3) & x(1,4) & x(1,2) & x(1,5) \\ x(2,1) & x(2,3) & x(2,4) & x(2,2) & x(2,5) \\ \end{array} \right)$$

or, using Permute/Cycles (2-> 4 ->3):

lis.SparseArray[Thread[Rule[Transpose[{Permute[Range[5], Cycles[{{2, 4, 3}}]], Range[5]}], 
1]], {5, 5}]

Swapping columns 2~3 with columns 4~5

lis2[[All, {1, 4, 5, 2, 3, 6}]]

or

lis2[[All, Permute[Range[6], Cycles[{{2, 4}, {3, 5}}]]]]

Edit. Original Answer:

 lis2.SparseArray[Thread[Rule[Transpose[{{1, 4, 5, 2, 3, 6}, Range[6]}],1]], {6, 6}]
 // MatrixForm

$$\left( \begin{array}{cccccc} x(1,1) & x(1,4) & x(1,5) & x(1,2) & x(1,3) & x(1,6) \\ x(2,1) & x(2,4) & x(2,5) & x(2,2) & x(2,3) & x(2,6) \\ \end{array} \right)$$

or using Permute/Cycles (2->4, 3->5):

lis2.SparseArray[Thread[Rule[Transpose[{Permute[Range[6], Cycles[{{2, 4}, {3, 5}}]], 
  Range[6]}], 1]], {6, 6}]

where:

lis = Array[x, {2, 5}];
lis2 = Array[x, {2, 6}];

Note I tried deleting this answer as the first attempt was very poor. I couldn't as the answer had been accepted. I am sure the simplified solution is not original, so I have opted for community wiki instead. Feel free to modify (or delete).

$\endgroup$
  • $\begingroup$ I like your approach which has much mathematical taste :) $\endgroup$ – ooo Jan 29 '18 at 14:30
  • $\begingroup$ @ooo Thanks! It is not often I get a compliment like that. (Perhaps Permute/Cycles is 'the way to go'?) $\endgroup$ – user1066 Jan 29 '18 at 15:48
6
$\begingroup$

edit with a more general function:

swapRanges[array_, {first_, last_}]:= Module[{temp = array}
, Block[{Span}
  , Span = Apply[Sequence]@*Range
  ; temp[[All, {first, last}]] = temp[[All, {last, first}]]
  ; temp
  ]
]


lis = Array[x, {2, 5}];

swapRanges[lis, {2;;3, 4;;5}]

enter image description here

swapRanges[lis, {;; 2, 3 ;; 5 ;; 2}]

enter image description here

| improve this answer | |
$\endgroup$
5
$\begingroup$

By in-place modification:

lis = Array[x, {2, 5}];

from = 2;
to = 4;
rot = 1;
lis[[All, from ;; to]] = lis[[All, RotateLeft[Range[from, to], rot]]];
lis // MatrixForm

By creating a new list

lis = Array[x, {2, 5}];
perm = PermutationList[
 Cycles[{RotateLeft[Range[from, to], rot]}], 
 Dimensions[lis][[2]]]
];
result = lis[[All,perm];
result // MatrixForm
| improve this answer | |
$\endgroup$
  • $\begingroup$ I'm 100% sure OP meant those ranges to be adjacent in general. E.g. swap 2 and 4;;5. $\endgroup$ – Kuba Jan 29 '18 at 9:27
  • $\begingroup$ @Kuba You mean them not to be adjacent? Now I see. $\endgroup$ – Henrik Schumacher Jan 29 '18 at 10:12
  • 2
    $\begingroup$ Yes, sorry. Are there any tips on how to not lose focus during typing one sentence? :( $\endgroup$ – Kuba Jan 29 '18 at 10:18
  • $\begingroup$ @Kuba Haha, none that I know of and that really help... $\endgroup$ – Henrik Schumacher Jan 29 '18 at 10:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.