/build/arrayfire/src/arrayfire-full-3.6.1/docs/pages/matrix_manipulation.md
Go to the documentation of this file.
1 Array and Matrix Manipulation {#matrixmanipulation}
2 ===================
3 
4 ArrayFire provides several different methods for
5 [manipulating arrays and matrices](\ref manip_mat). The functionality includes:
6 
7 * moddims() - change the dimensions of an array without changing the data
8 * array() - create a (shallow) copy of an array with different dimensions.
9 * flat() - flatten an array to one dimension
10 * flip() - flip an array along a dimension
11 * join() - join up to 4 arrays
12 * reorder() - changes the dimension order within the array
13 * shift() - shifts data along a dimension
14 * tile() - repeats an array along a dimension
15 * transpose() - performs a matrix transpose
16 * [T()](\ref af::array::T) - transpose a matrix or vector (shorthand notation)
17 * [H()](\ref af::array::H) - Hermitian Transpose (conjugate-transpose) a matrix
18 
19 Below we provide several examples of these functions and their use.
20 
21 ## flat()
22 
23 The __flat()__ function flattens an array to one dimension:
24 
25 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
26 a [3 3 1 1]
27  1.0000 4.0000 7.0000
28  2.0000 5.0000 8.0000
29  3.0000 6.0000 9.0000
30 
31 flat(a) [9 1 1 1]
32  1.0000
33  2.0000
34  3.0000
35  4.0000
36  5.0000
37  6.0000
38  7.0000
39  8.0000
40  9.0000
41 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42 
43 The flat function can be called from C and C++ as follows:
44 
45 > __af_err af_flat(af_array* out, const af_array in)__
46 > -- C interface for flat() function
47 
48 > __array af::flat(const array& in)__
49 > -- C++ interface for flat() function
50 
51 ## flip()
52 
53 The __flip()__ function flips the contents of an array along a chosen dimension.
54 In the example below, we show the 5x2 array flipped along the zeroth (i.e.
55 within a column) and first (e.g. across rows) axes:
56 
57 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
58 a [5 2 1 1]
59  1.0000 6.0000
60  2.0000 7.0000
61  3.0000 8.0000
62  4.0000 9.0000
63  5.0000 10.0000
64 
65 flip(a, 0) [5 2 1 1]
66  5.0000 10.0000
67  4.0000 9.0000
68  3.0000 8.0000
69  2.0000 7.0000
70  1.0000 6.0000
71 
72 flip(a, 1) [5 2 1 1]
73  6.0000 1.0000
74  7.0000 2.0000
75  8.0000 3.0000
76  9.0000 4.0000
77  10.0000 5.0000
78 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
79 
80 The flip function can be called from C and C++ as follows:
81 
82 > __af_err af_flip(af_array *out, const af_array in, const unsigned dim)__
83 > -- C interface for flip()
84 
85 > __array af::flip(const array &in, const unsigned dim)__
86 > -- C++ interface for flip()
87 
88 ## join()
89 
90 The __join()__ function joins arrays along a specific dimension. The C++
91 interface can join up to four arrays whereas the C interface supports up to 10
92 arrays. Here is an example of how to use join an array to itself:
93 
94 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
95 a [5 1 1 1]
96  1.0000
97  2.0000
98  3.0000
99  4.0000
100  5.0000
101 
102 join(0, a, a) [10 1 1 1]
103  1.0000
104  2.0000
105  3.0000
106  4.0000
107  5.0000
108  1.0000
109  2.0000
110  3.0000
111  4.0000
112  5.0000
113 
114 join(1, a, a) [5 2 1 1]
115  1.0000 1.0000
116  2.0000 2.0000
117  3.0000 3.0000
118  4.0000 4.0000
119  5.0000 5.0000
120 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
121 
122 The join function has several candidate functions in C:
123 
124 > __af_err af_join(af_array *out, const int dim, const af_array first, const af_array second)__
125 > -- C interface function to join 2 arrays along a dimension
126 
127 > __af_err af_join_many(af_array *out, const int dim, const unsigned n_arrays, const af_array *inputs)__
128 > -- C interface function to join up to 10 arrays along a dimension
129 
130 and in C++:
131 
132 > __array af::join(const int dim, const array &first, const array &second)__
133 > -- Joins 2 arrays along a dimension
134 
135 > __array af::join(const int dim, const array &first, const array &second, const array &third)__
136 > -- Joins 3 arrays along a dimension.
137 
138 > __array af::join(const int dim, const array &first, const array &second, const array &third, const array &fourth)__
139 > -- Joins 4 arrays along a dimension
140 
141 
142 ## moddims()
143 
144 The __moddims()__ function changes the dimensions of an array without changing
145 its data or order. Note that this function modifies only the _metadata_
146 associated with the array. It does not modify the content of the array.
147 Here is an example of moddims() converting an 8x1 array into a 2x4 and then
148 back to a 8x1:
149 
150 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
151 a [8 1 1 1]
152  1.0000
153  2.0000
154  1.0000
155  2.0000
156  1.0000
157  2.0000
158  1.0000
159  2.0000
160 
161 af::dim4 new_dims(2, 4);
162 moddims(a, new_dims) [2 4 1 1]
163  1.0000 1.0000 1.0000 1.0000
164  2.0000 2.0000 2.0000 2.0000
165 
166 moddims(a, a.elements(), 1, 1, 1) [8 1 1 1]
167  1.0000
168  2.0000
169  1.0000
170  2.0000
171  1.0000
172  2.0000
173  1.0000
174  2.0000
175 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
176 
177 The moddims function has a single form in the C API:
178 
179 > __af_err af_moddims(af_array *out, const af_array in, const unsigned ndims, const dim_t *const dims)__
180 > -- C interface to mod dimensions of an array
181 
182 And several overloaded candidates in the C++ API:
183 
184 > __array af::moddims(const array &in, const unsigned ndims, const dim_t *const dims)__
185 > -- mods number of dimensions to match _ndims_ as specidied in the array _dims_
186 
187 > __array af::moddims(const array &in, const dim4 &dims)__
188 > -- mods dimensions as specified by _dims_
189 
190 > __array af::moddims(const array &in, const dim_t d0, const dim_t d1=1, const dim_t d2=1, const dim_t d3=1)__
191 > -- mods dimensions of an array
192 
193 ## reorder()
194 
195 The __reorder()__ function modifies the order of data within an array by
196 exchanging data according to the change in dimensionality. The linear ordering
197 of data within the array is preserved.
198 
199 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
200 a [2 2 3 1]
201  1.0000 3.0000
202  2.0000 4.0000
203 
204  1.0000 3.0000
205  2.0000 4.0000
206 
207  1.0000 3.0000
208  2.0000 4.0000
209 
210 
211 reorder(a, 1, 0, 2) [2 2 3 1] //equivalent to a transpose
212  1.0000 2.0000
213  3.0000 4.0000
214 
215  1.0000 2.0000
216  3.0000 4.0000
217 
218  1.0000 2.0000
219  3.0000 4.0000
220 
221 
222 reorder(a, 2, 0, 1) [3 2 2 1]
223  1.0000 2.0000
224  1.0000 2.0000
225  1.0000 2.0000
226 
227  3.0000 4.0000
228  3.0000 4.0000
229  3.0000 4.0000
230 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231 
232 The reorder function has several candidates functions in the C/C++ APIs:
233 
234 > __af_err af_reorder(af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)__
235 > -- C interface for reordering function
236 
237 > __array af::reorder(const array &in, const unsigned x, const unsigned y=1, const unsigned z=2, const unsigned w=3)__
238 > -- Reorders dimensions of an array
239 
240 ## shift()
241 
242 The __shift()__ function shifts data in a circular buffer fashion along a
243 chosen dimension. Consider the following example:
244 
245 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
246 a [3 5 1 1]
247  0.0000 0.0000 0.0000 0.0000 0.0000
248  3.0000 4.0000 5.0000 1.0000 2.0000
249  3.0000 4.0000 5.0000 1.0000 2.0000
250 
251 shift(a, 0, 2 ) [3 5 1 1]
252  0.0000 0.0000 0.0000 0.0000 0.0000
253  1.0000 2.0000 3.0000 4.0000 5.0000
254  1.0000 2.0000 3.0000 4.0000 5.0000
255 
256 shift(a, -1, 2 ) [3 5 1 1]
257  1.0000 2.0000 3.0000 4.0000 5.0000
258  1.0000 2.0000 3.0000 4.0000 5.0000
259  0.0000 0.0000 0.0000 0.0000 0.0000
260 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
261 
262 The shift function can be called from C and C++ as follows:
263 
264 
265 > __af_err af_shift(af_array *out, const af_array in, const int x, const int y, const int z, const int w)__
266 > -- C interface for shifting an array
267 
268 > __array af::shift(const array &in, const int x, const int y=0, const int z=0, const int w=0)__
269 > -- Shifts array along specified dimensions
270 
271 ## tile()
272 
273 The __tile()__ function repeats an array along the specified dimension.
274 For example below we show how to tile an array along the zeroth and first
275 dimensions of an array:
276 
277 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
278 a [3 1 1 1]
279  1.0000
280  2.0000
281  3.0000
282 
283 // Repeat array a twice in the zeroth dimension
284 tile(a, 2) [6 1 1 1]
285  1.0000
286  2.0000
287  3.0000
288  1.0000
289  2.0000
290  3.0000
291 
292 // Repeat array a twice along both the zeroth and first dimensions
293 tile(a, 2, 2) [6 2 1 1]
294  1.0000 1.0000
295  2.0000 2.0000
296  3.0000 3.0000
297  1.0000 1.0000
298  2.0000 2.0000
299  3.0000 3.0000
300 
301 // Repeat array a twice along the first and three times along the second
302 // dimension.
303 af::dim4 tile_dims(1, 2, 3);
304 tile(a, tile_dims) [3 2 3 1]
305  1.0000 1.0000
306  2.0000 2.0000
307  3.0000 3.0000
308 
309  1.0000 1.0000
310  2.0000 2.0000
311  3.0000 3.0000
312 
313  1.0000 1.0000
314  2.0000 2.0000
315  3.0000 3.0000
316 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
317 
318 The C interface for tile is as follows:
319 
320 > __af_err af_tile(af_array *out, const af_array in, const unsigned x, const unsigned y, const unsigned z, const unsigned w)__
321 > -- C interface for tiling an array
322 
323 The C++ interface has two overloads
324 
325 > __array af::tile(const array &in, const unsigned x, const unsigned y=1, const unsigned z=1, const unsigned w=1)__
326 > -- Tiles array along specified dimensions
327 
328 > __array af::tile(const array &in, const dim4 &dims)__
329 > -- Tile an array according to a dim4 object
330 
331 ## transpose()
332 
333 The __transpose()__ function performs a standard matrix transpose. The input
334 array must have the dimensions of a 2D-matrix.
335 
336 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
337 a [3 3 1 1]
338  1.0000 3.0000 3.0000
339  2.0000 1.0000 3.0000
340  2.0000 2.0000 1.0000
341 
342 transpose(a) [3 3 1 1]
343  1.0000 2.0000 2.0000
344  3.0000 1.0000 2.0000
345  3.0000 3.0000 1.0000
346 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
347 
348 The C interfaces for transpose are as follows:
349 
350 > __af_err af_transpose(af_array *out, af_array in, const bool conjugate)__
351 > -- C interface to transpose a matrix.
352 
353 > __af_err af_transpose_inplace(af_array in, const bool conjugate)__
354 > -- C interface to transpose a matrix in-place.
355 
356 The C++ interface has two primary functions and two shorthand versions:
357 
358 > __array af::transpose(const array &in, const bool conjugate=false)__
359 > -- Transposes a matrix.
360 
361 > __void af::transposeInPlace(array &in, const bool conjugate=false)__
362 > -- Transposes a matrix in-place.
363 
364 > __array af::T()
365 > -- Transpose a matrix
366 
367 > __array af::H()
368 > -- Conjugate Transpose (Hermitian transpose) of a matrix
369 
370 Here is an example of how the shorthand versions might be used:
371 
372 \snippet test/matrix_manipulation.cpp ex_matrix_manipulation_transpose
373 
374 ## array()
375 
376 [array()](\ref af::array) can be used to create a (shallow) copy of a matrix
377 with different dimensions. The total number of elements must remain the same.
378 This function is a wrapper over the moddims() function discussed earlier.
379 
380 # Combining re-ordering functions to enumerate grid coordinates
381 
382 By using a combination of the array restructuring functions, one can quickly code
383 complex manipulation patterns with a few lines of code. For example, consider
384 generating (*x,y*) coordinates for a grid where each axis goes from *1 to n*.
385 Instead of using several loops to populate our arrays we can just use a small
386 combination of the above functions.
387 
388 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
389 unsigned n=3;
390 af::array xy = join(1,
391  tile(seq(1, n), n),
392  flat( transpose(tile(seq(1, n), 1, n)) )
393  );
394 xy [9 2 1 1]
395  1.0000 1.0000
396  2.0000 1.0000
397  3.0000 1.0000
398  1.0000 2.0000
399  2.0000 2.0000
400  3.0000 2.0000
401  1.0000 3.0000
402  2.0000 3.0000
403  3.0000 3.0000
404 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~