Today i met a trouble.I have a special index vector P,and a matrix A.for example:
MatrixXd B = MatrixXd::Ones(10, 10);
std::cout << B;
std::vector<int> P = { 1, 6, 3, 7, 5 };
and I want to change values of rows of B.Which rows' indexs is not in P;In this case ,i want to do some implements to row 0,2,4,5,8,9.
But how to get that efficiently by eigen?
The use of Eigen is rather secondary to the question. The main issue is that you need to find all indices in the range [0, B.rows())
which are not in P
. From the looks of things, P
is not sorted, which is unfortunate. I assume it is at least unique as this saves us some memory.
Here is a version that is optimized to be fast, rather than pretty.
std::vector<int> indices_not_in(const std::vector<int>& P, int end)
{
assert(P.size() <= end);
std::vector<bool> inP(end);
for(int pi: P) {
assert(inP[pi] == false && "Duplicate entry");
inP[pi] = true;
}
std::vector<int> notP(inP.size() - P.size() + 1);
auto cur = notP.begin();
int i = 0;
for(bool inPi: inP) {
*cur = i++;
cur += ! inPi;
}
notP.erase(cur, notP.end());
return notP;
}
int main()
{
Eigen::MatrixXd B = Eigen::MatrixXd::Ones(10, 10);
std::cout << B << "\n\n";
std::vector<int> P = { 1, 6, 3, 7, 5 };
std::vector<int> notP = indices_not_in(P, B.rows());
B(notP, Eigen::all) *= 2.;
std::cout << B << "\n";
}
If you cannot guarantee that the P
vector contains unique entries, then here is a modified version that works with that:
std::vector<int> indices_not_in(const std::vector<int>& P, int end)
{
std::vector<bool> inP(end);
for(int pi: P)
inP[pi] = true;
std::vector<int> notP(end);
auto cur = notP.begin();
int i = 0;
for(bool inPi: inP) {
*cur = i++;
cur += ! inPi;
}
notP.erase(cur, notP.end());
return notP;
}