//------------------------------------------------------------------------------ // Invert //------------------------------------------------------------------------------ bool Matrix::invert() { bool ok = mda != nullptr && rows > 0 && cols > 0 && isSquare(); if (ok) { Matrix m(rows, cols); m.makeIdent(); unsigned int origCols = cols; // 'cols' is changed after augment() augment(m); for (unsigned int k = 0; k < origCols; k++) { pivotRow(k,k); mulRow(k, 1.0/getElem(k,k)); for (unsigned int i=0; i<rows; i++) { if (i != k) { addRow(i, k, -getElem(i,k)); } } } remCols(0, origCols-1); } return ok; }
/* * 行最简式,Error */ Matrix* calc_rref(Matrix* p) { Matrix *oldAns = ans; int i, j, k; int l = 0; if (p == NULL) { //Error return NULL; } ans = NULL; if (!stor_createAns(p->m, p->n)) { //Error return NULL; } if (!stor_assign(ans, p)) { //Error return NULL; } if (!ans) { //Error return NULL; } for (i = 0; i < ans->m; i++) { k = isZeroLine(ans, i); if (k == -1) { continue; } if (util_isZero(*stor_entry(ans, i, k))) { //Error return NULL; } mulRow(ans, i, (double)1.0 / *stor_entry(ans, i, k)); if (!ans) { //Error return NULL; } for (j = 0; j < ans->m; j++) { if (i != j && !util_isZero(*stor_entry(ans, j, k))) { addRow(ans, j, i, -*stor_entry(ans, j, k)); } } } l = 0; for (i = 0; i < p->n; i++) { for (j = i; j < p->m; j++) { if (!util_isZero(*stor_entry(ans, j, i))) break; } if (j < p->m) { if (i != j) swapRow(ans, l, j); l++; } } stor_freeMatrix(oldAns); return ans; }
/* * return value(ans only 1*1) should be treated as int, Error */ Matrix* calc_rank(Matrix *p) { Matrix *oldAns = ans; int i, j, k; int count = 0; if (p == NULL) { //Error return NULL; } ans = NULL; if (p->m > p->n) { if (!calc_trans(p)) { //Error return NULL; } } else { if (!stor_createAns(p->m, p->n)) { //Error return NULL; } if (!stor_assign(ans, p)) { //Error return NULL; } } if (ans == NULL) { //Error return NULL; } for (i = 0; i < ans->m; i++) { k = count; while (k < ans->n && util_isZero(*stor_entry(ans, i, k))) k++; if (k >= ans->n) { continue; } if (k != count) { swapColum(ans, count, k); } if (util_isZero(*stor_entry(ans, i, count))) { //Error return NULL; } mulRow(ans, i, (double)1.0 / *stor_entry(ans, i, count)); if (!ans) { //Error return NULL; } for (j = i + 1; j < ans->m; j++) { addRow(ans, j, i, -*stor_entry(ans, j, count)); } count++; } if (!stor_createAns(1, 1)) { //Error return NULL; } *stor_entry(ans, 0, 0) = count; stor_freeMatrix(oldAns); return ans; }
/* * return value(ans only 1*1) should be treated as double, Error */ Matrix* calc_det(Matrix* p) { Matrix *oldAns = ans; Matrix *temp = NULL; int i, j, k, n; if (p == NULL) { //Error return NULL; } if (p->m != p->n) { //Error return NULL; } n = p->m; if (!stor_createMatrix(&temp, n, n)) { //Error return NULL; } if (!stor_assign(temp, p)) { //Error return NULL; } ans = NULL; if (!stor_createAns(1, 1)) { //Error return NULL; } *stor_entry(ans, 0, 0) = 1; for (i = 0; i < n; i++) { k = i; while (k < n && util_isZero(*stor_entry(temp, i, k))) k++; if (k >= n) { *stor_entry(ans, 0, 0) = 0; return ans; } if (i != k) { swapColum(temp, i, k); } *stor_entry(ans, 0, 0) *= *stor_entry(temp, i, i); if (util_isZero(*stor_entry(temp, i, i))) { //Error return NULL; } mulRow(temp, i, (double)1.0/ *stor_entry(temp, i, i)); for (j = i + 1; j < n; j++) { if (!util_isZero(*stor_entry(temp, j, i))) { addRow(temp, j, i, -*stor_entry(temp, j, i)); } } } stor_freeMatrix(temp); stor_freeMatrix(oldAns); return ans; }
/* *the inverse of matrix, Error */ Matrix* calc_inverse(Matrix* p) { Matrix *oldAns = ans; int i, j, k; int n; double temp, temp2; Matrix *t = NULL; if (p == NULL){ //Error return NULL; } else if (p->m != p->n){ //Error return NULL; } n = p->m; if (!stor_createMatrix(&t, n, n)) { //Error return NULL; } if (!stor_assign(t, p)) { //Error return NULL; } ans = NULL; if (!calc_eye(n)) { //Error return NULL; } for (i = 0; i < n; i++) { k = i; //the first line that the i colum is not zero while (k < n && util_isZero(*stor_entry(t, i, k))) k++;//一定要是列增 if (k >= n) { //Error,非满秩矩阵 return NULL; } if (k != i) { swapColum(t, i, k); swapColum(ans, i, k); } //k is no use since temp = *stor_entry(t, i, i); if (util_isZero(temp)) { //Error return NULL; } mulRow(t, i, (double)1.0 / temp); mulRow(ans, i, (double)1.0 / temp); //the [i][i] is 1 now for (j = i + 1; j < n; j++) { if (!util_isZero(*stor_entry(t, j, i))) { temp2 = *stor_entry(t, j, i); addRow(t, j, i, -temp2); addRow(ans, j, i, -temp2); } } } //现在是阶梯型,阶梯头是1 for (i = n - 1; i >= 0; i--) { for (j = i - 1; j >= 0; j--) { if (!util_isZero(*stor_entry(t, j, i))) { temp2 = *stor_entry(t, j, i); addRow(t, j, i, -temp2); addRow(ans, j, i, -temp2); } } } stor_freeMatrix(t); stor_freeMatrix(oldAns); return ans; }