如何从Eigen中的索引向量中提取子向量(Eigen::Vector)
How to extract a subvector (of an Eigen::Vector) from a vector of indices in Eigen?
假设我有
Eigen::VectorXd x; //{1,2,3,4,5,6,7,8}
和
Eigen::VectorXd ind_vec; //{0,2,4,5}
有没有一种简单的方法可以提取x的ind_vec
元素?
类似于:
x.extract(ind_vec) returning {1, 3, 5, 6}
由于当前的答案对我来说不满意,我在谷歌上搜索了一下,在Eigen文档中找到了本教程。
#include <Eigen/Dense>
#include <iostream>
using namespace std;
int main()
{
Eigen::ArrayXf v(6);
v << 1, 2, 3, 4, 5, 6;
cout << "v.head(3) =" << endl << v.head(3) << endl << endl;
cout << "v.tail<3>() = " << endl << v.tail<3>() << endl << endl;
v.segment(1,4) *= 2;
cout << "after 'v.segment(1,4) *= 2', v =" << endl << v << endl;
}
将输出:
v.head(3) =
1
2
3
v.tail<3>() =
4
5
6
after 'v.segment(1,4) *= 2', v =
1
4
6
8
10
6
我还没有用矢量测试过,但我想这也是可能的。
在C++11中(及以上)执行以下操作:
ind_vec.unaryExpr(x);
您可以使用unaryExpr(Functor)
,因为我们使用一个索引数组,并将一个函子应用于数组的每个元素。结果类型将具有与索引数组相同的维度。对于函子,我们需要一个带有运算符的对象:
Scalar operator() (Index index) const {
return x[index];
}
碰巧,Eigen::Matrix
已经有了这样一个运算符。下面是一个完整的例子:
Eigen::VectorXd x(8); x << 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8;
Eigen::Array4i ind_vec(0,2,4,5);
// result has dimensions as ind_vec matrix/array, and scalar type from x
Eigen::Array4d result = ind_vec.unaryExpr(x);
std::cout << "result^T = " << result.transpose() << std::endl;
// Output:
// result^T = 1.1 3.3 5.5 6.6
唯一需要注意的是,这至少需要C++11才能工作。问题是,本征内部依赖于std::result_of
来获得标量结果类型。如果没有这一点,您可能会出现错误,指出需要强制转换。
如果只为向量编写,那么编写自己的代码似乎很容易:
#include "Eigen/Core"
template <typename T, typename T2>
T extract(const T2& full, const T& ind)
{
int num_indices = ind.innerSize();
T target(num_indices);
for (int i = 0; i < num_indices; i++)
{
target[i] = full[ind[i]];
}
return target;
}
int main()
{
Eigen::VectorXd full(8);
full << 1, 2, 3, 4, 5, 6, 7, 8;
Eigen::Vector4d ind_vec(4);
ind_vec << 0, 2, 4, 5;
std::cout << "full:" << full<< std::endl;
std::cout << "ind_vec:" << ind_vec<< std::endl;
std::cout << "extracted" << extract(full,ind_vec) << std::endl;
}
这应该适用于大多数情况
edit:对于索引标量类型与源标量类型和目标标量类型不同的情况,以下操作将起作用(适用于所有内置的Eigen类型)。
template <typename T, typename T2>
Eigen::Matrix<typename T2::Scalar,T::RowsAtCompileTime,T::ColsAtCompileTime,T::Options>
extract2(const Eigen::DenseBase<T2>& full, const Eigen::DenseBase<T>& ind)
{
using target_t = Eigen::Matrix < T2::Scalar, T::RowsAtCompileTime, T::ColsAtCompileTime, T::Options > ;
int num_indices = ind.innerSize();
target_t target(num_indices);
for (int i = 0; i < num_indices; i++)
{
target[i] = full[ind[i]];
}
return target;
}
(这与另一个不同之处在于,您可以使用int向量作为索引,使用doubles向量作为源,并返回doubles的向量,而不是像上面的extract()
那样使用int向量)
这在Eigen 3.4中通过切片和索引得到了支持:
Eigen::VectorXd x(8); x<<1,2,3,4,5,6,7,8;
Eigen::VectorXi ind_vec(4); ind_vec<<0,2,4,5;
Eigen::VectorXd x_slice = x(ind_vec);
正如文档所指出的,ind_vec
也可以是
行或列索引的任意列表,存储为ArrayXi,一个std::矢量,std::array<int、N>,等
使用libigl的igl::slice
,您可以通过以下方式实现:
Eigen::VectorXd result;
igl::slice(x,ind_vec,result);
由于特征3.4,您可以使用如下索引数组对特征向量和矩阵进行切片:
Eigen::VectorXd x; //{1,2,3,4,5,6,7,8}
Eigen::VectorXd ind_vec; //{0,2,4,5}
x(ind_vec); // indexes the vector using a vector of indices
x(ind_vec, Eigen::all); // also works
取自:https://eigen.tuxfamily.org/dox/group__TutorialSlicingIndexing.html
您可以类似地以这种方式索引矩阵的行和向量
- 写入向量<向量<bool>>
- 函数向量_指针有不同的原型,我可以构建一个吗
- std::向量与传递值的动态数组
- 将值指定给向量(2D)的向量中的某个位置
- 特征::向量;在函数中使用 Eigen::Matrix3f 的值初始化向量,大于 4 个条目
- 浮点数组作为 Eigen::Vector3f 的向量
- 在标准向量中将元素分配给 Eigen::Vector2d 会引发错误
- 从单个数组的不同段中初始化eigen ::向量
- 如何使用另一个"Eigen::VectorXd"向量中的值初始化"Eigen::VectorXd",基于索引的"向量<int>"
- C :如何将std ::向量转换为eigen :: matrixxd
- 将memcpy与Eigen类型的向量一起使用安全吗
- 为什么用Eigen和OpenCV计算的SVD左奇异向量具有不同的符号
- 如何从Eigen中的索引向量中提取子向量(Eigen::Vector)
- 如何在Eigen中连接向量
- 2个向量的标量乘Eigen
- 在 EIGEN 中,c++ 不能将向量乘以它的转置
- 对齐数据类型Eigen::矩阵的数组或向量声明
- 如何在Eigen中近似比较向量
- 如何在Eigen中将行向量转换为列向量
- 使用 Boost::odeint 和 Eigen::Matrix 作为状态向量