0
$\begingroup$

I want to pad the numbers,but it throws an error Part::partw,so I use Quiet to suppress this error.

lis = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};

n = 6;(*It can change be any size bigger than Dimensions[lis]*)
sum = ConstantArray[0, {n, n}];

Quiet@Do[sum[[x, y]] = 
lis[[Floor[x/2] + 1, Floor[y/2] + 1]] + 
lis[[Floor[x/2] + 2, Floor[y/2] + 1]] + 
lis[[Floor[x/2] + 1, Floor[y/2] + 2]] + 
lis[[Floor[x/2] + 2, Floor[y/2] + 2]], {x, n}, {y, n}]

mat1=Replace[sum, _Plus -> "Error", {2}]

$\left( \begin{array}{cccccc} 14 & 18 & 18 & 22 & 22 & \text{Error} \\ 30 & 34 & 34 & 38 & 38 & \text{Error} \\ 30 & 34 & 34 & 38 & 38 & \text{Error} \\ 46 & 50 & 50 & 54 & 54 & \text{Error} \\ 46 & 50 & 50 & 54 & 54 & \text{Error} \\ \text{Error} & \text{Error} & \text{Error} & \text{Error} & \text{Error} & \text{Error} \\ \end{array} \right)$

But I expect the output would be:

mat2={{14, 18, 18, 22, 22, 22}, {30, 34, 34, 38, 38, 38}, {30, 34, 34, 38, 38, 38}, {46, 50, 50, 54, 54, 54}, {46, 50, 50, 54, 54, 54}, {46, 50, 50, 54, 54, 54}};

$\left( \begin{array}{cccccc} 14 & 18 & 18 & 22 & 22 & 22 \\ 30 & 34 & 34 & 38 & 38 & 38 \\ 30 & 34 & 34 & 38 & 38 & 38 \\ 46 & 50 & 50 & 54 & 54 & 54 \\ 46 & 50 & 50 & 54 & 54 & 54 \\ 46 & 50 & 50 & 54 & 54 & 54 \\ \end{array} \right)$

How to implement this in Mathematica? Or how about this:How to transform the mat1 to mat2?

$\endgroup$
  • $\begingroup$ So when n is larger, say when n=7, what will the extra rows and columns of the output be? Will they just be copies of the final rows and columns again? $\endgroup$ – Jason B. Apr 19 '16 at 9:06
  • $\begingroup$ Yes,they just be copies of the final rows and columns again $\endgroup$ – partida Apr 19 '16 at 9:12
1
$\begingroup$

So you can't ask for more elements of the list than it has, so you can't have the iterators x and y go higher than 5 in your code. Then you can just use ArrayPad to do the padding:

lis = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}};

n = 6;
sum = ConstantArray[0, {5, 5}];

Do[sum[[x, y]] = 
  lis[[Floor[x/2] + 1, Floor[y/2] + 1]] + 
   lis[[Floor[x/2] + 2, Floor[y/2] + 1]] + 
   lis[[Floor[x/2] + 1, Floor[y/2] + 2]] + 
   lis[[Floor[x/2] + 2, Floor[y/2] + 2]], {x, 5}, {y, 5}]
ArrayPad[sum, {0, n - 5}, "Fixed"] // MatrixForm

enter image description here

But I would rewrite the Do loop as a Table,

n = 12;
mat1 = ArrayPad[
   Table[
    Total[
     lis[[Floor[x/2] + 1 ;; Floor[x/2] + 2,
       Floor[y/2] + 1 ;; Floor[y/2] + 2]],
     2],
    {x, 5}, {y, 5}],
   {0, n - 5}, "Fixed"];
mat1 // MatrixForm

enter image description here

$\endgroup$
  • $\begingroup$ Thank you,I know how to handle this problem now:) $\endgroup$ – partida Apr 19 '16 at 9:36
  • $\begingroup$ @partida, glad to help. I was generally confused by the particular matrix you are using here, but I think the general answer to the question of how to pad a matrix on the right and bottom with extra copies of the final row and column is ArrayPad[ matrix, {0, X}, "Fixed"] where X is the number of extra rows to pad $\endgroup$ – Jason B. Apr 19 '16 at 9:41
  • $\begingroup$ yeah,ArrayPad is the key to my problem,and I hasn't noticed at the beginning $\endgroup$ – partida Apr 19 '16 at 9:43
  • $\begingroup$ If not for the repeated elements, Partition[] would have done nicely: Map[Total[#, 2] &, Partition[lis, {2, 2}, {1, 1}], {2}]. Take[] works fine, tho: Table[Total[Take[lis, Quotient[j, 2] + {1, 2}, Quotient[k, 2] + {1, 2}], 2], {j, 5}, {k, 5}] $\endgroup$ – J. M. will be back soon Apr 21 '16 at 5:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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