4
$\begingroup$

I am trying to write a program of the following nature. Let $A = [[a_{ij}]]$ be a $4 \times 4$ matrix. I have to divide it in the form

$$ A = \begin{bmatrix} P & Q \\ R & S\end{bmatrix}$$

where $P,Q,R,S$ are all $2 \times 2$ matrices. Now I want to apply an arbitrary map on this form. For a concrete example let the map be $f\left(\begin{bmatrix} a & b \\ c & d \end{bmatrix} \right) = \begin{bmatrix} a-d & b-c \\ c-b & d+a \end{bmatrix}$, which applied on the actual matrix should be of the form $$ f(A) = \begin{bmatrix} P -S & Q-R \\ R-Q & S+P\end{bmatrix}.$$ The output should be seen in the form of a $4\times 4$ matrix. All these can be done by hand of course.

Of course the matrix which I want to work on is very large (and may not admit a $2 \times 2$ block matrix form). Similarly the function $f$ may be equally complicated so much so that entrywise manipulation may not be easy. Is there any easy way to do all these? Advanced thanks for any help or suggestion.

$\endgroup$
2
  • 2
    $\begingroup$ Is it possible to find a linear transformation? $\endgroup$ May 7, 2018 at 6:34
  • $\begingroup$ @ΑλέξανδροςΖεγγ I am preparing for the most general transformation, not necessarily linear. $\endgroup$
    – RSG
    May 7, 2018 at 6:48

2 Answers 2

4
$\begingroup$

Does this do what you want?

f[A_?MatrixQ] := 
 With[{
   m = Quotient[Dimensions[A][[1]], 2], 
   n = Quotient[Dimensions[A][[2]], 2]
  }, 
  With[{
    a = A[[;; m, ;; n]], 
    b = A[[;; m, -n ;;]], 
    c = A[[-m ;;,  ;; n]], 
    d = A[[-m ;;, -n ;;]]
   },
   ArrayFlatten[{
     {a - d, b - c},
     {c - b, d + a}
     }]
   ]
  ]

This may be a bit more readable:

g[A_?MatrixQ] := With[{
   m = Quotient[Dimensions[A][[1]], 2],
   n = Quotient[Dimensions[A][[2]], 2]
  },
  With[{a = Partition[A, {m, n}]},
   ArrayFlatten[{
     {a[[1, 1]] - a[[2, 2]], a[[1, 2]] - a[[2, 1]]},
     {a[[2, 1]] - a[[1, 2]], a[[2, 2]] + a[[1, 1]]}
     }]
   ]
  ]

You an use Internal`PartitionRagged for partitioning a matrix into blocks of varying size. Here is an example:

A = RandomInteger[{1, 100}, {6, 6}];
i = {1, 2, 3};
j = {2, 3, 1};
B = Internal`PartitionRagged[A, {i, j}];
Map[Dimensions, B, {2}]
ArrayFlatten[B] == A

$$\left( \begin{array}{ccc} \{1,2\} & \{1,3\} & \{1,1\} \\ \{2,2\} & \{2,3\} & \{2,1\} \\ \{3,2\} & \{3,3\} & \{3,1\} \\ \end{array} \right)$$

True

$\endgroup$
2
  • $\begingroup$ Excellent. +1 for the code. However, instead of manually writing $a,b,c,d$, is there a way to modify the code so that we get like $a_{11}, a_{12},a_{21},a_{22}$, so that this can be used irrespective of dimensions. $\endgroup$
    – RSG
    May 7, 2018 at 6:52
  • $\begingroup$ Starting with M11.2, you can use TakeList instead of Internal`PartitionRagged, although it doesn't support your specific syntax. The equivalent TakeList syntax woud be TakeList[A, i, j] $\endgroup$
    – Carl Woll
    May 7, 2018 at 14:49
0
$\begingroup$

Apologies if I miss-understood the question - first answer post.

Given your matrix A = {{P, Q}, {R, S}}, could you not just use the Reverse function?

A - Reverse[A, {1, 2}]*{{1, 1}, {1, -1}} // MatrixForm

$$ \begin{matrix} P-S & Q-R\\ -Q+R & P+S\\\end{matrix} $$

I must admit the multiplication to gain the positive P+S is rather clunky, I'm sure this could be improved.

$\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.