当前位置: 首页 > 工具软件 > ArrayFire > 使用案例 >

玩转 ArrayFire:07 数组和矩阵操作

公西国发
2023-12-01


前言

在《玩转 ArrayFire:06 矢量化介绍》中,我们已经了解到几种使用 ArrayFire 对代码进行向量化的方法,在这一篇中,我们将继续学习 ArrayFire 的数组和矩阵操作。


一、数组和矩阵操作函数

     ArrayFire 提供了几种不同的操作数组和矩阵的方法。这些方法或函数包括如下几种:

函数名含义
moddims()在不改变数据的情况下改变数组的维数
array()创建不同维度数组的(浅)副本
flat()将数组平展为一维
flip()沿维度翻转数组
join()最多连接4个数组
reorder()更改数组中的维度顺序
shift()沿着维度移动数据
tile()沿维度重复数组
transpose()矩阵转置
T()矩阵或向量的转置(简写)
H()厄米矩阵的转置(共轭转置)

    下面我们将提供这些函数的几个示例及其用法。

1. flat( )

    该函数的作用是将数组简化为一维:

	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

     flat() 函数可以在 C++ 中调用,如下所示:

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

2. flip( )

    该函数的作用是沿着选定的维度翻转数组的内容。在下面的例子中,我们展示了 5x2 数组沿着第 0 和第 1 轴翻转:

	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

     flip() 函数可以在 C++ 中调用,如下所示:

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

3. join( )

    该函数的作用是沿着特定的维度连接数组。C++ 最多可以连接 4 个数组,而 C 最多支持 10 个数组。下面是一个如何将数组连接到自身的例子:

	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

     join() 函数在 C++ 语言中有几个候选函数:

	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( )

    该函数的作用是改变数组的维度,但不改变数组的数据或顺序。注意,这个函数只修改与数组相关联的元数据。它不修改数组的内容。下面是一个将8x1数组转换为2x4,然后再返回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

     moddims() 函数在 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( )

    该函数的作用是根据维度的变化交换数据,从而修改数组中数据的顺序。数组内的数据保持线性顺序。

	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

     reorder() 函数在 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( )

    该函数的作用是沿着选定的维度以循环缓冲区的方式移动数据。考虑以下示例:

	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

     shift() 函数可以在 C++ 中调用,如下所示:

	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( )

    该函数的作用是沿着指定的维度重复一个数组。下面的例子展示了如何重复数组的第 0 维和第 1 维:

	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

     tile() 函数可以在 C++ 中调用,如下所示:

	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( )

    该函数的作用是执行一个标准的矩阵转置。输入数组必须具有 2D 矩阵的维数。

	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

     transpose() 函数可以在 C++ 中调用,如下所示:

	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

     下面是一个如何使用简写版本的例子:

    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( )

    该函数可用于创建不同尺寸矩阵的(浅)副本。元素的总数必须保持不变。这个函数是前面讨论的moddim()函数的包装。

二、组合重新排序函数来枚举网格坐标

    通过使用数组重组函数的组合,可以用几行代码快速编写复杂的操作模式。例如,考虑为网格生成 (x,y) 坐标,其中每个轴从 1 到 n 。我们可以使用上述函数的一个小组合,而不是使用几个循环来填充数组。

	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

 类似资料: