BlockCopy - Maple Help

ArrayTools

 BlockCopy
 copy a block of several segments of elements from one Matrix, Vector, or Array to another

 Calling Sequence BlockCopy(A,offsetA,skipA,segsizeA,numsegsA,B,offsetB,skipB,segsizeB,numsegsB)

Parameters

 A - source; rectangular storage Matrix, Vector, or Array of any data type and ordering offsetA - (optional) offset for source skipA - increment for source; the number of elements between the start of consecutive segments segsizeA - (optional) segment size for source; the number of elements in each segment. Can be specified only if offsetA is specified numsegsA - (optional) number of segments to copy from source. Can only be specified if segsizeA is specified B - target; rectangular storage Matrix, Vector, or Array of matching data type and any ordering offsetB - (optional) offset for target skipB - increment for target; the number of elements between the start of consecutive segments segsizeB - (optional) segment size for target, if different from segsizeA. Can be specified only if offsetB is specified numsegsB - (optional) number of segments to write data to when copying into target. Can only be specified if segsizeB is specified

Description

 • The BlockCopy command copies a block of data from an existing Matrix, Vector, or Array (source) to another Matrix, Vector, or Array (target). The data types of the source and target must match, or an error results. In addition, the source and target must both have rectangular (dense) storage.
 • In contrast to ArrayTools[Copy], which copies a single segment of data from the source to the target, BlockCopy copies multiple equally spaced equal-sized segments of elements from the source to the target.  Such segments must be groups of contiguous elements when the underlying one-dimensional ordering of the source rtable is considered.  The result depends only upon the internal ordering of the elements in the input rtable, and is independent of the shape of the source or target rtables. Consequently, this routine requires knowledge of the storage structure of multidimensional rectangular rtables under different data orderings (C_order and Fortran_order).  For a description of storage under these orderings, see Fortran_order.
 • With the source and target segment sizes set to 1, BlockCopy behaves in the same manner as ArrayTools[Copy].  The command ArrayTools[Copy](num,A,offsetA,skipA,B,offsetB,skipB) performs the same data movements as the command ArrayTools[BlockCopy](A,offsetA,skipA,1,num,B,offsetB,skipB,1,num).
 • The parameters offsetA, skipA, segsizeA, numsegsA, offsetB, skipB, segsizeB, and numsegsB provide a mechanism for specifying the size, shape, and location of the source and destination blocks.  The data copied from the source is a block of numsegsA segments of segsizeA elements.  The first segment starts at position offsetA+1, and each subsequent segment begins skipA elements after the previous one; if skipA is negative, that means -skipA elements before the previous segment, and if skipA is zero, all segments start at the same position.  These segsizeA*numsegsA elements are copied into numsegsB segments of segsizeB elements in the target.  The first target segment starts at position offsetB+1, and each subsequent segment begins skipB elements after the previous one.
 • The default values of the optional parameters are described as follows:
 – offsetA and offsetB are $0$ (start at the very beginning)
 – segsizeA and numsegsA are $1$ (copy one segment of one element)
 – segsizeB is equal to $\mathrm{segsizeA}$ (copy each source segment into a target segment of equal size)
 – numsegsB is equal to $\frac{\mathrm{segsizeA}\mathrm{numsegsA}}{\mathrm{segsizeB}}$ (copy the source block into a target block containing an equal number of elements; numsegsB will be exactly numsegsA if segsizeB is also unspecified.)
 • The skipA and skipB parameters must be specified.  When copying a submatrix of elements from a two-dimensional Array or Matrix, skipA and skipB are usually set to the number of rows (for Fortran order rtables) or the number of columns (for C order rtables) of the source and target rtables, respectively.  Making the source and target increments equal to the number of rows (or number of columns, for C order rtables) tells BlockCopy to copy using the same offset in each column (or row), thereby copying a physical rectangular submatrix of elements.
 • As an example, copying the upper-right $p$ by $q$ block of an $n$ by $m$ C order Matrix A (where $p\le n$ and $q\le m$) corresponds to accessing the elements $m-q+i-1+m\left(j-1\right)$ of the underlying rtable data structure (for $i=1..q$ and $j=1..p$).  The source offset would be $m-q$, since the first $m-q$ elements are skipped.  The source increment would be $m$ (the number of columns in the input rtable), since each segment begins exactly one row, or $m$ elements, after the previous one.  The segment size and number of segments would be $q$ and $p$, respectively.  To copy this into a $p$ by $q$ C order Matrix B, only skipB would need to be computed, since the default values for the other parameters would copy a block of identical size and shape into B.  The command to accomplish this would then be BlockCopy(A,m-q,m,q,p,B,q) (where m, n, p, and q are fixed values corresponding to the problem.)
 • In contrast, the same operation for an $n$ by $m$ Fortran order rtable must be specified differently. The source offset will now be $n\left(m-q\right)$, since all the values in the first m-q columns are skipped. The source increment will be $n$ (the number of rows) and the segment size and number of segments become reversed, giving us $q$ segments of $p$ elements instead of $p$ segments of $q$ elements.  If the destination is a $p$ by $q$ Fortran order Matrix, the command to accomplish this is BlockCopy(A,n*(m-q),n,p,q,B,p).
 • This function is part of the ArrayTools package, so it can be used in the short form BlockCopy(..) only after executing the command with(ArrayTools).  However, it can always be accessed through the long form of the command by using ArrayTools[BlockCopy](..).

 • The BlockCopy command is thread safe as of Maple 2023, provided that the rtables A and B are not shared between threads.

Examples

 > $\mathrm{with}\left(\mathrm{ArrayTools}\right):$

Copy the upper-right 3x2 block of a Fortran order Matrix into another Matrix:

 > $A≔\mathrm{Matrix}\left(\left[\left[11,12,13,14\right],\left[21,22,23,24\right],\left[31,32,33,34\right],\left[41,42,43,44\right]\right]\right)$
 ${A}{≔}\left[\begin{array}{cccc}{11}& {12}& {13}& {14}\\ {21}& {22}& {23}& {24}\\ {31}& {32}& {33}& {34}\\ {41}& {42}& {43}& {44}\end{array}\right]$ (1)
 > $B≔\mathrm{Matrix}\left(3,2\right):$
 > $\mathrm{BlockCopy}\left(A,8,4,3,2,B,3\right)$
 > $B$
 $\left[\begin{array}{cc}{13}& {14}\\ {23}& {24}\\ {33}& {34}\end{array}\right]$ (2)

Use the offset parameter to copy the block into the lower left of another Fortran order Matrix:

 > $C≔\mathrm{Matrix}\left(5,3\right):$
 > $\mathrm{BlockCopy}\left(A,8,4,3,2,C,2,5\right)$
 > $C$
 $\left[\begin{array}{ccc}{0}& {0}& {0}\\ {0}& {0}& {0}\\ {13}& {14}& {0}\\ {23}& {24}& {0}\\ {33}& {34}& {0}\end{array}\right]$ (3)

Copy the same block, but reshape it into a 6x1 column Vector:

 > $V≔\mathrm{Vector}\left(6\right):$
 > $\mathrm{BlockCopy}\left(A,8,4,3,2,V,0,6,6,1\right)$
 > $V$
 $\left[\begin{array}{c}{13}\\ {23}\\ {33}\\ {14}\\ {24}\\ {34}\end{array}\right]$ (4)

The original example, but with a C order Matrix instead.  Note the different parameter values:

 > $A≔\mathrm{Matrix}\left(\left[\left[11,12,13,14\right],\left[21,22,23,24\right],\left[31,32,33,34\right],\left[41,42,43,44\right]\right],\mathrm{order}=\mathrm{C_order}\right)$
 ${A}{≔}\left[\begin{array}{cccc}{11}& {12}& {13}& {14}\\ {21}& {22}& {23}& {24}\\ {31}& {32}& {33}& {34}\\ {41}& {42}& {43}& {44}\end{array}\right]$ (5)
 > $B≔\mathrm{Matrix}\left(3,2,\mathrm{order}=\mathrm{C_order}\right):$
 > $\mathrm{BlockCopy}\left(A,2,4,2,3,B,2\right)$
 > $B$
 $\left[\begin{array}{cc}{13}& {14}\\ {23}& {24}\\ {33}& {34}\end{array}\right]$ (6)

BlockCopy can be used to create a Matrix from several submatrices.

 > $\mathrm{J1}≔\mathrm{Matrix}\left(\left[\left[1,0\right],\left[0,1\right]\right]\right)$
 ${\mathrm{J1}}{≔}\left[\begin{array}{cc}{1}& {0}\\ {0}& {1}\end{array}\right]$ (7)
 > $\mathrm{J2}≔\mathrm{Matrix}\left(\left[\left[0,1\right],\left[1,0\right]\right]\right)$
 ${\mathrm{J2}}{≔}\left[\begin{array}{cc}{0}& {1}\\ {1}& {0}\end{array}\right]$ (8)
 > $J≔\mathrm{Matrix}\left(4,4\right)$
 ${J}{≔}\left[\begin{array}{cccc}{0}& {0}& {0}& {0}\\ {0}& {0}& {0}& {0}\\ {0}& {0}& {0}& {0}\\ {0}& {0}& {0}& {0}\end{array}\right]$ (9)
 > $\mathrm{BlockCopy}\left(\mathrm{J1},0,2,2,2,J,0,4,2,2\right)$
 > $\mathrm{BlockCopy}\left(\mathrm{J2},0,2,2,2,J,2,4,2,2\right)$
 > $\mathrm{BlockCopy}\left(\mathrm{J2},0,2,2,2,J,8,4,2,2\right)$
 > $\mathrm{BlockCopy}\left(\mathrm{J1},0,2,2,2,J,10,4,2,2\right)$
 > $J$
 $\left[\begin{array}{cccc}{1}& {0}& {0}& {1}\\ {0}& {1}& {1}& {0}\\ {0}& {1}& {1}& {0}\\ {1}& {0}& {0}& {1}\end{array}\right]$ (10)

Extract every second row of a C order Matrix, and concatenate them into a row vector.  Here, since you are skipping every second row, the skipA parameter is not equal to the number of columns:

 > $A≔\mathrm{Matrix}\left(5,3,\left(i,j\right)↦10\cdot i+j,\mathrm{order}=\mathrm{C_order}\right)$
 ${A}{≔}\left[\begin{array}{ccc}{11}& {12}& {13}\\ {21}& {22}& {23}\\ {31}& {32}& {33}\\ {41}& {42}& {43}\\ {51}& {52}& {53}\end{array}\right]$ (11)
 > $V≔\mathrm{Vector}\left[\mathrm{row}\right]\left(9\right)$
 ${V}{≔}\left[\begin{array}{ccccccccc}{0}& {0}& {0}& {0}& {0}& {0}& {0}& {0}& {0}\end{array}\right]$ (12)
 > $\mathrm{BlockCopy}\left(A,0,6,3,3,V,0,9,9,1\right)$
 > $V$
 $\left[\begin{array}{ccccccccc}{11}& {12}& {13}& {31}& {32}& {33}& {51}& {52}& {53}\end{array}\right]$ (13)

To copy a row vector into every row of a C order Matrix, you can specify 0 for the skipA parameter.

 > $A≔\mathrm{Vector}\left[\mathrm{row}\right]\left(\left[1,3,3,6,4\right]\right)$
 ${A}{≔}\left[\begin{array}{ccccc}{1}& {3}& {3}& {6}& {4}\end{array}\right]$ (14)
 > $B≔\mathrm{Matrix}\left(6,5,\mathrm{order}=\mathrm{C_order}\right)$
 ${B}{≔}\left[\begin{array}{ccccc}{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}\\ {0}& {0}& {0}& {0}& {0}\end{array}\right]$ (15)
 > $\mathrm{BlockCopy}\left(A,0,0,5,6,B,5\right)$
 > $B$
 $\left[\begin{array}{ccccc}{1}& {3}& {3}& {6}& {4}\\ {1}& {3}& {3}& {6}& {4}\\ {1}& {3}& {3}& {6}& {4}\\ {1}& {3}& {3}& {6}& {4}\\ {1}& {3}& {3}& {6}& {4}\\ {1}& {3}& {3}& {6}& {4}\end{array}\right]$ (16)

To copy the columns of a Fortran order Matrix into a different Matrix in reverse order, you can specify a negative value for either the skipA or skipB parameter (but not both: that would cancel the reversion). Here, we copy the middle three columns of A into the center of B. The first column to copy is the fourth column from the left, at offset $3*6=18$. To get to the next column, we skip 6 elements backward. We copy 3 segments of length 4. The first column is copied into the third column from the left of B, at offset $2*4=8$. To get to the next column, we skip 4 elements forward.

 > $A≔\mathrm{Matrix}\left(6,5,'\mathrm{symbol}'='a'\right)$
 ${A}{≔}\left[\begin{array}{ccccc}{{a}}_{{1}{,}{1}}& {{a}}_{{1}{,}{2}}& {{a}}_{{1}{,}{3}}& {{a}}_{{1}{,}{4}}& {{a}}_{{1}{,}{5}}\\ {{a}}_{{2}{,}{1}}& {{a}}_{{2}{,}{2}}& {{a}}_{{2}{,}{3}}& {{a}}_{{2}{,}{4}}& {{a}}_{{2}{,}{5}}\\ {{a}}_{{3}{,}{1}}& {{a}}_{{3}{,}{2}}& {{a}}_{{3}{,}{3}}& {{a}}_{{3}{,}{4}}& {{a}}_{{3}{,}{5}}\\ {{a}}_{{4}{,}{1}}& {{a}}_{{4}{,}{2}}& {{a}}_{{4}{,}{3}}& {{a}}_{{4}{,}{4}}& {{a}}_{{4}{,}{5}}\\ {{a}}_{{5}{,}{1}}& {{a}}_{{5}{,}{2}}& {{a}}_{{5}{,}{3}}& {{a}}_{{5}{,}{4}}& {{a}}_{{5}{,}{5}}\\ {{a}}_{{6}{,}{1}}& {{a}}_{{6}{,}{2}}& {{a}}_{{6}{,}{3}}& {{a}}_{{6}{,}{4}}& {{a}}_{{6}{,}{5}}\end{array}\right]$ (17)
 > $B≔\mathrm{Matrix}\left(4,7\right)$
 ${B}{≔}\left[\begin{array}{ccccccc}{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}& {0}& {0}& {0}\end{array}\right]$ (18)
 > $\mathrm{BlockCopy}\left(A,18,-6,4,3,B,8,4\right)$
 > $B$
 $\left[\begin{array}{ccccccc}{0}& {0}& {{a}}_{{1}{,}{4}}& {{a}}_{{1}{,}{3}}& {{a}}_{{1}{,}{2}}& {0}& {0}\\ {0}& {0}& {{a}}_{{2}{,}{4}}& {{a}}_{{2}{,}{3}}& {{a}}_{{2}{,}{2}}& {0}& {0}\\ {0}& {0}& {{a}}_{{3}{,}{4}}& {{a}}_{{3}{,}{3}}& {{a}}_{{3}{,}{2}}& {0}& {0}\\ {0}& {0}& {{a}}_{{4}{,}{4}}& {{a}}_{{4}{,}{3}}& {{a}}_{{4}{,}{2}}& {0}& {0}\end{array}\right]$ (19)

Compatibility

 • The ArrayTools[BlockCopy] command was updated in Maple 2024.
 • The skipA and skipB parameters were updated in Maple 2024.