C++之 Eigen-3.4.0 全方位教程:Chapter03-数组篇

数组(The Array class

数组是比较通用的类,不像矩阵专注于线性代数。

此外,Array类提供了一种简单的方法来执行系数操作,这可能没有线性代数含义,例如向数组中的每个系数添加一个常数或将两个数组按系数相乘。

数组类型

Array是一个类模板,它采用与Matrix相同的模板参数。与Matrix 一样,前三个模板参数是必需的:

Array<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>

后面三个参数和矩阵类完全相同,详情请参考 矩阵类

Eigen还为一些常见情况提供了 typedef,其方式类似于Matrix typedef,但有一些细微差别,因为“数组”一词用于一维和二维数组。

Eigen采用这样的约定,即 ArrayNt 形式的 typedef 代表一维数组,其中 N 和 t 是大小和标量类型,如本页中解释的矩阵typedef所示。对于二维数组,我们使用 ArrayNNt 形式的 typedef。

示例:

TypeTypedef
Array<float,Dynamic,1>ArrayXf
Array<float,3,1>Array3f
Array<double,Dynamic,Dynamic>ArrayXXd
Array<double,3,3>Array33d

访问数组

Eigen重载了括号运算符访问数组。

同时,左移运算符也被重载用于(逗号)初始化,和打印输出。

void Eigen_Introduction_ArrayClass_001()
{
	ArrayXXf a(2, 2);
	ArrayXXf b(2, 2);
	a(0, 0) = 1; a(0, 1) = 2;
	a(1, 0) = 3; a(1, 1) = 4;
	cout << "a\n" << a << endl;
	b << 4, 3, 2, 1;
	cout << "b\n" << b << endl;
}

输出:

a
1 2
3 4
b
4 3
2 1

四则运算

  • 加减运算

两个数组的加减与矩阵相同。如果两个数组具有相同的大小,并且加法或减法是按系数进行的,则该操作是有效的。

数组还支持 array + scalar 将标量添加到数组中的每个系数的形式的表达式。(这提供了不能直接用于Matrix对象的功能)

  • 乘除运算

首先,array * scalar 数组乘标量的运算当然是可行的,与矩阵完全一致。

但是!!!,array*arraymatrix*matrix是不一样的:

​ 矩阵相乘的结果为矩阵乘积;(m,n)*(n,p)=(m,p)

​ 数组相乘的结果为系数乘积;(m,n)*(m,n)=(m,n)

//Array四则运算
void Eigen_Introduction_ArrayClass_002()
{
	ArrayXXf a(3, 3);
	ArrayXXf b(3, 3);
	a << 1, 2, 3,
		 4, 5, 6,
		 7, 8, 9;
	b << 1, 2, 3,
		 1, 2, 3,
		 1, 2, 3;
	cout << "a + b = " << endl << a + b << endl;
	cout << "a - 2 = " << endl << a - 2 << endl;
	cout << "a * b = " << endl << a * b << endl;
	cout << "a / b = " << endl << a / b << endl;
}

输出:

a + b =
 2  4  6
 5  7  9
 8 10 12
a - 2 =
-1  0  1
 2  3  4
 5  6  7
a * b =
 1  4  9
 4 10 18
 7 16 27
a / b =
  1   1   1
  4 2.5   2
  7   4   3

其他函数操作

.abs().sqrt()等等,

.min(.)返回两个同规模数组对应系数最小值的新数组。

//Array其他函数操作
void Eigen_Introduction_ArrayClass_003()
{
	ArrayXf a = ArrayXf::Random(5);
	ArrayXf b = ArrayXf::Random(5);
	cout << "a = " << endl 
		<< a.transpose() << endl;
	cout << "b = " << endl
		<< b.transpose() << endl;
	cout << "a.abs() = " << endl
		<< a.abs().transpose() << endl;				//绝对值
	cout << "a.sqrt() =" << endl
		<< a.abs().sqrt().transpose() << endl;		//开方	
	cout << "a.minCoeff() = " << endl
		<< a.minCoeff() << endl;		//最小系数
	cout << "a.maxCoeff() = " << endl
		<< a.maxCoeff() << endl;		//最大系数
	cout << "a.min(b)" << endl
		<< a.min(b).transpose() << endl;			//对应最小值
	cout << "a.max(b)" << endl
		<< a.max(b).transpose() << endl;			//对应最大值
}

输出:

a =
 -0.113254  -0.110202   0.632496 -0.0588702  -0.971007
b =
 0.851558  0.741935  0.148534  0.241005 -0.610828
a.abs() =
 0.113254  0.110202  0.632496 0.0588702  0.971007
a.sqrt() =
0.336533 0.331967 0.795296 0.242632 0.985397
a.minCoeff() =
-0.971007
a.maxCoeff() =
0.632496
a.min(b)
 -0.113254  -0.110202   0.148534 -0.0588702  -0.971007
a.max(b)
 0.851558  0.741935  0.632496  0.241005 -0.610828

数组和矩阵相互转换

线性代数运算时需要用矩阵类,系数运算时需要用数组类;但是往往需要两种类型交替使用。

所以数组和矩阵的相互转换就显得尤为重要了,.array().matrix() 就出现了。

Eigen禁止在表达式中混合矩阵和数组。例如,您不能直接添加矩阵和数组;运算+符的操作数要么都是矩阵,要么都是数组。但是,使用.array()和.matrix()很容易从一种转换到另一种。

这条规则的例外是赋值运算符:允许将矩阵表达式赋值给数组变量,或将数组表达式赋值给矩阵变量。

因此两个同尺寸的矩阵转换成数组相乘再分配给矩阵的语法也是合法的:result = m1.array()*m2.array()

事实上,这种用法非常普遍,以至于Eigen为矩阵提供了一个const .cwiseProduct(.)方法来计算系数乘积。

/*	Matrix to Array*/
void Eigen_Introduction_ArrayClass_004()
{
	Matrix2f m1, m2;
	Matrix2f result;
	Array22f a1, a2;
	m1 << 1, 2,
		  3, 4;
	m2 << 2, 2,
		  2, 2;

	result = m1 * m2;
	cout << "-- Matrix m*n: --" << endl << result << endl << endl;
	result = m1.array() * m2.array();
	cout << "-- Array m*n: --" << endl << result << endl << endl;
	result = m1.cwiseProduct(m2);
	cout << "-- With cwiseProduct: --" << endl << result << endl << endl;
	result = m1.array() + 4;
	cout << "-- Array m + 4: --" << endl << result << endl << endl;
}
/*	Array to Matrix*/
void Eigen_Introduction_ArrayClass_005()
{
	//主要测一下矩阵怎么执行数组运算
	Matrix2f m1, m2;
	Matrix2f result;
	m1 << 1, 2,
		  3, 4;
	m2 << 2, 2,
		  2, 2;
	result = (m1.array() + 4).matrix() * m2;
	cout << "-- Combination 1: --" << endl << result << endl << endl;
	result = (m1.array() * m2.array()).matrix() * m2;
	cout << "-- Combination 2: --" << endl << result << endl << endl;
}

输出

/*	Matrix to Array*/
-- Matrix m*n: --
 6  6
14 14

-- Array m*n: --
2 4
6 8

-- With cwiseProduct: --
2 4
6 8

-- Array m + 4: --
5 6
7 8

/*	Array to Matrix*/
-- Combination 1: --
22 22
30 30

-- Combination 2: --
12 12
28 28
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jacob-xyb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值