# mapping a smaller matrix in a greater matrix with a specific sequence

I have a matrix 300x300 i need to map the values ina greater matrix (900x900) in the positions given by the sequence
$$({3*i-1,3*j-1)}$$
while everything else remain empty, how can achieve this result?

KroneckerProduct

f5 = KroneckerProduct[#, {{0, 0, 0}, {0, 1, 0}, {0, 0, 0}}] &;
f6 = KroneckerProduct[SparseArray@#, SparseArray[{2, 2} -> 1, {3, 3}]] &;


SparseArray and Band

f1 = SparseArray[Band[{2, 2}, Automatic, {3, 3}] -> #,3 Dimensions[#]] &;


or

f1 = SparseArray[Band[{2, 2}, 3 Dimensions[#], {3, 3}] -> #] &


f2 = ArrayFlatten[Map[ArrayPad[{{#}}, 1] &, #, {2}]] &;


Examples

n = 3;
m = RandomInteger[{1, 5}, {n, n}];
Row[MatrixForm /@ {m, f1@m, f2@m}] Timings:

f0 = (* from bill's answer *) SparseArray[Flatten[{Drop[ArrayRules@ SparseArray[#] /.
{x_, y_} -> {3 x - 1, 3 y - 1}, -1], 3 Dimensions[#] -> 0}, 1]] &;

f3 = (* from george2079's answer *) SparseArray[{i_ /; Mod[i + 1, 3] == 0,
j_ /; Mod[j + 1, 3] == 0} :> #[[(i + 1)/3, (j + 1)/3]], {3 Length@#, 3 Length@#}] &;

f4 = (* from ciao's answer *) Upsample[#, 3, 2] &;

n = 300; mm = RandomInteger[10, {n, n}];

Equal @@ Through[{f0, f1, f2, f3, f4, f5, f6}[mm]]


True

Grid[SortBy[{HoldForm[#], First@AbsoluteTiming[#[mm]]} & /@
{f0, f1, f2, f3, f4, f5, f6}, Last], Dividers -> All] // Style[#, 16, Bold, "Panel"] & • it works thanks but i fail at understanding the code, i am just a novice. same thing with bill's answer. what does the & and the # means? – Alucard May 13 '16 at 19:05
• @Alucard, f1 = SparseArray[Band[{2, 2}, Automatic, {3, 3}] -> #,3 Dimensions[#]] &; is the same as f1[mat_] : = SparseArray[Band[{2, 2}, Automatic, {3, 3}] ->mat,3 Dimensions[mat]] ; see Function (&) and Slot (#) in the docs. – kglr May 13 '16 at 19:10

Perhaps I'm missing something in the question, but why not just:

new=Upsample[old, 3, 2];

• god i have no words, i did not know there was this command – Alucard May 13 '16 at 22:56
• @Alucard - Developing a full vocabulary of Mathematica functions is probably on the order of developing a decent vocabulary in English - I doubt there are many that know all of the functions off the tops of their heads... – ciao May 13 '16 at 23:15

Here is one way -- represent the original array in sparse form, then replace the indices with the desired ones:

m = RandomInteger[{-5, 5}, {3, 3}];
Normal@SparseArray[Drop[ArrayRules@SparseArray[m]
/. {x_, y_} -> {3 x - 1, 3 y - 1}, -1]] // MatrixForm


More generally, and controlling for the ultimate size of the matrix:

n = 3; m = RandomInteger[{1, 5}, {n, n}];
Normal@SparseArray[Flatten[{Drop[ArrayRules@SparseArray[m]
/. {x_, y_} -> {3 x - 1, 3 y - 1}, -1], {3 n, 3 n} -> 0}, 1]]

• I think the dimensions of the resulting matrix should be {3 n, 3 n} (not {n^2,n^2}). – kglr May 13 '16 at 20:30
• @kglr - Thanks for noticing... just fooled by the simple n=3 case where 3n==n^2! – bill s May 14 '16 at 2:28

A different SparseArray approach:

n = 3
(m = RandomInteger[{1, 5}, {n, n}]) // MatrixForm
big = SparseArray[
{i_ /; Mod[i + 1, 3] == 0, j_ /; Mod[j + 1, 3] == 0} :>
#[[(i + 1)/3, (j + 1)/3]] , {3 Length@#, 3 Length@#}] &@m;
MatrixForm[big]