// ======================================================= // // IMPORTANT NOTE: Do not modify this file // (except to uncomment the provided test cases // and add your test cases where specified) // // ======================================================= #include #include #include #include #include "Matrix.h" #define __EPSILON 0.0000000001 //Need this to compare doubles because representation. void SimpleTest(); //Some basic tests void StudentTest(); //Write your own test cases here //Function to test a ton of matrices at once. void BatchTest(double start, double step, unsigned int rows, unsigned int cols, unsigned int num); //Quick function that returns if two doubles are very similar to each other. bool double_compare(double a, double b); //Uses Gauss-Jordan elimination to create a Reduced Row Echelon Form matrix. Matrix rref(const Matrix& m); int main(){ SimpleTest(); std::cout << "Completed all simple tests." << std::endl; //Uncomment this to allocate a lot of 100x100 matrices so leaks will be bigger. BatchTest(100,0.1,100,100,50); std::cout << "Completed all batch tests." << std::endl; StudentTest(); std::cout << "Completed all student tests." << std::endl; return 0; } ////////////////Test functions////////////////////// //Some basic tests void SimpleTest(){ //well behaved getrow/read after //Default constructor Matrix m1; assert(m1.num_rows() == 0 && m1.num_cols() == 0); //Copy constructor Matrix m2(3,4,0); assert(m2.num_rows() == 3 && m2.num_cols() == 4); Matrix m2_copy(m2); assert(m2_copy.num_rows() == 3 && m2_copy.num_cols() == 4); m2_copy.set(1,1,27); double d0; assert(m2.get(1,1,d0)); assert(double_compare(d0,0.0)); assert(m2_copy.get(1,1,d0)); assert(double_compare(d0,27)); //Equality and Inequality Matrix m3; assert(m1 == m3); assert(m1 != m2); //Printing std::cout << "Empty matrix:"; std::cout << m1 << std::endl; std::cout << "Zeroed 3x4 matrix:"; std::cout << m2 << std::endl; std::cout << "One after the other:"; std::cout << m1 << m2 << std::endl; //Set & get Matrix m5(4,4,2); Matrix m6(4,4,12); assert(m6.set(2,1,7)); assert(m6.set(3,3,11)); double d1; assert(m6.get(2,1,d1)); assert(d1==7); //Addition std::cout << "Adding m5 and m6" << std::endl; std::cout << m5 << m6 << std::endl; Matrix m7; m7 = m5; Matrix m8(m5); assert(m7 == m8); assert(m7.add(m6)); std::cout << "The result" << std::endl; std::cout << m7 << std::endl; double* r1 = NULL; r1 = m7.get_row(2); assert(r1[0] == 14 && r1[1] == 9); delete [] r1; //Remember we need to clean up dynamic allocations. Matrix m9(3,6,0); m9.set(0,0,1); m9.set(0,1,2); m9.set(0,2,1); m9.set(0,3,1); m9.set(1,0,2); m9.set(1,1,3); m9.set(1,2,-1); m9.set(1,4,1); m9.set(2,0,3); m9.set(2,1,-2); m9.set(2,2,-1); m9.set(2,5,1); std::cout << "Attempting Gauss-Jordan reduced row echelon form." << m9 << std::endl; Matrix m12 = rref(m9); std::cout << m12 << std::endl; double comparison_value; assert(m12.get(0,3,comparison_value)); assert(double_compare(comparison_value,0.25)); assert(m12.get(0,1,comparison_value)); assert(double_compare(comparison_value,0.0)); assert(m12.get(1,5,comparison_value)); assert(double_compare(comparison_value,-3.00/20)); assert(m9.get(0,3,comparison_value)); assert(double_compare(comparison_value,1.0)); assert(m9.get(0,1,comparison_value)); assert(double_compare(comparison_value,2.0)); assert(m9.get(1,5,comparison_value)); assert(double_compare(comparison_value,0.0)); Matrix m11(3,4,0); m11.set(0,0,1); m11.set(0,1,2); m11.set(0,2,3); m11.set(0,3,4); m11.set(1,0,5); m11.set(1,1,6); m11.set(1,2,7); m11.set(1,3,8); m11.set(2,0,9); m11.set(2,1,10); m11.set(2,2,11); m11.set(2,3,12); std::cout << "M11 to be quartered: " << std::endl; std::cout << m11 << std::endl; Matrix* ma1 = NULL; ma1 = m11.quarter(); assert(ma1 != NULL); std::cout << "UL: " << std::endl << ma1[0] << std::endl; std::cout << "UR: " << std::endl << ma1[1] << std::endl; std::cout << "LL: " << std::endl << ma1[2] << std::endl; std::cout << "LR: " << std::endl << ma1[3] << std::endl; for(unsigned int i=0; i<4; i++){ assert((ma1[i].num_rows() == 2) && (ma1[i].num_cols() == 2)); } //Upper Left assert(ma1[0].get(0,0,comparison_value)); assert(double_compare(comparison_value,1)); assert(ma1[0].get(1,1,comparison_value)); assert(double_compare(comparison_value,6)); //Upper Right assert(ma1[1].get(0,0,comparison_value)); assert(double_compare(comparison_value,3)); assert(ma1[1].get(1,1,comparison_value)); assert(double_compare(comparison_value,8)); //Lower Left assert(ma1[2].get(0,0,comparison_value)); assert(double_compare(comparison_value,5)); assert(ma1[2].get(1,1,comparison_value)); assert(double_compare(comparison_value,10)); //Lower Right assert(ma1[3].get(0,0,comparison_value)); assert(double_compare(comparison_value,7)); assert(ma1[3].get(1,1,comparison_value)); assert(double_compare(comparison_value,12)); delete [] ma1; } //Write your own test cases here void StudentTest() { double val; // Test 1: Transpose a non-square matrix. Matrix m(2, 3, 1.0); m.set(0, 0, 1.0); m.set(0, 1, 2.0); m.set(0, 2, 3.0); m.set(1, 0, 4.0); m.set(1, 1, 5.0); m.set(1, 2, 6.0); m.transpose(); // Now m should be 3 x 2. assert(m.num_rows() == 3 && m.num_cols() == 2); m.get(0, 0, val); assert(val == 1.0); m.get(0, 1, val); assert(val == 4.0); m.get(1, 0, val); assert(val == 2.0); m.get(1, 1, val); assert(val == 5.0); m.get(2, 0, val); assert(val == 3.0); m.get(2, 1, val); assert(val == 6.0); // Test 2: Multiply matrix by a coefficient. Matrix m2(2, 2, 2.0); m2.multiply_by_coefficient(3.0); m2.get(0, 0, val); assert(val == 6.0); m2.get(1, 1, val); assert(val == 6.0); // Test 3: get_col() functionality. Matrix m3(3, 3, 0.0); int counter = 1; for (unsigned int i = 0; i < 3; i++) { for (unsigned int j = 0; j < 3; j++) { m3.set(i, j, counter++); } } double* col1 = m3.get_col(1); // Expecting column 1 to be: 2, 5, 8. assert(col1[0] == 2); assert(col1[1] == 5); assert(col1[2] == 8); delete [] col1; // Test 4: swap_row(). Matrix m4(2, 3, 0.0); m4.set(0, 0, 1); m4.set(0, 1, 2); m4.set(0, 2, 3); m4.set(1, 0, 4); m4.set(1, 1, 5); m4.set(1, 2, 6); m4.swap_row(0, 1); m4.get(0, 0, val); assert(val == 4); m4.get(1, 0, val); assert(val == 1); // Test 5: subtract(). Matrix m5(2, 2, 10.0); Matrix m6(2, 2, 3.0); bool success = m5.subtract(m6); assert(success); m5.get(0, 0, val); assert(val == 7.0); // Test 6: quarter() on an even-dimensioned matrix. Matrix m7(4, 4, 0.0); counter = 1; for (unsigned int i = 0; i < 4; i++) { for (unsigned int j = 0; j < 4; j++) { m7.set(i, j, counter++); } } Matrix* quads = m7.quarter(); // For a 4 x 4 matrix, quadrant size should be (4+1)/2 = 2 (integer division) assert(quads[0].num_rows() == 2 && quads[0].num_cols() == 2); // Upper Left quadrant should be: // [ 1 2 ] // [ 5 6 ] quads[0].get(0, 0, val); assert(val == 1); quads[0].get(0, 1, val); assert(val == 2); quads[0].get(1, 0, val); assert(val == 5); quads[0].get(1, 1, val); assert(val == 6); delete [] quads; // Test 7: clear() method. Matrix m8(3, 3, 9.0); m8.clear(); assert(m8.num_rows() == 0 && m8.num_cols() == 0); // Test 8: Self-assignment. Matrix m9(2, 2, 7.0); m9 = m9; m9.get(0, 0, val); assert(val == 7.0); // Test 9: Binary add() with mismatched dimensions. Matrix m10(2, 3, 1.0); Matrix m11(3, 2, 1.0); bool res = m10.add(m11); assert(res == false); // Test 10: Binary subtract() with mismatched dimensions. res = m10.subtract(m11); assert(res == false); } ////////////////Utility functions////////////////////// /* Function that quickly populates a rows x cols matrix with values from * start in increments of step. Does this num_times times. */ void BatchTest(double start, double step, unsigned int rows, unsigned int cols, unsigned int num){ Matrix* m_arr = new Matrix[num]; for(unsigned int i=0; i=ret.num_cols()){ return ret; } ret.get(i,curr_col,dummy); if(double_compare(dummy,0.0)){ //Swap with a nonzero row for(unsigned int scan_i = i+1; scan_i < ret.num_rows(); scan_i++){ ret.get(scan_i,curr_col,dummy); if(!double_compare(dummy,0.0)){ ret.swap_row(scan_i,i); break; } } } //Now we know ret i,curr_col is non-zero so we can use it as a pivot. double pivot; ret.get(i,curr_col,pivot); for(unsigned int j=0; j