Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

So I have been fiddling with this the last hour and I just can't get it to work.

I have 3 matrices of the same size which contain nothing but 0's in a list, I also have 3 matrices of the same size (not same as first 3) that have different values in them (also in a list). I have a Coordinate x and y value as well (x is right, y is down). I want to replace the values of a small part of the matrices containing 0's with their corresponding matrix (corresponding one is the ones with different values)

e.g.

$a=\begin{matrix}0&0&0&0&0\\0&0&0&0&0\\0&0&0&0&0\\0&0&0&0&0\\0&0&0&0&0\end{matrix}$

$b=\begin{matrix}1&2&3\\4&5&6\end{matrix}$

$CoordX=2$, $CoordY=3$

When I use the function, I want the output to be

$Output->\begin{matrix}0&0&0&0&0\\0&0&0&0&0\\0&1&2&3&0\\0&4&5&6&0\\0&0&0&0&0\end{matrix}$

This was my attempt at the function but for the three matrices instead

CreatePlaceholderMatrix[Matrix_,CoordX_,CoordY_]:=
(PlaceholderMatrix=Table[0,{3},{64},{64}];
For[i=CoordX,i==CoordX+Dimensions[Matrix[[1]][[1]]][[1]]-1,i++
 For[j=CoordY,j==CoordY+Dimensions[Matrix[[1]][[1]]][[1]]-1,j++
  For[k=1,k==3,k++,PlaceholderMatrix[[k,i,j]]=Matrix[[k,1,i,j]]
  ]
 ]
];
PlaceholderMatrix)

The value of Matrix is in the form of (and if it helps is square):

MatrixForm/@ImageData[Image,"Byte",Interleaving->False]

and that is why I needed an extra [[1]] whenever I referred to Matrix (not sure exactly why but it was the only value that worked).

Anyways, whenever I run the function, it just presents PlaceholderMatrix as 3 64*64 Matrices of 0's and nothing else. It seems as if it didn't even go through the for loop.

I also want the final answer to be in the same Format as matrix, so I can do operations with it later and convert it to an image

If anyone can explain why this is happening, or any alternative method that may work better, please tell.

share|improve this question
1  
Also, this link will save your time in the future while working with matrices: elegant operations on matrix rows.... It is good to avoid loops too. –  Kuba Aug 18 '13 at 7:51
3  
MatrixForm is an output-formatting tool (see 3098). Use it thus MatrixForm[mat] when you want to display mat as a table of values between parentheses. Do not use it like this: mat = MatrixForm[...]. The internal form of a matrix is a List of sub-Lists, where the sublists represent the rows and must have the same length. –  Michael E2 Aug 18 '13 at 11:53
add comment

2 Answers

up vote 10 down vote accepted

Why complicate it?

a[[3 ;; 4, 2 ;; 4]] = b;

Mathematica graphics

Here is a general function. It take a main matrix, and a sub matrix. It puts the sub matrix inside the main matrix. All what you have to do is just tell it the starting row number and starting column number for where to insert the sub matrix at.

Updated:

Added pattern checking on arguments. Added additional checks inside to make it more robust. Used basic Throw mechanism to throw error when matrix to insert is too large or does not fit at given location.

mk[main_?MatrixQ,(*matrix to insert into*)
  sub_?MatrixQ,(*matrix to be inserted*)
  row_Integer /; row > 0,(*row number to insert at*)
  col_Integer /; col > 0 (*column number to insert at*)
  ] := Module[{m = main, mainRow, mainCol, subRow, subCol},

  {mainRow, mainCol} = Dimensions[main];
  {subRow, subCol} = Dimensions[sub];

  (*error checking*)
  If[subRow > mainRow || subCol > mainCol, 
   Throw["mk::sub matrix larger than main", $Failed]];

  If[row + subRow - 1 > mainRow || col + subCol - 1 > mainCol,
   Throw["mk::sub matrix too large to fit at location given", $Failed]];

  (*all clear, lets go for it*)
  m[[row ;; row + subRow - 1, col ;; col + subCol - 1]] = sub;
  (* now, that was not too hard. lets return the updated matrix *)

  m
  ]

Calling it like this:

a = Table[0, {5}, {5}];
b = {{1, 2, 3}, {4, 5, 6}};
(mk[a, b, 2, 1]) // MatrixForm

Mathematica graphics

(mk[a, IdentityMatrix[4], 2, 1]) // MatrixForm

Mathematica graphics

(mk[a, b, 3, 3]) // MatrixForm

Mathematica graphics

(mk[a, a, 2, 2]) // MatrixForm

Mathematica graphics

(mk[a, a, 1, 1]) // MatrixForm

Mathematica graphics

If you can catch the error like this:

Catch[a = mk[a, b, 5, 3], $Failed]

Mathematica graphics

If there was no error, then a will be updated as normal:

Catch[a = mk[a, b, 2, 3], $Failed]
MatrixForm[a]

Mathematica graphics

share|improve this answer
    
I tried that, but simply put copies of $b$ in each of the squares, so basically the elements that were replaced, were actually replaced with the matrix $b$ instead of their corresponding elements in $b$ –  user9053 Aug 18 '13 at 7:49
    
I do not follow you. I'll post a general function that you can use. –  Nasser Aug 18 '13 at 7:52
    
That works, I'll just have to separate the three matrices, convert them and rejoin them –  user9053 Aug 18 '13 at 8:14
add comment

Since your background matrix will "contain nothing but 0's" you should be building a SparseArray.
There is already a syntax for what you want using Band:

b = {{1, 2, 3}, {4, 5, 6}};

m = SparseArray[Band[{3, 2}] -> b, {5, 5}];

m // MatrixForm

enter image description here

You can use MatrixForm to display the array or Normal to convert it to a non-sparse form.

You can use the third argument of SparseArray to specify a different background:

SparseArray[Band[{3, 2}] -> b, {5, 5}, -3] // MatrixForm

enter image description here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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