Eigen使用笔记:如何进行矩阵和标量加减、类似numpy where等方法

1.std::vector转Eigen的数据结构

a.通过Eigen::Map转VectorXf,长度不用编译时期确定
std::vector<float> test_vec1 = {1, 2, 3};
Eigen::Map<Eigen::VectorXf> test_mat1(test_vec1.data(), test_vec1.size());
std::cout << "test_mat1 before:" << test_mat1 << std::endl;
test_vec1[1]=100;
std::cout << "test_mat1 after:" << test_mat1 << std::endl;

output:

test_mat1 before:1
2
3
test_mat1 after:  1
100
  3

可以看到这种方式并不是深拷贝,这点需要特别注意.

b.转Matrix,长度需要编译时期确定
std::vector<float> test_vec2 = {1, 2, 3};
Eigen::Matrix<float, 1, 3> test_mat2(test_vec2.data());
std::cout << "test_mat2 before:" << test_mat2 << std::endl;
test_vec2[1]=100;
std::cout << "test_mat2 after:" << test_mat2 << std::endl;

output:

test_mat2 before:1 2 3
test_mat2 after:1 2 3

多维情况:

std::vector<float> test_vec3 = {1, 2, 3, 4};
Eigen::Map<Eigen::MatrixXf> test_mat3(test_vec3.data(), 2, 2);
std::cout << "test_mat3 before:" << test_mat3 << std::endl;
test_vec3[1]=100;
std::cout << "test_mat3 after:" << test_mat3 << std::endl;

output:

test_mat3 before:1 3
2 4
test_mat3 after:  1   3
100   4

2.数值运算

矩阵和标量的加减运算

Eigen本身是不支持矩阵类和标量的加减的,因此需要转换.同时矩阵类的加减法必须是两个同类型同维度的矩阵类相加减.
a.矩阵减

Eigen::Matrix<float, 2, 3> data3;
data3 << 0., 1., 2., 3., 4., 5.;
std::cout << "data3:" << data3 << std::endl;
float coeff = 0.1;
auto data4 = (data3 - Eigen::MatrixXf::Ones(data3.rows(), data3.cols()) * coeff);
std::cout << "data4:" << data4 << std::endl;

output:

data3:0 1 2
3 4 5
data4:-0.1  0.9  1.9 
 2.9  3.9  4.9

b.向量减

Eigen::VectorXf data5(6);
data5 << 0., 1., 2., 3., 4.,5.;
std::cout << "data5:" << data5 << std::endl;
coeff = 0.5;
auto data6 = (data5 + Eigen::VectorXf::Ones(data5.size()) * coeff);
std::cout << "data6:" << data6 << std::endl;

output:

data5:0
1
2
3
4
5
data6:0.5
1.5
2.5
3.5
4.5
5.5

3.最大值和最小值

maxCoeff不加参数时只获取最大值,加参数可以获取最大值坐标.(minCoeff同理)

auto max = data3.maxCoeff();
std::cout << "max:" << max << std::endl;
int max_row, max_col;
max = data3.maxCoeff(&max_row, &max_col);
std::cout << "max_row:" << max_row << std::endl;
std::cout << "max_col:" << max_col << std::endl;

auto min = data3.minCoeff();
std::cout << "min:" << min << std::endl;
int min_row, min_col;
min = data3.minCoeff(&min_row, &min_col);
std::cout << "min_row:" << min_row << std::endl;
std::cout << "min_col:" << min_col << std::endl;

output

max:5
max_row:1
max_col:2
min:0
min_row:0
min_col:0

4.截取部分块

提取部分数据,类似切片的功能.需要使用block()方法.具体使用有两种方式:
matrix.block(i,j,p,q)和matrix.block<p,q>(i,j),前者用于大小不固定的,可以动态提取大小.后者必须是固定的参数.其中,(i,j)是起始位置,(p,q)是提取的大小.

Eigen::Matrix<float, 2, 4> data7;
data7 << 0., 1., 2., 3., 4., 5., 6., 7.;
std::cout << "data7:" << data7 << std::endl;
// 起始(0, 1), 大小(2, 2)
auto data8 = data7.block(0, 1, 2, 2);
std::cout << "data8:" << data8 << std::endl;

output:

data7:0 1 2 3
4 5 6 7
data8:1 2
5 6

block()也可以用于对矩阵进行部分赋值

5.类似numpy.where的功能,添加条件筛选

判断矩阵中的元素是否都大于某个值,通过.array()来实现.这里返回的ret为和data7同样size的矩阵,每个元素为1或者0,表示对应的data7的元素是否满足条件.
另外,all()返回是否全部元素都满足条件,any()返回是否存在一个满足条件的元素.count()返回满足条件元素的个数.

auto threshold = 1.5;
auto ret = (data7.array() > threshold);
std::cout << "ret:" << ret << std::endl;
std::cout << "ret.all():" << ret.all() << std::endl;
std::cout << "ret.any():" << ret.any() << std::endl;
std::cout << "ret.count():" << ret.count() << std::endl;

output:

ret:0 0 1 1
1 1 1 1
ret.all():0
ret.any():1
ret.count():6

6.按照行或者列,求平均值或者求和

rowwise()表示按照行,而colwise()表示按照列.

// 按行或者列求平均
auto mean1 = data7.rowwise().mean();
auto mean2 = data7.colwise().mean();
std::cout << "mean1:" << mean1 << std::endl;
std::cout << "mean2:" << mean2 << std::endl;
// 按行或者列求和
auto sum1 = data7.rowwise().sum();
auto sum2 = data7.colwise().sum();
std::cout << "sum1:" << sum1 << std::endl;
std::cout << "sum2:" << sum2 << std::endl;

output:

mean1:1.5
5.5
mean2:2 3 4 5
sum1: 6
22
sum2: 4  6  8 10

7.绝对值

cwiseAbs()返回绝对值,cwiseAbs2()返回绝对值的平方

Eigen::Matrix<float, 2, 4> data9;
data9 << -1., -2., -3., 4., -5., -6., -7., 8;
auto data9_abs = data9.cwiseAbs();
auto data9_abs2 = data9.cwiseAbs2();
std::cout << "data9:" << data9 << std::endl;
std::cout << "data9_abs:" << data9_abs << std::endl;
std::cout << "data9_abs2:" << data9_abs2 << std::endl;

output:

data9:-1 -2 -3  4
-5 -6 -7  8
data9_abs:1 2 3 4 5 6 7 8 
data9_abs2: 1  4  9 16
25 36 49 64
  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值