diff --git a/Final/io.cpp b/Final/io.cpp index ae754b7..186b4a8 100644 --- a/Final/io.cpp +++ b/Final/io.cpp @@ -1,433 +1,523 @@ #include #include #include #include #include "io.hpp" #include "LinSys.hpp" using namespace std; Lin_sys_struct::Lin_sys_struct(int msize) { A.SetSize(msize,msize); b.SetSize(msize); size=msize; } Lin_sys_struct::~Lin_sys_struct() {} void out_2_file(Matrix A,string filename,int n_sig){ ofstream write_output(filename); assert((write_output.is_open())&& "Cant write because file is open. Choose another filename or close file."); write_output.precision(n_sig); write_output<>size; Matrix A(size); for (int i=0;i>A(i+1,j+1); } } cout<<"Successfully read file "<>size; Vector b(size); for (int i=0;i>b(i+1); } cout<<"Successfully read file "<>size; Matrix A=Matrix(size); Vector b=Vector(size); Lin_sys_struct instance(size); // Matrix A cout<<"\nLets fill matrix A."<>A(i+1,j+1); } } TerminalPrint(A,"Matrix A :"); //Vector b cout<<"\nLets fill vector B."<>b(i+1); } TerminalPrint(b,"Vector b :"); instance.A=A; instance.b=b; return instance; } string method(){ // Description of methods available cout<<"Description of available methods:\n----------------------\n------------------------\n"; cout<<"Exact : (suitable for relatively small systems)\n---------------------------------------------\n"; cout<<"Cholesky : Fast but for semipositive definite systems only."<>my_method; return my_method; } +//Evaluate if the Matrix A is diagonally dominant +string diagonallyDominant(Matrix A){ + string m_diagonallyDominant = "True"; + int size = A.NumberOfColumns(); + double sum = 0; + for (int i = 0; i < size; ++i) { + for (int j = 0; j < size; ++j) { + sum += A(j+1, i+1); + } + sum -= A(i+1, i+1); + if (A(i+1, i+1) < sum) { + m_diagonallyDominant = "False"; + } + } + return m_diagonallyDominant; +} + + void run_algo(Matrix A,Vector b,string my_method){ if (my_method=="LU") { LU mySys=LU(A,b); string command; cout<<"\nYou chose the LU method. Type a command from the ones available below:\n"; cout<<"U_matrix: outputs the upper triangular decomposition of A.\n"; cout<<"L_matrix: outputs the lower triangular decomposition of A.\n"; cout<<"P_matrix: outputs the permutation matrix of A.\n"; cout<<"Solve: outputs the solution of the system Ax=b\n\n"; cin >> command; while(command!="Exit") { if (command == "U_Matrix") { TerminalPrint(mySys.get_U(), "U decomposition of A."); } else if (command == "L_Matrix") { TerminalPrint(mySys.get_L(), "L decomposition of A."); } else if (command == "P_Matrix") { TerminalPrint(mySys.get_P(), "Permutation matrix of A."); } else if (command == "Solve" ) { Vector x=mySys.Solve(); int counter=0; for (int i=0;i> command; } } else if (my_method=="Cholesky") { if (A.Check_positive_definite() == false) { cout << "Matrix is not definite semi-positive. Try LU method instead" << endl; } else { Cholesky mySys = Cholesky(A, b); string command; cout << "\nYou chose the Cholesky method. Type a command from the ones available below:\n"; cout << "L_matrix: outputs the lower triangular decomposition of A.\n"; cout << "U_matrix: outputs the upper triangular decomposition of A, which is the transpose of L.\n"; cout << "P_matrix: outputs the permutation matrix of A.\n"; cout << "Solve: outputs the solution of the system Ax=b\n\n"; cin >> command; while (command != "Exit") { if (command == "U_Matrix") { TerminalPrint(mySys.get_U(), "U decomposition of A."); } else if (command == "L_Matrix") { TerminalPrint(mySys.get_L(), "L decomposition of A."); } else if (command == "P_Matrix") { TerminalPrint(mySys.get_P(), "Permutation matrix of A."); } else if (command == "Solve") { TerminalPrint(mySys.Solve(), "Solution of system Ax=b."); } else { cout << "Command not supported."; } cout << "Type Exit to quit the algorithm or type a new command :\n\n"; cin >> command; } } } else if (my_method=="Conjugate_gradient"){ Conjugate_Gradient mySys=Conjugate_Gradient(A,b); string command; cout<<"\nYou chose the Conjugate gradient method. Type a command from the ones available below:\n"; cout<<"Set_tol: Sets the convergence criteria to the value given (1e-12 by default). \n"; cout<<"Set_x0 : Sets the initial solution. \n"; cout<<"Set_max_iter : Sets the max number of iterations possible to the value given (5000 by default). \n"; cout<<"Solve: outputs the solution of the system Ax=b. Run this first to unlock following methods:\n\n"; cout<<"iter: outputs the number of iterations needed for convergence. \n"; cout<<"Convergence: outputs a vector with each index corresponding to the error at the iteration. \n"; cin >> command; while(command!="Exit") { if (command == "Solve") { TerminalPrint(mySys.Solve(), "Solution of system Ax=b."); } else if (command == "iter") { TerminalPrint(mySys.get_n_iter(), "Number of iterations needed for convergence."); } else if (command == "Convergence") { for (int i=0;i> tol; mySys.set_tol(tol); } else if (command == "Set_x0") { Vector x0(b.GetSize()); cout<<"Type x0(1),x0(2),...,x0(n) values you wish to start algorithm with:\n\n"; for (int i=0;i>x0(i+1); } TerminalPrint(x0,"Initial solution x0 :"); } else if (command == "Set_max_iter") { int max_iter; cout<<"Type the maximum number of iterations criteria:\n\n"; cin >> max_iter; mySys.set_iter_max(max_iter); } else {cout<<"Command not supported.";} cout<<"Type Exit to quit the algorithm or type a new command :\n\n"; cin >> command; } } else if (my_method=="Gauss_Seidel"){ Gauss_Seidel mySys=Gauss_Seidel(A,b); string command; - cout<<"\nYou chose the Gauss_Seidel method. Type a command from the ones available below:\n"; - cout<<"Set_tol: Sets the convergence criteria to the value given (1e-12 by default). \n"; - cout<<"Set_x0 : Sets the initial solution. \n"; - cout<<"Set_max_iter : Sets the max number of iterations possible to the value given (5000 by default). \n"; + string isDD; + isDD = diagonallyDominant(A); - cout<<"Solve: outputs the solution of the system Ax=b. Run this first to unlock following methods:\n\n"; - cout<<"iter: outputs the number of iterations needed for convergence. \n"; - cout<<"Convergence: outputs a vector with each index corresponding to the error at the iteration. \n"; + cout << "\nYou chose the Jacobi method."; + + string incorrect = "True"; + while (incorrect == "True") { + incorrect = "False"; + if (isDD == "False") { + cout << "The matrix isn't diagonally dominant therefore the algorithm might not converge.\n"; + cout << "You can either continue or change algorithm. Type a command from the ones available below:\n"; + cout << "Continue: if you want to procceed \n"; + cout << "Change: if you want to change method \n"; + + cin >> command; + if (command == "Continue") { + cout << "Type a command from the ones available below:\n"; + cout<<"Set_tol: Sets the convergence criteria to the value given (1e-12 by default). \n"; + cout<<"Set_x0 : Sets the initial solution. \n"; + cout<<"Set_max_iter : Sets the max number of iterations possible to the value given (5000 by default). \n"; + cout<<"Solve: outputs the solution of the system Ax=b. Run this first to unlock following methods:\n\n"; + cout<<"iter: outputs the number of iterations needed for convergence. \n"; + cout<<"Convergence: outputs a vector with each index corresponding to the error at the iteration. \n"; + + cin >> command; + + } else if (command == "Change") { + command = "Exit"; + } else { + cout << "incorrect command\n"; + incorrect = "True"; + + } + }else { + cout << " Type a command from the ones available below:\n"; + cout<<"Set_tol: Sets the convergence criteria to the value given (1e-12 by default). \n"; + cout<<"Set_x0 : Sets the initial solution. \n"; + cout<<"Set_max_iter : Sets the max number of iterations possible to the value given (5000 by default). \n"; + cout<<"Solve: outputs the solution of the system Ax=b. Run this first to unlock following methods:\n\n"; + cout<<"iter: outputs the number of iterations needed for convergence. \n"; + cout<<"Convergence: outputs a vector with each index corresponding to the error at the iteration. \n"; + + cin >> command; + } + } - cin >> command; while(command!="Exit") { if (command == "Solve") { TerminalPrint(mySys.Solve(), "Solution of system Ax=b."); } else if (command == "iter") { TerminalPrint(mySys.get_n_iter(), "Number of iterations needed for convergence."); } else if (command == "Convergence") { for (int i=0;i> tol; mySys.set_tol(tol); } else if (command == "Set_x0") { Vector x0(b.GetSize()); cout<<"Type x0(1),x0(2),...,x0(n) values you wish to start algorithm with:\n\n"; for (int i=0;i>x0(i+1); } TerminalPrint(x0,"Initial solution x0 :"); } else if (command == "Set_max_iter") { int max_iter; cout<<"Type the maximum number of iterations criteria:\n\n"; cin >> max_iter; mySys.set_iter_max(max_iter); } else {cout<<"Command not supported.";} cout<<"Type Exit to quit the algorithm or type a new command :\n\n"; cin >> command; } } else if (my_method=="Jacobi"){ Jacobi mySys=Jacobi(A,b); string command; - cout<<"\nYou chose the Jacobi method. Type a command from the ones available below:\n"; - cout<<"Set_tol: Sets the convergence criteria to the value given (1e-12 by default). \n"; - cout<<"Set_x0 : Sets the initial solution. \n"; - cout<<"Set_max_iter : Sets the max number of iterations possible to the value given (5000 by default). \n"; + string isDD; + isDD = diagonallyDominant(A); - cout<<"Solve: outputs the solution of the system Ax=b. Run this first to unlock following methods:\n\n"; - cout<<"iter: outputs the number of iterations needed for convergence. \n"; - cout<<"Convergence: outputs a vector with each index corresponding to the error at the iteration. \n"; + cout << "\nYou chose the Jacobi method."; + + string incorrect = "True"; + while (incorrect == "True") { + incorrect = "False"; + if (isDD == "False") { + cout << "The matrix isn't diagonally dominant therefore the algorithm might not converge.\n"; + cout << "You can either continue or change algorithm. Type a command from the ones available below:\n"; + cout << "Continue: if you want to procceed \n"; + cout << "Change: if you want to change method \n"; + + cin >> command; + if (command == "Continue") { + cout << "Type a command from the ones available below:\n"; + cout<<"Set_tol: Sets the convergence criteria to the value given (1e-12 by default). \n"; + cout<<"Set_x0 : Sets the initial solution. \n"; + cout<<"Set_max_iter : Sets the max number of iterations possible to the value given (5000 by default). \n"; + cout<<"Solve: outputs the solution of the system Ax=b. Run this first to unlock following methods:\n\n"; + cout<<"iter: outputs the number of iterations needed for convergence. \n"; + cout<<"Convergence: outputs a vector with each index corresponding to the error at the iteration. \n"; + + cin >> command; + + } else if (command == "Change") { + command = "Exit"; + } else { + cout << "incorrect command\n"; + incorrect = "True"; + + } + }else { + cout << " Type a command from the ones available below:\n"; + cout<<"Set_tol: Sets the convergence criteria to the value given (1e-12 by default). \n"; + cout<<"Set_x0 : Sets the initial solution. \n"; + cout<<"Set_max_iter : Sets the max number of iterations possible to the value given (5000 by default). \n"; + cout<<"Solve: outputs the solution of the system Ax=b. Run this first to unlock following methods:\n\n"; + cout<<"iter: outputs the number of iterations needed for convergence. \n"; + cout<<"Convergence: outputs a vector with each index corresponding to the error at the iteration. \n"; + + cin >> command; + } + } - cin >> command; while(command!="Exit") { if (command == "Solve") { TerminalPrint(mySys.Solve(), "Solution of system Ax=b."); } else if (command == "iter") { TerminalPrint(mySys.get_n_iter(), "Number of iterations needed for convergence."); } else if (command == "Convergence") { for (int i=0;i> tol; mySys.set_tol(tol); } else if (command == "Set_x0") { Vector x0(b.GetSize()); cout<<"Type x0(1),x0(2),...,x0(n) values you wish to start algorithm with:\n\n"; for (int i=0;i>x0(i+1); } TerminalPrint(x0,"Initial solution x0 :"); } else if (command == "Set_max_iter") { int max_iter; cout<<"Type the maximum number of iterations criteria:\n\n"; cin >> max_iter; mySys.set_iter_max(max_iter); } else {cout<<"Command not supported.";} cout<<"Type Exit to quit the algorithm or type a new command :\n\n"; cin >> command; } } else if (my_method=="Richardson"){ Richardson mySys=Richardson(A,b); string command; cout<<"\nYou chose the Richardson method. Type a command from the ones available below:\n"; cout<<"Set_tol: Sets the convergence criteria to the value given (1e-12 by default). \n"; cout<<"Set_x0 : Sets the initial solution. \n"; cout<<"Set_max_iter : Sets the max number of iterations possible to the value given (5000 by default). \n"; cout<<"Solve: outputs the solution of the system Ax=b. Run this first to unlock following methods:\n\n"; cout<<"iter: outputs the number of iterations needed for convergence. \n"; cout<<"Convergence: outputs a vector with each index corresponding to the error at the iteration. \n"; cin >> command; while(command!="Exit") { if (command == "Solve" ) { Vector x=mySys.Solve(); int counter=0; for (int i=0;i> tol; mySys.set_tol(tol); } else if (command == "Set_x0") { Vector x0(b.GetSize()); cout<<"Type x0(1),x0(2),...,x0(n) values you wish to start algorithm with:\n\n"; for (int i=0;i>x0(i+1); } TerminalPrint(x0,"Initial solution x0 :"); } else if (command == "Set_max_iter") { int max_iter; cout<<"Type the maximum number of iterations criteria:\n\n"; cin >> max_iter; mySys.set_iter_max(max_iter); } else {cout<<"Command not supported.";} cout<<"Type Exit to quit this method and try a new one or type a new command :\n\n"; cin >> command; } }else if (my_method=="Exit"){ cout<<"Leaving program .. BYYE\n"; } else { cout<<"\nMethod not recognized. Select another one.\n\n"; } } void run_algo_2(Matrix A,Vector b,std::string my_method){ if (my_method=="LU") { LU mySys=LU(A,b); out_2_file(mySys.get_U(),"U.dat",3); out_2_file(mySys.get_L(),"L.dat",3); out_2_file(mySys.get_P(),"P.dat",1); out_2_file(mySys.get_b_star(),"b*.dat",3); out_2_file(mySys.Solve(),"x.dat",3); } else if (my_method=="Cholesky"){ if (A.Check_positive_definite() == false) { cout << "Matrix is not definite semi-positive. Try LU method instead" << endl; } else { Cholesky mySys = Cholesky(A, b); out_2_file(mySys.get_U(),"U.dat",3); out_2_file(mySys.get_L(),"L.dat",3); out_2_file(mySys.get_P(),"P.dat",1); out_2_file(mySys.get_b_star(),"b*.dat",3); out_2_file(mySys.Solve(),"x.dat",3); } } else if (my_method=="Conjugate_Gradient"){ cout<<"System solved with default tol (1e-6), iter_max(5000) and initial solution set to 0."<