std::vector<double> SquareMatrix::xVec(std::vector<double> bVec){
SquareMatrix temp = *this;
std::vector<double> xVector(temp.dimension, 0);
//A^-1*b
if (getDeterminant() != 0){
SquareMatrix temp = *this;
return temp.inverse()*bVec;
}
else if (temp.dimension != bVec.size()){
std::cout << "Error: incompatible dimensions" << std::endl;
return xVector;
}
else if (bVec.size() == 1 && bVec[0] == 0){
xVector.resize(1);
if (temp(1, 1) == 0){
std::cout << "Any solution works." << std::endl;
}
xVector[0] = 0;
return xVector;
}
//row reduces the matrix temp.
for (int i = 0; i < temp.dimension - 1; ++i){
std::cout << "First, at i: " << i << std::endl;
temp.show();
//swaps the rows if pivot point is zero
if (temp.matrix[i][i] == 0){
for (int k = i + 1; k < temp.dimension; ++k){
if (temp.matrix[k][i] != 0){
temp.rowSwap(k + 1, i + 1);
std::swap(bVec[k], bVec[i]);
break;
}
}
}
std::cout << "Next: " << std::endl;
temp.show();
//multiplies entire row by reciprocal of pivot.
for (int j = i; j < temp.dimension; ++j){
if (temp.matrix[j][i] != 0){
//bVec[j] reassignment MUST go before
//temp reassignment.
bVec[j] /= temp.matrix[j][i];
temp.rowMul(j + 1, 1 / temp.matrix[j][i]);
}
}
std::cout << "Next: " << std::endl;
temp.show();
//subtracts rows from each other
for (int j = i + 1; j < temp.dimension; ++j){
if (temp.matrix[j][i] != 0){
temp.rowNeg(j + 1, i + 1);
bVec[j] -= bVec[i];
}
}
std::cout << "Next: " << std::endl;
temp.show();
}
if (temp.matrix[dimension - 1][dimension - 1] != 0){
bVec[dimension - 1] /= temp.matrix[dimension - 1][dimension - 1];
temp.matrix[dimension - 1][dimension - 1]
/= temp.matrix[dimension - 1][dimension - 1];
}
//(inefficient) bubble-sort algorithm to
//place the pivots where they belong
for (int i = 0; i < temp.dimension; ++i){
for (int j = 0; j < dimension; j++){
if (temp.matrix[i][j] != 1){
continue;
}
else if (i != j){
temp.rowSwap(i + 1, j + 1);
}
}
}
//matrix A is row-reduced and b is consistent with these operations
//now we are ready for back substitution
//the last index
int start = temp.dimension - 1;
for (int k = 0; k < temp.dimension; ++k){
double restOfRowValue = 0;
int counter = 0;
//detects if equation has a free variable.
if (bVec[start - k] == 0){
for (int i = 0; i < temp.dimension; ++i){
if (temp.matrix[start - k][i] == 0){
++counter;
}
else
break;
}
if (counter == temp.dimension){
std::cout << "x_" << start - k + 1 << " is free;";
std::cout << " setting it equal to one..." << std::endl;
xVector[start - k] = 1;
continue;
}
}
//detects if equation is inconsistent
else if (temp.matrix[start - k][start - k] == 0){
std::cout << "Inconsistent system detected;";
std::cout << " matrix has only trivial solution." << std::endl;
std::vector<double> newVec(temp.dimension, 0);
return newVec;
}
//b - Ax to find the next x-value
for (int j = start; start - k < j; --j){
restOfRowValue += temp.matrix[start - k][j]*xVector[j];
}
xVector[start - k] = bVec[start - k] - restOfRowValue;
}
return xVector;
}