/* should output: * print_matrix: * 3 1 -1 * 0 -2 0 * 5 0 0 * matrix minor: * 0 0 * 5 0 * ineff_det: -10 * eff_det: 10 * lu decomposition is not unique, output can be checked manually * invert_lower_tri_matrix: * 1.000000 0.000000 0.000000 * 0.000000 1.000000 0.000000 * -1.666667 -0.833333 1.000000 * invert_upper_tri_matrix: * 0.333333 0.166667 0.200000 * 0.000000 -0.500000 0.000000 * 0.000000 -0.000000 0.600000 * invert_matrix: * 0.000000 0.000000 0.200000 * 0.000000 -0.500000 0.000000 * -1.000000 -0.500000 0.600000 */ void test_matrix_functions() { matrix *a = identity_matrix(3); a->entries[0][0] = 3.0; a->entries[0][1] = 1.0; a->entries[0][2] = -1.0; a->entries[1][1] = -2.0; a->entries[2][0] = 5.0; a->entries[2][2] = 0.0; printf("print_matrix: \n"); print_matrix(*a); printf("matrix_minor: \n"); print_matrix(*matrix_minor(*a, 1)); printf("ineff_det: %lf\n", (double) ineff_det(*a)); printf("eff_det: %lf\n", (double) eff_det(*a)); matrix *a_cpy = copy_matrix(*a); printf("lu_decomp: \n"); matrix **pl = lu_decomp(a_cpy, (int*) NULL); print_matrix(*pl[0]); // prints p print_matrix(*pl[1]); // prints l print_matrix(*a_cpy); // prints u printf("invert_lower_tri_matrix: \n"); print_matrix(*invert_lower_tri_matrix(*pl[1])); printf("invert_upper_tri_matrix: \n"); print_matrix(*invert_upper_tri_matrix(*a_cpy)); printf("invert_matrix: \n"); print_matrix(*invert_matrix(*a)); }
/** Computes the determinant of a matrix * * @param m a Matrix pointer * * @return the determinant of m */ scalar_t matrix_det(Matrix *m) { Matrix *minor; unsigned int j; scalar_t rdet, sign; assert(MATRIX_IS_SQUARE(m)); if(m->cols == 2) { return ((matrix_get(m,0,0) * matrix_get(m,1,1)) - (matrix_get(m,0,1) * matrix_get(m,1,0))); } else { rdet = 0; for(j=0; j < m->cols; j++) { minor = matrix_minor(m, 0, j); sign = (j%2) ? S_LITERAL(1.0) : S_LITERAL(-1.0); rdet += sign * matrix_get(m, 0, j) * matrix_det(minor); matrix_free(minor); } return rdet; } return 0; }
// inefficient determinant algorithm // runtime: O(n!) static matrix_entry ineff_det(matrix a) { if (a.n == 1) return a.entries[0][0]; matrix_entry result = 0; for (int i=0; i<a.n; i++) { result += ((matrix_entry) alt(i)) * a.entries[0][i] * ineff_det(*matrix_minor(a, i)); } return result; }
int main() { DoubleMatrix X(3,3); DoubleInterval A(2,5); X = A; DoubleMatrix Y(3,3); DoubleInterval B(5,9); Y = B; std::cout << X << std::endl; std::cout << Y << std::endl; DoubleMatrix Z(3,3); Z = mtl::mat::trans(X); std::cout << Z << std::endl; mtl::mat::swap_row(Z,1,2); std::cout << Z << std::endl; DoubleInterval C; C = boost::numeric::max(A,B); std::cout << C << std::endl; std::cout << "============== Test 1 ==============" << std::endl << std::endl; DoubleInterval A00(2,3); DoubleInterval A01(0,1); DoubleInterval A10(1,2); DoubleInterval A11(2,3); DoubleMatrix *Test = new DoubleMatrix(2,2); (*Test)(0,0) = A00; (*Test)(0,1) = A01; (*Test)(1,0) = A10; (*Test)(1,1) = A11; std::cout << "Test: " << std::endl; std::cout << *Test << std::endl; bool diag = diagonally_dominant(*Test); if(diag == true) std::cout << "Test is diagonally dominant" << std::endl << std::endl; else std::cout << "Test is NOT diagonally dominant" << std::endl << std::endl; std::cout << "Max on row 2 is " << row_max_element(*Test,1,0) << std::endl; std::cout << "The max is located on element " << row_max_term(*Test,1,0) << std::endl; std::cout << std::endl; std::cout << "determinant = " << det(*Test) << std::endl; delete Test; std::cout << "============== Test 2 ==============" << std::endl << std::endl; Test = new DoubleMatrix(3,3); (*Test)(0,0) = 1; (*Test)(0,1) = 2; (*Test)(0,2) = 3; (*Test)(1,0) = 4; (*Test)(1,1) = 5; (*Test)(1,2) = 6; (*Test)(2,0) = 7; (*Test)(2,1) = 8; (*Test)(2,2) = 9; std::cout << "Test: " << std::endl; std::cout << *Test << std::endl; diag = diagonally_dominant(*Test); if(diag == true) std::cout << "Test is diagonally dominant" << std::endl << std::endl; else std::cout << "Test is NOT diagonally dominant" << std::endl << std::endl; for(unsigned int i = 0; i < mtl::mat::num_rows(*Test); i++) { std::cout << "Max on row " << i << " is " << row_max_element(*Test,i,0) << std::endl; std::cout << "The max is located on element " << row_max_term(*Test,i,0) << std::endl; } std::cout << std::endl; std::cout << "determinant = " << det(*Test) << std::endl; delete Test; std::cout << "============== Test 3 ==============" << std::endl << std::endl; Test = new DoubleMatrix(3,3); (*Test)(0,0) = 1; (*Test)(0,1) = 2; (*Test)(0,2) = 3; (*Test)(1,0) = 10; (*Test)(1,1) = 5; (*Test)(1,2) = 6; (*Test)(2,0) = 10; (*Test)(2,1) = 8; (*Test)(2,2) = 9; std::cout << "Test: " << std::endl; std::cout << *Test << std::endl; diag = diagonally_dominant(*Test); if(diag == true) std::cout << "Test is diagonally dominant" << std::endl << std::endl; else std::cout << "Test is NOT diagonally dominant" << std::endl << std::endl; for(unsigned int i = 0; i < mtl::mat::num_cols(*Test); i++) { std::cout << "Max on col " << i << " is " << col_max_element(*Test,i,0) << std::endl; std::cout << "The max is located on element " << col_max_term(*Test,i,0) << std::endl; } std::cout << std::endl; std::cout << "DoubleMatrix minor(1,0) = " << std::endl; std::cout << matrix_minor(*Test,1,0) << std::endl; std::cout << "determinant = " << det(*Test) << std::endl; delete Test; std::cout << "============== Test 4 ==============" << std::endl << std::endl; Test = new DoubleMatrix(2,2); (*Test)(0,0) = A10; (*Test)(0,1) = A11; (*Test)(1,0) = A00; (*Test)(1,1) = A01; std::cout << "Test: " << std::endl; std::cout << *Test << std::endl; diag = diagonally_dominant(*Test); if(diag == true) std::cout << "Test is diagonally dominant" << std::endl << std::endl; else std::cout << "Test is NOT diagonally dominant" << std::endl << std::endl; std::cout << "The midpoint Doublematrix m(Test): " << std::endl; std::cout << m(*Test) << std::endl; std::cout << "determinant = " << det(*Test) << std::endl; delete Test; return 0; }