Performs the opposite of unwrap(). More...
Functions | |
AFAPI array | wrap (const array &in, const dim_t ox, const dim_t oy, const dim_t wx, const dim_t wy, const dim_t sx, const dim_t sy, const dim_t px=0, const dim_t py=0, const bool is_column=true) |
C++ Interface for performing the opposite of unwrap() More... | |
AFAPI af_err | af_wrap (af_array *out, const af_array in, const dim_t ox, const dim_t oy, const dim_t wx, const dim_t wy, const dim_t sx, const dim_t sy, const dim_t px, const dim_t py, const bool is_column) |
C Interface for performing the opposite of unwrap() More... | |
AFAPI af_err | af_wrap_v2 (af_array *out, const af_array in, const dim_t ox, const dim_t oy, const dim_t wx, const dim_t wy, const dim_t sx, const dim_t sy, const dim_t px, const dim_t py, const bool is_column) |
C Interface for the version of af_wrap that accepts a preallocated output array. More... | |
Performs the opposite of unwrap().
More specifically, wrap takes each column (or row if is_column
is false) of the \(m \times n\) input array and reshapes them into wx
\(\times\) wy
patches (where \(m =\) wx
\(\times\) wy
) of the ox
\(\times\) oy
output array. Wrap is typically used on an array that has been previously unwrapped - for example, in the case of image processing, one can unwrap an image, process the unwrapped array, and then compose it back into an image using wrap.
The figure below illustrates how wrap works. The process can be visualized as a moving window (orange boxes in the figure) taking a column from the input (top-left), reshaping it into a patch (bottom-left), and then placing that patch on its corresponding position in the output array (right; numbers in yellow show correspondence). It starts placing a patch on the output's top-left corner, then moves sx
units along the column, and sy
units along the row whenever it exhausts a column. If padding exists in the input array (gray-filled boxes), which typically happens when padding was applied on the previous unwrap, then px
and py
must be specified in order for the padding to be removed on the output array (in the figure, the output array on the right will actually only contain the inner boxes, size ox
\(\times\) oy
).
There are some things that must be considered when wrapping a previously unwrapped array. First, wrap must use the same parameters that unwrap used, and must use the original array's size (before unwrap) as ox
and oy
. This is necessary to correctly elicit wrap's behavior as the opposite of unwrap. Second, one must consider whether the previous unwrap used a distinct or sliding window configuration, since the element-wise mapping from the input array to the output depends on the configuration. If the distinct window configuration (the stride is at least as large as the window size) was used, then the mapping is straightforward - each column will map to a unique section in the output array, and therefore each element in the input will map to a unique position in the output (shown in the figure above). However, in the case of the sliding window configuration (the stride is smaller than the window size), some of the columns will map to overlapping sections in the output array, and so elements from multiple columns will map to the same position on the output array. Recomposing the array then requires some way to choose between competing elements to place in that position. To address this contention, wrap simply sums all of the competing elements and places the sum in that position. The figure below illustrates this behavior: the fourth element of the first column and the third element of the second column in the input array both map to the same position on the output array, and thus their sum is placed on that position (this happens on the second and third column of the input as well - they both map to the third element of the second column in the output). Given this behavior, it is up to the user to pre-process the input (unwrapped) array (or post-process the output (wrapped) array) in a way that somehow takes all of the competing elements into consideration.
For inputs that have more than two dimensions, the wrap operation will be applied to each 2D slice of the input. This is especially useful for independently processing each channel of an image (or set of images) - each channel (along the third dimension) on the input corresponds to the same channel on the output, and each image (along the fourth dimension) on the input corresponds to the same image on the output.
Here are some code examples that demonstrate wrap's usage. The first one shows wrapping a previously unwrapped array that used a 1x1 padding and a distinct window configuration. Notice how the arguments used in unwrap are the same as those used in wrap:
The next one shows what happens when both unwrap and wrap uses the sliding window configuration. Notice how the original array is not recovered through wrap; instead, overlapping elements are summed, just as described above:
Note that the actual implementation of unwrap may not match the way the operation is visualized above, but the effect should be the same.
AFAPI af_err af_wrap | ( | af_array * | out, |
const af_array | in, | ||
const dim_t | ox, | ||
const dim_t | oy, | ||
const dim_t | wx, | ||
const dim_t | wy, | ||
const dim_t | sx, | ||
const dim_t | sy, | ||
const dim_t | px, | ||
const dim_t | py, | ||
const bool | is_column | ||
) |
C Interface for performing the opposite of unwrap()
[out] | out | is an array with the input's columns (or rows) reshaped as patches |
[in] | in | is the input array |
[in] | ox | is the output's dimension 0 size |
[in] | oy | is the output's dimension 1 size |
[in] | wx | is the window size along dimension 0 |
[in] | wy | is the window size along dimension 1 |
[in] | sx | is the stride along dimension 0 |
[in] | sy | is the stride along dimension 1 |
[in] | px | is the padding along dimension 0 |
[in] | py | is the padding along dimension 1 |
[in] | is_column | determines whether an output patch is formed from a column (if true) or a row (if false) |
ox
and oy
. wx
\(\times\) wy
, must equal input.dims(0)
(or input.dims(1)
if is_column
is false). sx
and sy
must be at least 1 px
and py
must be between [0, wx) and [0, wy), respectively input.dims(1)
(or input.dims(0)
if is_column
is false), must equal \(nx \times\ ny\), where \(\displaystyle nx = \frac{ox + 2px - wx}{sx} + 1\) and \(\displaystyle ny = \frac{oy + 2py - wy}{sy} + 1\) in
is three or four-dimensional AFAPI af_err af_wrap_v2 | ( | af_array * | out, |
const af_array | in, | ||
const dim_t | ox, | ||
const dim_t | oy, | ||
const dim_t | wx, | ||
const dim_t | wy, | ||
const dim_t | sx, | ||
const dim_t | sy, | ||
const dim_t | px, | ||
const dim_t | py, | ||
const bool | is_column | ||
) |
C Interface for the version of af_wrap that accepts a preallocated output array.
[out] | out | is an array with the input's columns (or rows) reshaped as patches |
[in] | in | is the input array |
[in] | ox | is the output's dimension 0 size |
[in] | oy | is the output's dimension 1 size |
[in] | wx | is the window size along dimension 0 |
[in] | wy | is the window size along dimension 1 |
[in] | sx | is the stride along dimension 0 |
[in] | sy | is the stride along dimension 1 |
[in] | px | is the padding along dimension 0 |
[in] | py | is the padding along dimension 1 |
[in] | is_column | determines whether an output patch is formed from a column (if true) or a row (if false) |
ox
and oy
. wx
\(\times\) wy
, must equal input.dims(0)
(or input.dims(1)
if is_column
is false). sx
and sy
must be at least 1 px
and py
must be between [0, wx) and [0, wy), respectively input.dims(1)
(or input.dims(0)
if is_column
is false), must equal \(nx \times\ ny\), where \(\displaystyle nx = \frac{ox + 2px - wx}{sx} + 1\) and \(\displaystyle ny = \frac{oy + 2py - wy}{sy} + 1\) in
is three or four-dimensional AFAPI array af::wrap | ( | const array & | in, |
const dim_t | ox, | ||
const dim_t | oy, | ||
const dim_t | wx, | ||
const dim_t | wy, | ||
const dim_t | sx, | ||
const dim_t | sy, | ||
const dim_t | px = 0 , |
||
const dim_t | py = 0 , |
||
const bool | is_column = true |
||
) |
C++ Interface for performing the opposite of unwrap()
[in] | in | is the input array |
[in] | ox | is the output's dimension 0 size |
[in] | oy | is the output's dimension 1 size |
[in] | wx | is the window size along dimension 0 |
[in] | wy | is the window size along dimension 1 |
[in] | sx | is the stride along dimension 0 |
[in] | sy | is the stride along dimension 1 |
[in] | px | is the padding along dimension 0 |
[in] | py | is the padding along dimension 1 |
[in] | is_column | determines whether an output patch is formed from a column (if true) or a row (if false) |
ox
and oy
. wx
\(\times\) wy
, must equal input.dims(0)
(or input.dims(1)
if is_column
is false). sx
and sy
must be at least 1 px
and py
must be between [0, wx) and [0, wy), respectively input.dims(1)
(or input.dims(0)
if is_column
is false), must equal \(nx \times\ ny\), where \(\displaystyle nx = \frac{ox + 2px - wx}{sx} + 1\) and \(\displaystyle ny = \frac{oy + 2py - wy}{sy} + 1\) in
is three or four-dimensional