# Function on a block matrix

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.

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

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 InternalPartitionRagged 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 = InternalPartitionRagged[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

• 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.
– RSG
May 7, 2018 at 6:52
• Starting with M11.2, you can use TakeList instead of InternalPartitionRagged, although it doesn't support your specific syntax. The equivalent TakeList syntax woud be TakeList[A, i, j] May 7, 2018 at 14:49

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.