5
$\begingroup$

If I pad an array with two columns on the left the order of the columns is reversed depending on the length of the row of the padded array. I don't think this is normal, but if it is, what is the right way to do it without the reversing of the order?

Below is the MWE. The second argument says: no padding on top, none on bottom, none on the right, two on the left. The third specifies what should be padded. Notice how the order of z and y changes in the result.

I am on Mathematica 10.1.0.0

ArrayPad[{{x}}, {{0, 0}, {2, 0}}, {y, z}]
Out={{z, y, x}}

ArrayPad[{{x, x}}, {{0, 0}, {2, 0}}, {y, z}]
Out={{y, z, x, x}}

ArrayPad[{{x, x, x}}, {{0, 0}, {2, 0}}, {y, z}]
Out={{z, y, x, x, x}}
```
$\endgroup$
  • $\begingroup$ I'm not sure why but the padding seems to go rightward and then rolls over onto the left of x. See this: ArrayPad[{{x}}, 3, Range[6]] // MatrixForm . Docs say this: {Subscript[c, 1],Subscript[c, 2],\[Ellipsis]} cyclic repetition of constants Subscript[c, 1],\[Ellipsis] $\endgroup$ – flinty Jun 4 at 17:27
  • 1
    $\begingroup$ Behavior persists in 12.1. This smells like a bug to me: the weirdness is only for left-padding, and it appears to rotate the constant padding list right by the length of the row. I fail to come up with any justification for this. $\endgroup$ – ciao Jun 4 at 23:10
  • 1
    $\begingroup$ Related: (72740), (209608) $\endgroup$ – Mr.Wizard Jun 5 at 9:14
2
$\begingroup$

First a function that gives the desired output:

ClearAll[arrayPad]
arrayPad = ArrayPad[#, {{0, 0}, {#3, 0}}, PadRight[#2, #3 + Length@#[[1]], #2]] &;

Examples:

Row[{Grid[Prepend[{#, {y, z}, 2,
     arrayPad[#, {y, z}, 2]} & /@ ({ ConstantArray[x, #]} & /@ Range[4]), 
    {"a", "padding", "m", "arrayPad[a,padding,m]"}], Dividers -> All],
  Grid[Prepend[{#, {y, z, w}, 3, 
       arrayPad[#, {y, z, w}, 3]} & /@ ({ ConstantArray[x, #]} & /@ Range[4]), 
    {"a", "padding", "m", "arrayPad[a,padding,m]"}], Dividers -> All], 
  Grid[Prepend[{#, Range[4], 5,
       arrayPad[#, Range[4], 5]} & /@ ({ ConstantArray[x, #]} & /@ Range[4]),
    {"a", "padding", "m", "arrayPad[a,padding,m]"}], Dividers -> All]}, Spacer[5]]

enter image description here

How come ArrayPad changes the ordering?

Trace @ ArrayPad[{{x}}, {{0, 0} , {2, 0}}, {y, z}]
{ArrayPad[{{x}}, {{0, 0}, {2, 0}}, {y, z}], 
 PadLeft[{{x}}, {1, 3}, {y, z}, {0, 0}], {{z, y, x}}}

PadLeft >> Details

enter image description here

That is, ArrayPad[{a}, {{0,0}, {m,0}}, padding] behaves as if it takes PadLeft[padding, m + Length[a], padding] and replaces the last Length[a] elements of this list with a. For the example in OP:

PadLeft[{y, z}, 2 + #, {y, z}] & /@ Range[3]
{ {z, y, z}, {y, z, y, z}, {z, y, z, y, z}}

whereas

PadRight[{y, z}, 2 + #, {y, z}] & /@ Range[3]
{{y, z, y}, {y, z, y, z}, {y, z, y, z, y}}

In other words, ArrayPad[a, {{0,0}, {m,0}}, padding] behaves like the version of arrayPad above with PadRight replaced with PadLeft:

padding = Range[5];
pl = RandomInteger[{1, 10}]; 

And @@ (ArrayPad[{ConstantArray[x, #]}, {{0, 0}, {pl, 0}}, padding] === 
  ArrayPad[{ConstantArray[x, #]}, {{0, 0}, {pl, 0}},
    PadLeft[padding, pl + #, padding]] & /@ Range[10])
 True
| improve this answer | |
$\endgroup$
  • $\begingroup$ Please let me know if you disagree with the closure. $\endgroup$ – Mr.Wizard Jun 5 at 8:38
  • 4
    $\begingroup$ @Mr.Wizard, Padding Behavior seems to be a duplicate. But this question also asks " what is the right way to do it without the reversing of the order". $\endgroup$ – kglr Jun 5 at 9:11
2
$\begingroup$

A way without ArrayPad

Join[{y, z}, Map[x &, Range[4]]]
(* Out: {y, z, x, x, x, x} *)

PadRight[{y, z}, 10, x]

| improve this answer | |
$\endgroup$

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.