Playing with ArrayFire: 07 Array and Matrix Operations


Preface

In "Playing with ArrayFire: 06 Vectorization Introduction", we have learned about several methods of vectorizing code using ArrayFire. In this article, we will continue to learn ArrayFire's array and matrix operations.


1. Array and matrix operation functions

     ArrayFire provides several different ways to manipulate arrays and matrices. These methods or functions include the following:

Function name meaning
moddims () Change the dimension of the array without changing the data
array() Create (shallow) copies of arrays of different dimensions
flat() Flatten the array into one dimension
flip() Flip array along dimension
join() Connect up to 4 arrays
reorder() Change the order of dimensions in the array
shift() Move data along dimensions
tile() Repeat array along dimension
transpose() Matrix transpose
T() Transpose of a matrix or vector (shorthand)
H() Transpose of Hermitian matrix (conjugate transpose)

    Below we will provide several examples of these functions and their usage.

1. flat( )

    The function of this function is to reduce the 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

     The flat() function can be called in C++ as follows:

	array af::flat(const array& in) – C++ interface for flat() function

2. flip( )

    The function of this function is to flip the contents of the array along the selected dimension. In the following example, we show that a 5x2 array is flipped along the 0th and 1st axis:

	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

     The flip() function can be called in C++ as follows:

	array af::flip(const array &in, const unsigned dim) – C++ interface for flip()

3. join( )

    The function of this function is to connect arrays along a specific dimension. C++ can connect up to 4 arrays, while C supports up to 10 arrays. Here is an example of how to connect 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

     The join() function has several candidate functions in C++ language:

	array af::join(const int dim, const array &first, const array &second) – Joins 2 arrays along a dimension
	
	array af::join(const int dim, const array &first, const array &second, const array &third) – Joins 3 arrays along a dimension.
	
	array af::join(const int dim, const array &first, const array &second, const array &third, const array &fourth) – Joins 4 arrays along a dimension

4. moddims ()

    The function of this function is to change the dimension of the array, but does not change the data or order of the array. Note that this function only modifies the metadata associated with the array. It does not modify the contents of the array. Here is an example of converting an 8x1 array to 2x4, and then back to 8x1:

	a [8 1 1 1]
	    1.0000
	    2.0000
	    1.0000
	    2.0000
	    1.0000
	    2.0000
	    1.0000
	    2.0000
	    
	af::dim4 new_dims(2, 4);
	moddims(a, new_dims) [2 4 1 1]
	    1.0000     1.0000     1.0000     1.0000
	    2.0000     2.0000     2.0000     2.0000
	    
	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

     The moddims() function has several candidate functions in the C++ API:

	array af::moddims(const array &in, const unsigned ndims, const dim_t *const dims) – mods number of dimensions to match ndims as specidied in the array dims
	
	array af::moddims(const array &in, const dim4 &dims) – mods dimensions as specified by dims
	
	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) – mods dimensions of an array

5. reorder( )

    The function of this function is to exchange data according to the change of dimensions, thereby modifying the order of data in the array. The data in the array maintains a linear order.

	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

     The reorder() function has several candidate functions in the C++ API:

	array af::reorder(const array &in, const unsigned x, const unsigned y=1, const unsigned z=2, const unsigned w=3) – Reorders dimensions of an array

6. shift( )

    The function of this function is to move the data in a circular buffer along the selected 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

     The shift() function can be called in C++ as follows:

	array af::shift(const array &in, const int x, const int y=0, const int z=0, const int w=0) – Shifts array along specified dimensions

7. tile( )

    The function of this function is to repeat an array along the specified dimension. The following example shows how to repeat the 0th and 1st 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.
	af::dim4 tile_dims(1, 2, 3);
	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

     The tile() function can be called in C++ as follows:

	array af::tile(const array &in, const unsigned x, const unsigned y=1, const unsigned z=1, const unsigned w=1) – Tiles array along specified dimensions

	array af::tile(const array &in, const dim4 &dims) – Tile an array according to a dim4 object

8. transpose( )

    The function of this function is to perform 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) [3 3 1 1]
	    1.0000     2.0000     2.0000
	    3.0000     1.0000     2.0000
	    3.0000     3.0000     1.0000

     The transpose() function can be called in C++ as follows:

	array af::transpose(const array &in, const bool conjugate=false) – Transposes a matrix.
	
	void af::transposeInPlace(array &in, const bool conjugate=false) – Transposes a matrix in-place.
	
	__array af::T() – Transpose a matrix
	
	__array af::H() – Conjugate Transpose (Hermitian transpose) of a matrix

     Here is an example of how to use the shorthand version:

    array x = randu(2, 2, f32);
    af_print(x.T());  // transpose (real)
    array c = randu(2, 2, c32);
    af_print(c.T());  // transpose (complex)
    af_print(c.H());  // Hermitian (conjugate) transpose

9. array( )

    This function can be used to create (shallow) copies of matrices of different sizes. The total number of elements must remain the same. This function is a wrapper for the moddim() function discussed earlier.

2. Combine reordering functions to enumerate grid coordinates

    By using a combination of array reorganization functions, complex operating modes can be quickly written with a few lines of code. For example, consider generating (x,y) coordinates for the grid, where each axis goes from 1 to n. Instead of using several loops to fill the array, we can use a small combination of the above functions.

	unsigned n=3;
	af::array xy = join(1,
	                tile(seq(1, n), n),
	                flat( transpose(tile(seq(1, n), 1, n)) )
	                   );
	xy [9 2 1 1]
	    1.0000     1.0000
	    2.0000     1.0000
	    3.0000     1.0000
	    1.0000     2.0000
	    2.0000     2.0000
	    3.0000     2.0000
	    1.0000     3.0000
	    2.0000     3.0000
	    3.0000     3.0000

Guess you like

Origin blog.csdn.net/weixin_42467801/article/details/113635639