// ======================================================= // // 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() { //Test transpose Matrix m(2, 3, 0); m.set(0, 0, 1); m.set(0, 1, 2); m.set(0, 2, 3); m.set(1, 0, 4); m.set(1, 1, 5); m.set(1, 2, 6); m.transpose(); assert(m.num_rows() == 3); assert(m.num_cols() == 2); double val; m.get(0, 0, val); assert(double_compare(val, 1.0)); m.get(0, 1, val); assert(double_compare(val, 4.0)); m.get(1, 0, val); assert(double_compare(val, 2.0)); m.get(2, 1, val); assert(double_compare(val, 6.0)); //Test quarter with odd dimensions Matrix q(5, 5, 1); Matrix* quarters = q.quarter(); assert(quarters != nullptr); //each quadrant should be 3x3 (ceiling: (5+1)/2 == 3) assert(quarters[0].num_rows() == 3); assert(quarters[0].num_cols() == 3); assert(quarters[1].num_rows() == 3); assert(quarters[1].num_cols() == 3); assert(quarters[2].num_rows() == 3); assert(quarters[2].num_cols() == 3); assert(quarters[3].num_rows() == 3); assert(quarters[3].num_cols() == 3); //verify that the quadrants hold the expected values. for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { quarters[0].get(i, j, val); assert(double_compare(val, 1.0)); quarters[1].get(i, j, val); assert(double_compare(val, 1.0)); quarters[2].get(i, j, val); assert(double_compare(val, 1.0)); quarters[3].get(i, j, val); assert(double_compare(val, 1.0)); } } delete[] quarters; //Test add and subtract Matrix a(2, 2, 2); Matrix b(2, 2, 3); assert(a.add(b)); // Now a is all 5's. double v; a.get(0, 0, v); assert(double_compare(v, 5.0)); assert(a.subtract(b)); // Now a is back to all 2's. a.get(0, 0, v); assert(double_compare(v, 2.0)); //Test multiply by coefficient a.multiply_by_coefficient(2.5); //Now a is all 5's (2*2.5). a.get(0, 0, v); assert(double_compare(v, 5.0)); //Test get_row double* row = a.get_row(0); assert(row != nullptr); assert(double_compare(row[0], 5.0)); assert(double_compare(row[1], 5.0)); delete[] row; // Test get_col double* col = a.get_col(1); assert(col != nullptr); assert(double_compare(col[0], 5.0)); assert(double_compare(col[1], 5.0)); delete[] col; //Test clear a.clear(); assert(a.num_rows() == 0 && a.num_cols() == 0); //Test swap_row Matrix s(3, 2, 0); s.set(0, 0, 1); s.set(0, 1, 2); s.set(1, 0, 3); s.set(1, 1, 4); s.set(2, 0, 5); s.set(2, 1, 6); //swap row 0 and row 2 assert(s.swap_row(0, 2)); s.get(0, 0, val); assert(double_compare(val, 5.0)); s.get(0, 1, val); assert(double_compare(val, 6.0)); s.get(2, 0, val); assert(double_compare(val, 1.0)); s.get(2, 1, val); assert(double_compare(val, 2.0)); //invalid swap should return false. assert(!s.swap_row(0, 3)); //Test copy constructor and assignment operator. Matrix orig(2, 3, 7); Matrix copy(orig); // Using copy constructor. Matrix assign; assign = orig; // Using assignment operator. //change orig to ensure copy and assign remain unchanged. orig.set(0, 0, 10); orig.get(0, 0, val); assert(double_compare(val, 10.0)); copy.get(0, 0, val); assert(double_compare(val, 7.0)); assign.get(0, 0, val); assert(double_compare(val, 7.0)); //Test out-of-bound get and set assert(!orig.get(5, 5, val)); assert(!orig.set(5, 5, 3.0)); } ////////////////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