I have a matrix (vector of vector), in other words, 2D vector (6 X 6) elements <double>
, and after I have a vector with 6 elements <int>
. the vector with ints has only "0" and "1". Then, I am looking for a way to remove a row and column of the 2D vector when a "0" is found in the vector (1D) of ints. This time is only 6 X 6 but later on, will be around 100 X 100.
What I've done is use iterators, and I successfully remove the rows but now I don't know how to tackle the columns.
This is my code.
#include <iostream>
#include <vector>
#include <iomanip>
int main() {
std::vector <int> boundaryConditions = { 0,1,1,1,0,0 };
std::vector <std::vector<double>> matrix = { {1.46371e 07, 1.46371e 07, -1.46371e 07, -1.46371e 07, 0, 0},
{1.46371e 07, 5.60371e 07, -1.46371e 07, -1.46371e 07, 0, -4.14e 07},
{-1.46371e 07, -1.46371e 07, 5.60371e 07, 1.46371e 07, -4.14e 07, 0},
{-1.46371e 07, -1.46371e 07, 1.46371e 07, 1.46371e 07, 0, 0},
{0, 0, -4.14e 07, 0, 4.14e 07, 0},
{0, -4.14e 07, 0, 0, 0, 4.14e 07}};
int i = 0;
std::vector<int>::iterator it = boundaryConditions.begin();
while (it != boundaryConditions.end())
{
if (*it == 0)
{
it = boundaryConditions.erase(it);
matrix.erase(matrix.begin() i);
}
else
{
it ;
i ;
}
}
for (int i = 0; i < matrix.size(); i )
{
for (int j = 0; j < matrix[i].size(); j )
{
std::cout << matrix[i][j] << std::setw(15);
}
std::cout << "\n";
}
system("pause>0");
}
CodePudding user response:
Maybe this could help, not fully tested: Let A be the binaryConditions array,
void reduce(std::vector<int> A, std::vector<int> &target) {
int i = 0, j = 0;
int nOnes = 0;
while (i<A.size() && j < A.size()) {
if (A[i] != 0) {
i;
nOnes ;
}
else {
j = max(i 1, j);
while (j < A.size() && A[j] == 0) j;
if (j >= A.size()) break;
swap(A[i], A[j]);
swap(target[i], target[j]);
}
}
A.resize(nOnes);
target.resize(nOnes);
}
CodePudding user response:
You can create a new matrix after you've removed the rows.
std::vector<std::vector<double>> removeColumns(const std::vector<int>& boundaryConditions,
const std::vector<std::vector<double>>& matrix)
{
std::vector<std::vector<double>> returnValue(matrix.size());
size_t curRow = 0;
size_t curCol = 0;
for (auto& v : returnValue)
{
for (size_t curCol = 0; curCol < matrix[0].size(); curCol)
{
if (boundaryConditions[curCol] == 1)
v.push_back(matrix[curRow][curCol]);
}
curRow;
}
return returnValue;
}
Then you would call it like this, given that you have already removed the rows from matrix
:
matrix = removeColumns({0,1,1,1,0,0}, matrix);
Here is a Live Example.
If you want an in-place solution, here is an example:
void removeColumns(const std::vector<int>& boundaryConditions, std::vector<std::vector<double>>& matrix)
{
size_t curCol = 0;
for (size_t i = 0; i < boundaryConditions.size(); i)
{
if (boundaryConditions[i] == 0)
{
for (auto& v : matrix)
v.erase(v.begin() curCol);
}
else
curCol;
}
}
Then it would be called like this:
removeColumns({0,1,1,1,0,0}, matrix);
Here is a Live Example