int main(int argc, const char * argv[]) { HuaRongDaoBoard board; Solver solver; Solver::SolutionType solution = solver.Solve(board); std::cout << "Show the solution:" << std::endl; int step = 0; Solver::SolutionType::const_iterator it = solution.begin(); if (it != solution.end()) { Solver::SolutionType::const_iterator nextIt = it; ++nextIt; while(nextIt != solution.end()) { std::cout << "Step " << ++step << "\t"; std::vector<Diff> diff = (*it)->FindDiff(**nextIt); assert(diff.size() == 1); std::cout << diff[0] << std::endl; it = nextIt; ++nextIt; } } return 0; }
// // construct and solve various formulations // static void solve_c_svc( const svm_problem *prob, const svm_parameter* param, double *alpha, Solver::SolutionInfo* si, double Cp, double Cn) { int l = prob->l; double *minus_ones = new double[l]; schar *y = new schar[l]; int i; for(i=0;i<l;i++) { alpha[i] = 0; minus_ones[i] = -1; if(prob->y[i] > 0) y[i] = +1; else y[i]=-1; } Solver s; s.Solve(l, SVC_Q(*prob,*param,y), minus_ones, y, alpha, Cp, Cn, param->eps, si, param->shrinking); double sum_alpha=0; for(i=0;i<l;i++) sum_alpha += alpha[i]; if (Cp==Cn) info("nu = %f\n", sum_alpha/(Cp*prob->l)); for(i=0;i<l;i++) alpha[i] *= y[i]; delete[] minus_ones; delete[] y; }
static void solve_one_class( const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo* si) { int l = prob->l; double *zeros = new double[l]; schar *ones = new schar[l]; int i; int n = (int)(param->nu*prob->l); // # of alpha's at upper bound for(i=0;i<n;i++) alpha[i] = 1; if(n<prob->l) alpha[n] = param->nu * prob->l - n; for(i=n+1;i<l;i++) alpha[i] = 0; for(i=0;i<l;i++) { zeros[i] = 0; ones[i] = 1; } Solver s; s.Solve(l, ONE_CLASS_Q(*prob,*param), zeros, ones, alpha, 1.0, 1.0, param->eps, si, param->shrinking); delete[] zeros; delete[] ones; }
bool simpleNoPrintABbinTest(ofstream& fout, Solver& solver, Iterator a, Iterator b) { fout << "solver.Solve(a,b);" << endl; double res = solver.Solve(a, b); solver.PrintTestData(fout); fout <<fixed<<setprecision(10)<< "result=" << res << endl; return true; }
static void IdleFunc(void) { solver.ClearPrevData(); //Clean last step forces AddInteractionFromUI(); //Add Forces and Densities solver.Solve(); //Calculate the next step glutSetWindow(win_id); glutPostRedisplay(); }
void Workspace::LobattoTwo(double **&vcm,double **&omega,double **&torque, double **&fcm){ int numsys = currentIndex; int numbodies; double time = 0.0; int * mappings; double SysKE =0.0; for (int i = 0; i <= numsys; i++){ mappings = system[i].system->GetMappings(); numbodies = system[i].system->GetNumBodies() - 1; Matrix FF(6,numbodies); for (int j=1; j<=numbodies; j++){ FF(1,j) = torque[mappings[j - 1]-1][0]*ConFac; FF(2,j) = torque[mappings[j - 1]-1][1]*ConFac; FF(3,j) = torque[mappings[j - 1]-1][2]*ConFac; FF(4,j) = fcm[mappings[j - 1]-1][0]*ConFac; FF(5,j) = fcm[mappings[j - 1]-1][1]*ConFac; FF(6,j) = fcm[mappings[j - 1]-1][2]*ConFac; } //------------------------------------// // Get a solver and solve that system. Solver * theSolver = Solver::GetSolver((SolverType)system[i].solver); theSolver->SetSystem(system[i].system); theSolver->Solve(time, FF); ColMatrix tempv = *((*theSolver).GetStateDerivative()); ColMatrix tempa = *((*theSolver).GetStateDerivativeDerivative()); *((*theSolver).GetStateDerivative()) = tempv + Thalf*tempa; int numjoints = system[i].system->joints.GetNumElements(); for(int k = 0; k < numjoints; k++){ system[i].system->joints(k)->ForwardKinematics(); } for(int k = 0; k < numbodies; k++){ Vect3 temp1 =system[i].system->bodies(k+1)->r; Vect3 temp2 =system[i].system->bodies(k+1)->v; Vect3 temp3 =system[i].system->bodies(k+1)->omega; SysKE = SysKE + system[i].system->bodies(k+1)->KE; for(int m = 0; m < 3; m++){ vcm[mappings[k]-1][m] = temp2(m+1); omega[mappings[k]-1][m] = temp3(m+1); } } delete theSolver; } }
static void solve_epsilon_svr( const svm_problem *prob, const svm_parameter *param, double *alpha, Solver::SolutionInfo* si) { int l = prob->l; double *alpha2 = new double[2*l]; double *linear_term = new double[2*l]; schar *y = new schar[2*l]; int i; for(i=0;i<l;i++) { alpha2[i] = 0; linear_term[i] = param->p - prob->y[i]; y[i] = 1; alpha2[i+l] = 0; linear_term[i+l] = param->p + prob->y[i]; y[i+l] = -1; } Solver s; s.Solve(2*l, SVR_Q(*prob,*param), linear_term, y, alpha2, param->C, param->C, param->eps, si, param->shrinking); double sum_alpha = 0; for(i=0;i<l;i++) { alpha[i] = alpha2[i] - alpha2[i+l]; sum_alpha += fabs(alpha[i]); } info("nu = %f\n",sum_alpha/(param->C*l)); delete[] alpha2; delete[] linear_term; delete[] y; }
// Usage: caffe_('solver_solve', hSolver) static void solver_solve(MEX_ARGS) { mxCHECK(nrhs == 1 && mxIsStruct(prhs[0]), "Usage: caffe_('solver_solve', hSolver)"); Solver<float>* solver = handle_to_ptr<Solver<float> >(prhs[0]); solver->Solve(); }
void Solve(const Solver::Options& options, Problem* problem, Solver::Summary* summary) { Solver solver; solver.Solve(options, problem, summary); }
void Workspace::RKStep(double **&xcm, double **&vcm,double **&omega,double **&torque, double **&fcm, double **&ex_space, double **&ey_space, double **&ez_space){ double a[6]; double b[6][6]; double c[6]; //double e[6]; a[1] = 0.2; a[2] = 0.3; a[3] = 0.6; a[4] = 1.0; a[5] = 0.875; b[1][0] = 0.2; b[2][0] = 0.075; b[2][1] = 0.225; b[3][0] = 0.3; b[3][1] = -0.9; b[3][2] = 1.2; b[4][0] = -11.0/54.0; b[4][1] = 2.5; b[4][2] = -70.0/27.0; b[4][3] = 35.0/27.0; b[5][0] = 1631.0/55296.0; b[5][1] = 175.0/512.0; b[5][2] = 575.0/13824.0; b[5][3] = 44275.0/110592.0; b[5][4] = 253.0/4096.0; c[0] = 37.0/378.0; c[1] = 0.0; c[2] = 250.0/621.0; c[3] = 125.0/594.0; c[4] = 0.0; c[5] = 512.0/1771.0; int numsys = currentIndex; int numbodies; double time = 0.0; int * mappings; double SysKE =0.0; for (int i = 0; i <= numsys; i++){ mappings = system[i].system->GetMappings(); numbodies = system[i].system->GetNumBodies() - 1; Matrix FF(6,numbodies); for (int j=1; j<=numbodies; j++){ FF(1,j) = ConFac*torque[mappings[j - 1]-1][0]; FF(2,j) = ConFac*torque[mappings[j - 1]-1][1]; FF(3,j) = ConFac*torque[mappings[j - 1]-1][2]; FF(4,j) = ConFac*fcm[mappings[j - 1]-1][0]; FF(5,j) = ConFac*fcm[mappings[j - 1]-1][1]; FF(6,j) = ConFac*fcm[mappings[j - 1]-1][2]; } //------------------------------------// // Get a solver and solve that system. Solver * theSolver = Solver::GetSolver((SolverType)system[i].solver); theSolver->SetSystem(system[i].system); theSolver->Solve(time, FF); ColMatrix initial_x; ColMatrix initial_xdot; ColMatMap* x; ColMatMap* xdot; ColMatMap* xdotdot; x = theSolver->GetState(); xdot = theSolver->GetStateDerivative(); xdotdot=theSolver->GetStateDerivativeDerivative(); initial_x = *x; initial_xdot = *xdot; ColMatrix f[6]; ColMatrix ff[6]; ff[0] = initial_xdot; f[0] = *xdotdot; for(int ii=1;ii<6;ii++){ time = a[ii] * Tfull; (*x) = initial_x; (*xdot) = initial_xdot; for(int j=0;j<ii;j++){ (*x) = (*x) + (b[ii][j]*Tfull)*ff[j]; (*xdot) = (*xdot) + (b[ii][j]*Tfull)*f[j]; } theSolver->Solve(time,FF); f[ii] = (*xdotdot); ff[ii] = (*xdot); } (*x) = initial_x + (c[0]*Tfull)*ff[0] + (c[2]*Tfull)*ff[2] + (c[3]*Tfull)*ff[3] + (c[5]*Tfull)*ff[5]; (*xdot) = initial_xdot + (c[0]*Tfull)*f[0] + (c[2]*Tfull)*f[2] + (c[3]*Tfull)*f[3] + (c[5]*Tfull)*f[5]; int numjoints = system[i].system->joints.GetNumElements(); for(int k = 0; k < numjoints; k++){ system[i].system->joints(k)->ForwardKinematics(); } for(int k = 0; k < numbodies; k++){ Vect3 temp1 =system[i].system->bodies(k+1)->r; Vect3 temp2 =system[i].system->bodies(k+1)->v; Vect3 temp3 =system[i].system->bodies(k+1)->omega; Mat3x3 temp4 =system[i].system->bodies(k+1)->n_C_k; SysKE = SysKE + system[i].system->bodies(k+1)->KE; for(int m = 0; m < 3; m++){ xcm[mappings[k]-1][m] = temp1(m+1); vcm[mappings[k]-1][m] = temp2(m+1); omega[mappings[k]-1][m] = temp3(m+1); ex_space[mappings[k]-1][m] = temp4(m+1,1); ey_space[mappings[k]-1][m] = temp4(m+1,2); ez_space[mappings[k]-1][m] = temp4(m+1,3); } } delete theSolver; } }
int main(int argc, char* argv[]) { google::InitGoogleLogging(argv[0]); const int kNumberArguments = 6; if (argc < kNumberArguments) { LOG(ERROR) << "Usage: " << argv[0] << " " << "INSTANCE_FILE SOLVER RANDOM_SEED " << "ALGORITHM MAX_TIME [UPPER_BOUND] [SOLVER_LOG_LEVEL]"; return argc; } string instance_file(argv[1]); string formulacao(argv[2]); int random_seed = atoi(argv[3]); string algorithm(argv[4]); int max_time = atoi(argv[5]); int upper_bound = (argc >= 7 ? atoi(argv[6]) : 0); if (argc >= 8) Globals::SetSolverLog(atoi(argv[7])); if (instance_file.find(".mps") != string::npos) { ReadAndSolveMpsFile(instance_file); return 0; } Globals::rg()->RandomInit(random_seed); VLOG(1) << "Loading instance file: " << instance_file; ProblemDataLoader loader(instance_file.c_str(), upper_bound, Globals::instance()); loader.load(); // Solver options SolverOptions options; options.set_max_time(max_time); options.set_relative_time_for_first_solution(Globals::instance()->n() * Globals::instance()->m()); if (upper_bound > 0) options.set_cut_off_value(upper_bound); options.set_use_stabilization(true); // Solver and input options Solver* solver; SolverFactory* solver_factory; if (formulacao == "GeracaoColunas") { solver = new SolverGeracaoColunas(Globals::instance()); solver_factory = new SolverGeracaoColunasFactory(); } else if (formulacao == "FormulacaoPadrao") { solver = new SolverFormulacaoPadrao(Globals::instance()); solver_factory = new SolverFormulacaoPadraoFactory(); } else { LOG(FATAL) << "Inexistent formulation specified: " << formulacao; return 2; } // to keep the time Stopwatch^ sw = gcnew Stopwatch(); // input options and final status SolverStatus status; //PopulateStatus status; if (algorithm == "CPLEX") { sw->Start(); solver->Init(options); //solver->Populate(options, &status); solver->Solve(options, &status); sw->Stop(); } else if (algorithm == "CPLEX-UB") { options.set_cut_off_value(upper_bound); sw->Start(); solver->Init(options); solver->Solve(options, &status); sw->Stop(); } else if (algorithm == "VNSBra") { //options.set_time_for_first_solution(60); sw->Start(); LocalSearch::VNSBra(solver_factory, options.max_time() * 1000, 300 * 1000, 5, &status); sw->Stop(); } else if (algorithm == "Memetic") { sw->Start(); LocalSearch::MIPMemetic(&status); sw->Stop(); } else if (algorithm == "PathRelink") { sw->Start(); LocalSearch::PathRelink(solver_factory, options.max_time() * 1000, 120 * 1000, 1, &status); sw->Stop(); } else if (algorithm == "PostProcessing") { sw->Start(); LocalSearch::PostProcessing(solver_factory, options.max_time() * 1000, 120 * 1000, 1, &status); sw->Stop(); } else { LOG(FATAL) << "Inexistent algorithm specified: " << algorithm; return 3; } status.time = sw->ElapsedMilliseconds / 1000.0; LOG(INFO) << status.ToString(); return 0; }
int main(int argc, char **argv) { int processRank = 0, processorsCount = 1; #if defined(USE_MPI) MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &processRank); // Get the rank of the current process MPI_Comm_size(MPI_COMM_WORLD, &processorsCount); // Get the total number of processors used #endif { std::string matrixFileName = ""; std::string vectorBFileName = ""; std::string vectorXFileName = ""; std::string parametersFileName = ""; std::string solverName = "inner_ilu2"; std::string orderingFileName = ""; bool matrixFound = false; bool vectorBFound = false; bool vectorXFound = false; bool parametersFound = false; bool typeFound = false; bool saveVector = false; bool orderingFound = false; //Parse argv parameters if (argc == 1) goto helpMessage; int i; for (i = 1; i < argc; i++) { //Print help message and exit if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { helpMessage: if (processRank == 0) { std::cout << "Help message: " << std::endl; std::cout << "Command line options: " << std::endl; std::cout << "Required: " << std::endl; std::cout << "-m, --matrix <Matrix file name>" << std::endl; std::cout << "Optional: " << std::endl; std::cout << "-b, --bvector <RHS vector file name>" << std::endl; std::cout << "-x, --xvector <X vector file name>" << std::endl; std::cout << "-d, --database <Solver parameters file name>" << std::endl; std::cout << "-t, --type <Solver type name>" << std::endl; std::cout << "-ord, --ordering <Ordering file name>" << std::endl; std::cout << "-s, --save" << std::endl; std::cout << " Available solvers:" << std::endl; Solver::Initialize(NULL, NULL, NULL); std::vector<std::string> availableSolvers = Solver::getAvailableSolvers(); for (solvers_names_iterator_t it = availableSolvers.begin(); it != availableSolvers.end(); it++) { std::cout << " " << *it << std::endl; } Solver::Finalize(); } return 0; } //Matrix file name found with -m or --matrix options if (strcmp(argv[i], "-m") == 0 || strcmp(argv[i], "--matrix") == 0) { matrixFound = true; matrixFileName = std::string(argv[i + 1]); FILE *matrixFile = fopen(matrixFileName.c_str(), "r"); if (matrixFile == NULL) { if (processRank == 0) { std::cout << "Matrix file not found: " << argv[i + 1] << std::endl; exit(1); } } else { if (processRank == 0) { std::cout << "Matrix file found: " << argv[i + 1] << std::endl; } } fclose(matrixFile); i++; continue; } //B vector file name found with -b or --bvector options if (strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "--bvector") == 0) { if (processRank == 0) { std::cout << "B vector file found: " << argv[i + 1] << std::endl; } vectorBFound = true; vectorBFileName = std::string(argv[i + 1]); i++; continue; } //X vector file name found with -x or --xvector options if (strcmp(argv[i], "-x") == 0 || strcmp(argv[i], "--xvector") == 0) { if (processRank == 0) { std::cout << "X vector file found: " << argv[i + 1] << std::endl; } vectorXFound = true; vectorXFileName = std::string(argv[i + 1]); i++; continue; } //Parameters file name found with -d or --database options if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--database") == 0) { if (processRank == 0) { std::cout << "Solver parameters file found: " << argv[i + 1] << std::endl; } parametersFound = true; parametersFileName = std::string(argv[i + 1]); i++; continue; } //Ordering file name found with -ord or --parameters options if (strcmp(argv[i], "-ord") == 0 || strcmp(argv[i], "--ordering") == 0) { if (processRank == 0) { std::cout << "Ordering file found: " << argv[i + 1] << std::endl; } orderingFound = true; orderingFileName = std::string(argv[i + 1]); i++; continue; } if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--save") == 0) { saveVector = true; continue; } //Solver type found with -t ot --type options if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--type") == 0) { if (processRank == 0) { std::cout << "Solver type index found: " << argv[i + 1] << std::endl; } typeFound = true; solverName = std::string(argv[i + 1]); i++; continue; } } if (!matrixFound) { if (processRank == 0) { std::cout << "Matrix not found, you can specify matrix file name using -m or --matrix options, otherwise specify -h option to see all options, exiting..."; } return -1; } if (!typeFound) { if (processRank == 0) { std::cout << "Solver type not found in command line, you can specify solver type with -t or --type option, using INNER_ILU2 solver by default." << std::endl; } } if (!vectorBFound) { if (processRank == 0) { std::cout << "B vector not found, you can specify b vector file name with -b or --bvector option, using identity vector by default." << std::endl; } } // Initialize the linear solver in accordance with args Solver::Initialize(&argc, &argv, parametersFound ? parametersFileName.c_str() : NULL); if (!Solver::isSolverAvailable(solverName)) { if (processRank == 0) { std::cout << "Solver " << solverName << " is not available" << std::endl; } Solver::Finalize(); exit(1); } Solver solver = Solver(solverName, "test"); if (processRank == 0) { std::cout << "Solving with " << solverName << std::endl; } Sparse::Matrix mat("A"); // Declare the matrix of the linear system to be solved Sparse::Vector b("rhs"); // Declare the right-hand side vector Sparse::Vector x("sol"); // Declare the solution vector double tempTimer = Timer(), solvingTimer; if (orderingFound) { if (processRank == 0) { std::cout << "Using ordering file " << orderingFileName << std::endl; } mat.Load(matrixFileName, ENUMUNDEF, ENUMUNDEF, orderingFileName); } else { mat.Load(matrixFileName); //if interval parameters not set, matrix will be divided automatically } if (processorsCount == 1) { ps_inmost(mat, "a.ps"); //db !IK! } BARRIER if (processRank == 0) { std::cout << "load matrix: " << Timer() - tempTimer << std::endl; } tempTimer = Timer(); if (vectorBFound) { if (orderingFound) { b.Load(vectorBFileName, ENUMUNDEF, ENUMUNDEF, orderingFileName); // Load RHS vector with ordering } else { b.Load(vectorBFileName); //if interval parameters not set, matrix will be divided automatically } //b.Save(vectorBFileName + "_saved_test.rhs"); } else { // Set local RHS to 1 if it was not specified INMOST_DATA_ENUM_TYPE mbeg, mend, k; mat.GetInterval(mbeg, mend); b.SetInterval(mbeg, mend); for (k = mbeg; k < mend; ++k) b[k] = 1.0; } BARRIER if (processRank == 0) { std::cout << "load vector: " << Timer() - tempTimer << std::endl; } solvingTimer = Timer(); int iters; bool success; double resid, realresid = 0; std::string reason; BARRIER tempTimer = Timer(); solver.SetMatrix(mat); //s.SetMatrix(mat); // Compute the preconditioner for the original matrix BARRIER if (processRank == 0) std::cout << "preconditioner time: " << Timer() - tempTimer << std::endl; tempTimer = Timer(); success = solver.Solve(b, x); // Solve the linear system with the previously computted preconditioner BARRIER solvingTimer = Timer() - solvingTimer; if (processRank == 0) std::cout << "iterations time: " << Timer() - tempTimer << std::endl; iters = solver.Iterations(); // Get the number of iterations performed resid = solver.Residual(); // Get the final residual achieved reason = solver.ReturnReason(); // Get the convergence reason if (saveVector) { x.Save("output.sol"); // Save the solution if required } // Compute the true residual double aresid = 0, bresid = 0; Sparse::Vector test; tempTimer = Timer(); Solver::OrderInfo info; info.PrepareMatrix(mat, 0); info.PrepareVector(x); info.Update(x); mat.MatVec(1.0, x, 0.0, test); // Multiply the original matrix by a vector { INMOST_DATA_ENUM_TYPE mbeg, mend, k; info.GetLocalRegion(info.GetRank(), mbeg, mend); for (k = mbeg; k < mend; ++k) { aresid += (test[k] - b[k]) * (test[k] - b[k]); bresid += b[k] * b[k]; } } double temp[2] = {aresid, bresid}, recv[2] = {aresid, bresid}; #if defined(USE_MPI) MPI_Reduce(temp, recv, 2, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); #endif realresid = sqrt(recv[0] / (recv[1] + 1.0e-100)); info.RestoreVector(x); if (processRank == 0) { std::cout << "||Ax-b||=" << sqrt(recv[0]) << " ||b||=" << sqrt(recv[1]) << " ||Ax-b||/||b||=" << sqrt(recv[0] / (recv[1] + 1.0e-100)) << std::endl; std::cout << "norms: " << Timer() - tempTimer << std::endl; std::cout << processorsCount << " processors for Solver " << solverName; if (success) { std::cout << " solved in " << solvingTimer << " secs"; std::cout << " with " << iters << " iterations to " << resid << " norm"; } else std::cout << " failed to solve with " << iters << "iterations"; std::cout << " matrix \"" << matrixFileName << "\""; if (vectorBFound) std::cout << " vector \"" << vectorBFileName << "\""; std::cout << " true residual ||Ax-b||/||b||=" << realresid; std::cout << std::endl; std::cout << "reason: " << reason << std::endl; } if (vectorXFound) { Sparse::Vector ex("exact"); // Declare the exact solution vector Sparse::Vector err("error"); // Declare the solution error vector INMOST_DATA_ENUM_TYPE mbeg, mend, k; mat.GetInterval(mbeg, mend); err.SetInterval(mbeg, mend); ex.Load(vectorXFileName); BARRIER double dif1 = 0, dif2 = 0, dif8 = 0, norm = 0; for (k = mbeg; k < mend; ++k) { double dloc = err[k] = fabs(x[k] - ex[k]); dif1 += dloc; dif2 += dloc * dloc; dif8 = (dif8 > dloc) ? dif8 : dloc; norm += fabs(ex[k]); } #if defined(USE_MPI) if (processorsCount > 1) { double temp1 = dif1; MPI_Reduce(&temp1, &dif1, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); temp1 = dif2; MPI_Reduce(&temp1, &dif2, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); temp1 = dif8; MPI_Reduce(&temp1, &dif8, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); temp1 = norm; MPI_Reduce(&temp1, &norm, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); } #endif dif2 = sqrt(dif2); norm += 1.0e-100; if (processRank == 0) { std::cout << "Difference with exact solution \"" << vectorXFileName << "\": " << std::scientific << std::setprecision(6) << std::endl; std::cout << "dif1 = " << dif1 << " dif2 = " << dif2 << " dif8 = " << dif8 << " ||ex||_1 = " << norm << std::endl; std::cout << "rel1 = " << dif1 / norm << " rel2 = " << dif2 / norm << " rel8 = " << dif8 / norm << std::endl; } } } BARRIER Solver::Finalize(); // Finalize solver and close MPI activity return 0; }
bool solveTest(Solver& solver, const Array& a,const Array& b, double answer, double precision=1e-10) { double res=solver.Solve(a.begin(), b.begin()); return (fabs(answer-res) < precision); }