Array and Matrix Manipulation
ArrayFire provides several different methods for manipulating arrays and matrices. The functionality includes:
- moddims() - change the dimensions of an array without changing the data
- flat() - flatten an array to one dimension
- flip() - flip an array along a dimension
- join() - join up to 4 arrays
- reorder() - changes the dimension order within the array
- shift() - shifts data along a dimension
- tile() - repeats an array along a dimension
- transpose() - performs a matrix transpose
Below we provide several examples of these functions and their use.
moddims()
The moddims function changes the dimensions of an array without changing its data or order. Note that this function modifies only the metadata associated with the array. It does not modify the content of the array. Here is an example of moddims() converting an 8x1 array into a 2x4 and then back to a 8x1:
a [8 1 1 1]
1.0000
2.0000
1.0000
2.0000
1.0000
2.0000
1.0000
2.0000
let new_dims = Dim4::new(&[2, 4, 1, 1]);
moddims(&a, new_dims)
[2 4 1 1]
1.0000 1.0000 1.0000 1.0000
2.0000 2.0000 2.0000 2.0000
let out = moddims(&a, a.elements(), 1, 1, 1);
[8 1 1 1]
1.0000
2.0000
1.0000
2.0000
1.0000
2.0000
1.0000
2.0000
flat()
The flat function flattens an array to one dimension:
a [3 3 1 1]
1.0000 4.0000 7.0000
2.0000 5.0000 8.0000
3.0000 6.0000 9.0000
flat(&a)
[9 1 1 1]
1.0000
2.0000
3.0000
4.0000
5.0000
6.0000
7.0000
8.0000
9.0000
flip()
The flip function flips the contents of an array along a chosen dimension. In the example below, we show the 5x2 array flipped along the zeroth (i.e. within a column) and first (e.g. across rows) axes:
a [5 2 1 1]
1.0000 6.0000
2.0000 7.0000
3.0000 8.0000
4.0000 9.0000
5.0000 10.0000
flip(a, 0) [5 2 1 1]
5.0000 10.0000
4.0000 9.0000
3.0000 8.0000
2.0000 7.0000
1.0000 6.0000
flip(a, 1) [5 2 1 1]
6.0000 1.0000
7.0000 2.0000
8.0000 3.0000
9.0000 4.0000
10.0000 5.0000
join()
The join, join_many functions can be used to join arrays along a specific dimension.
Here is an example of how to use join an array to itself:
a [5 1 1 1]
1.0000
2.0000
3.0000
4.0000
5.0000
join(0, a, a) [10 1 1 1]
1.0000
2.0000
3.0000
4.0000
5.0000
1.0000
2.0000
3.0000
4.0000
5.0000
join(1, a, a) [5 2 1 1]
1.0000 1.0000
2.0000 2.0000
3.0000 3.0000
4.0000 4.0000
5.0000 5.0000
reorder()
The reorder function modifies the order of data within an array by exchanging data according to the change in dimensionality. The linear ordering of data within the array is preserved.
a [2 2 3 1]
1.0000 3.0000
2.0000 4.0000
1.0000 3.0000
2.0000 4.0000
1.0000 3.0000
2.0000 4.0000
reorder(&a, 1, 0, 2)
[2 2 3 1] //equivalent to a transpose
1.0000 2.0000
3.0000 4.0000
1.0000 2.0000
3.0000 4.0000
1.0000 2.0000
3.0000 4.0000
reorder(&a, 2, 0, 1)
[3 2 2 1]
1.0000 2.0000
1.0000 2.0000
1.0000 2.0000
3.0000 4.0000
3.0000 4.0000
3.0000 4.0000
shift()
The shift function shifts data in a circular buffer fashion along a chosen dimension. Consider the following example:
a [3 5 1 1]
0.0000 0.0000 0.0000 0.0000 0.0000
3.0000 4.0000 5.0000 1.0000 2.0000
3.0000 4.0000 5.0000 1.0000 2.0000
shift(&a, 0, 2 )
[3 5 1 1]
0.0000 0.0000 0.0000 0.0000 0.0000
1.0000 2.0000 3.0000 4.0000 5.0000
1.0000 2.0000 3.0000 4.0000 5.0000
shift(&a, -1, 2 )
[3 5 1 1]
1.0000 2.0000 3.0000 4.0000 5.0000
1.0000 2.0000 3.0000 4.0000 5.0000
0.0000 0.0000 0.0000 0.0000 0.0000
tile()
The tile function repeats an array along the specified dimension. For example below we show how to tile an array along the zeroth and first dimensions of an array:
a [3 1 1 1]
1.0000
2.0000
3.0000
// Repeat array a twice in the zeroth dimension
tile(&a, 2)
[6 1 1 1]
1.0000
2.0000
3.0000
1.0000
2.0000
3.0000
// Repeat array a twice along both the zeroth and first dimensions
tile(&a, 2, 2)
[6 2 1 1]
1.0000 1.0000
2.0000 2.0000
3.0000 3.0000
1.0000 1.0000
2.0000 2.0000
3.0000 3.0000
// Repeat array a twice along the first and three times along the second
// dimension.
let tile_dims = Dim4::new(&[1, 2, 3, 1]);
tile(a, tile_dims) [3 2 3 1]
1.0000 1.0000
2.0000 2.0000
3.0000 3.0000
1.0000 1.0000
2.0000 2.0000
3.0000 3.0000
1.0000 1.0000
2.0000 2.0000
3.0000 3.0000
transpose()
The transpose function performs a standard matrix transpose. The input array must have the dimensions of a 2D-matrix.
a [3 3 1 1]
1.0000 3.0000 3.0000
2.0000 1.0000 3.0000
2.0000 2.0000 1.0000
transpose(&a, False) //Second parameter to be used for conjugate transpose
[3 3 1 1]
1.0000 2.0000 2.0000
3.0000 1.0000 2.0000
3.0000 3.0000 1.0000
Combining functions to enumerate grid coordinates
By using a combination of the functions, one can quickly code complex manipulation patterns with a few lines of code. For example, consider generating (x,y) coordinates for a grid where each axis goes from 1 to n. Instead of using several loops to populate our arrays we can just use a small combination of the above functions.
let a = iota::<u32>(Dim4::new(&[3, 1, 1, 1]),
Dim4::new(&[1, 3, 1, 1]));
let b = transpose(&a, false);
let coords = join(1, &flat(&a), &flat(&b));
print(&coords);
The output for a [3 3 1 1]
matrix will be the following.
[9 2 1 1]
0 0
1 0
2 0
0 1
1 1
2 1
0 2
1 2
2 2