4
$\begingroup$

I have the following self-explanatory question.

https://1drv.ms/u/s!AsyHs3E_aioxhipb3wSPSX_heN-t

enter image description here

As seen from the above matrices, I start with the "original" matrix, which is a symmetric matrix, meaning that first row and first column represent the same variable, say X, and 2nd row and 2nd column represent the variable Y, following Z, W, V. I first want to move 2nd row in the "original" matrix to 4th row. This operation is shown in the matrix denoted by r24. After this operation, I want to do the same operation on the same columns, meaning that I want to move 2nd column to 4th column as shown in c24. All of these operations are shown with the colored text. The resulting final matrix, which I aim to create, c24, should be symmetric with respect to the variable names. It means that the final matrix has the ordered variable names as X, Z, W, Y, V in columns and rows. In fact, if the above two operations are done correctly, the order of the variables in rows and columns will remain identical.

I like to do all the operations using a Mathematica function such as f[original, 2, 4] to create the final matrix c24.

Thank you all.

$\endgroup$
2
  • 1
    $\begingroup$ closely related/ possible duplicate: Move element inside a list $\endgroup$
    – kglr
    Mar 20, 2019 at 17:21
  • 1
    $\begingroup$ FWIW: your matrix is called a Hankel matrix. HankelMatrix[Range[5], Range[5, 9]] $\endgroup$ Mar 23, 2019 at 12:45

4 Answers 4

5
$\begingroup$

Simply use Part and Set:

f[A_?SquareMatrixQ, i_Integer, j_Integer] := Module[{p, idx},
 idx = Range[i, j, Sign[j - i]];
 p = Range[1, Length[A]];
 p[[idx]] = RotateLeft[idx];
 A[[p, p]]
 ]

A = Outer[Plus, Range[5], Range[0, 4]];
A // MatrixForm

$\left( \begin{array}{ccccc} 1 & 2 & 3 & 4 & 5 \\ 2 & 3 & 4 & 5 & 6 \\ 3 & 4 & 5 & 6 & 7 \\ 4 & 5 & 6 & 7 & 8 \\ 5 & 6 & 7 & 8 & 9 \\ \end{array} \right)$

B = f[A,2,4];
B // MatrixForm

$\left( \begin{array}{ccccc} 1 & 3 & 4 & 2 & 5 \\ 3 & 5 & 6 & 4 & 7 \\ 4 & 6 & 7 & 5 & 8 \\ 2 & 4 & 5 & 3 & 6 \\ 5 & 7 & 8 & 6 & 9 \\ \end{array} \right)$

$\endgroup$
6
  • $\begingroup$ Your answer is very good, with one slight change. When you move the 2nd row to 4th row, the order of the rows should remain unchanged. It means that when you move the 2nd row, the 3rd and 4th rows should just be moved up without changing the order. Of course the same applies to the column movements. This is important for my purpose and that is why I gave a name for rows and columns. Thank you very much for your very quick answer. $\endgroup$ Mar 20, 2019 at 14:03
  • $\begingroup$ @TugrulTemel I see. Is this better now? I am not sure if the case $i>j$ is handled as you expect. $\endgroup$ Mar 20, 2019 at 14:16
  • $\begingroup$ Excellent...that is what I aim to achieve. Really, thank you so much for your prompt answer. regards, Tugrul $\endgroup$ Mar 20, 2019 at 14:34
  • 1
    $\begingroup$ You didn't reply, but anyway: q = Range[i, j, Sign[j - i]]; p = RotateLeft[q]; $\endgroup$
    – Mr.Wizard
    Mar 21, 2019 at 23:20
  • 3
    $\begingroup$ @Mr.Wizard Sorry, I've been out tonight. This won't happen again, I promise ;) Thank you, that is indeed simpler. I took the freedom to incorporate that into my solution (in an updated version with more performance). $\endgroup$ Mar 21, 2019 at 23:35
5
$\begingroup$

to move a row from $i$ to $j$:

rowmove[A_?MatrixQ, i_Integer, j_Integer] := Insert[Delete[A, i], A[[i]], j]

to move a column from $i$ to $j$:

colmove[A_?MatrixQ, i_Integer, j_Integer] := Transpose@rowmove[Transpose[A], i, j]

both at the same time:

move[A_?MatrixQ, i_Integer, j_Integer] := colmove[rowmove[A, i, j], i, j]
$\endgroup$
3
  • $\begingroup$ Clean solution, copying it... $\endgroup$
    – MikeY
    Mar 20, 2019 at 14:54
  • 1
    $\begingroup$ Here is somewhat simplified version of your solution f[A_?MatrixQ, i_Integer, j_Integer] := (B = Insert[Delete[A, i], A[[i]], j]; Insert[Delete[Transpose@B, i], B[[All, i]], j]) or this one g[A_?MatrixQ, i_Integer, j_Integer] := (B = Transpose@Insert[Delete[A, i], A[[i]], j]; Transpose@Insert[Delete[B, i], B[[i]], j]) $\endgroup$ Mar 21, 2019 at 13:40
  • $\begingroup$ @OkkesDulgerci I don't think it's a good idea to use global variables like B in a function definition. Instead, I'd use With or Module to make the variable local. $\endgroup$
    – Roman
    Mar 21, 2019 at 14:58
4
$\begingroup$

Define the indices that you want to interchange in a list $ind$ and then you can index into the array $a$ directly.

a = {{1, 2, 3, 4, 5}, {2, 3, 4, 5, 6}, {3, 4, 5, 6, 7},
     {4, 5, 6, 7, 8}, {5, 6, 7, 8, 9}}; 
ind = {1, 3, 4, 2, 5};
a[[ind, ind]]

If you don't want to specify the index array each time, Roman points out that you can build a simple function to do it:

indexlist[n_, i_, j_] := Insert[Delete[Range[n], i], i, j]

So to get the above you would specify

ind = indexlist[5,2,4]
$\endgroup$
1
  • $\begingroup$ You can get the index list ind with indexlist[n_, i_, j_] := Insert[Delete[Range[n], i], i, j]. In this case, indexlist[5, 2, 4] will give {1, 3, 4, 2, 5}. $\endgroup$
    – Roman
    Mar 21, 2019 at 1:23
1
$\begingroup$
f[A_?MatrixQ, i_Integer, j_Integer] := With[{B = Transpose@Insert[Delete[A, i], A[[i]], j]}, 
  Transpose@Insert[Delete[B, i], B[[i]], j]]
f[A, 2, 4] // MatrixForm
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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