int main ( int argc, char *argv[] ) /******************************************************************************/ /* Purpose: MAIN is the main program for POISSON_MPI. Discussion: This program solves Poisson's equation in a 2D region. The Jacobi iterative method is used to solve the linear system. MPI is used for parallel execution, with the domain divided into strips. Modified: 22 September 2013 Local parameters: Local, double F[(N+2)x(N+2)], the source term. Local, int N, the number of interior vertices in one dimension. Local, int NUM_PROCS, the number of MPI processes. Local, double U[(N+2)*(N+2)], a solution estimate. Local, double U_NEW[(N+2)*(N+2)], a solution estimate. */ { char file_name[100]; double change, epsilon = 1.0E-03, *f, *swap, wall_time, my_change; int i, j, my_n, n, num_procs, step; /* MPI initialization. */ MPI_Init ( &argc, &argv ); MPI_Comm_size ( MPI_COMM_WORLD, &num_procs ); MPI_Comm_rank ( MPI_COMM_WORLD, &my_rank ); /* Read commandline arguments, if present. */ if ( 1 < argc ) { sscanf ( argv[1], "%d", &N ); } else { N = 32; } if ( 2 < argc ) { sscanf ( argv[2], "%lf", &epsilon ); } else { epsilon = 1.0E-03; } if ( 3 < argc ) { strcpy ( file_name, argv[3] ); } else { strcpy ( file_name, "poisson_mpi.out" ); } /* Print out initial information. */ if ( my_rank == 0 ) { timestamp ( ); printf ( "\n" ); printf ( "POISSON_MPI:\n" ); printf ( " C version\n" ); printf ( " 2-D Poisson equation using Jacobi algorithm\n" ); printf ( " ===========================================\n" ); printf ( " MPI version: 1-D domains, non-blocking send/receive\n" ); printf ( " Number of processes = %d\n", num_procs ); printf ( " Number of interior vertices = %d\n", N ); printf ( " Desired fractional accuracy = %f\n", epsilon ); printf ( "\n" ); } allocate_arrays ( ); f = make_source ( ); make_domains ( num_procs ); step = 0; /* Begin timing. */ wall_time = MPI_Wtime ( ); /* Begin iteration. */ do { jacobi ( num_procs, f ); ++step; /* Estimate the error */ change = 0.0; n = 0; my_change = 0.0; my_n = 0; for ( i = i_min[my_rank]; i <= i_max[my_rank]; i++ ) { for ( j = 1; j <= N; j++ ) { if ( u_new[INDEX(i,j)] != 0.0 ) { my_change = my_change + fabs ( 1.0 - u[INDEX(i,j)] / u_new[INDEX(i,j)] ); my_n = my_n + 1; } } } MPI_Allreduce ( &my_change, &change, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD ); MPI_Allreduce ( &my_n, &n, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); if ( n != 0 ) { change = change / n; } if ( my_rank == 0 && ( step % 10 ) == 0 ) { printf ( " N = %d, n = %d, my_n = %d, Step %4d Error = %g\n", N, n, my_n, step, change ); } /* Interchange U and U_NEW. */ swap = u; u = u_new; u_new = swap; } while ( epsilon < change ); /* Here is where you can copy the solution to process 0 and print to a file. */ /* Report on wallclock time. */ wall_time = MPI_Wtime() - wall_time; if ( my_rank == 0 ) { printf ( "\n" ); printf ( " Wall clock time = %f secs\n", wall_time ); } /* Terminate MPI. */ MPI_Finalize ( ); /* Free memory. */ free ( f ); /* Terminate. */ if ( my_rank == 0 ) { printf ( "\n" ); printf ( "POISSON_MPI:\n" ); printf ( " Normal end of execution.\n" ); printf ( "\n" ); timestamp ( ); } return 0; }
void simplex_optimization ( vfp nmodel, /* pointer to noise model */ vfp smodel, /* pointer to signal model */ int r, /* number of parameters in the noise model */ int p, /* number of parameters in the signal model */ float * min_nconstr, /* minimum parameter constraints for noise model */ float * max_nconstr, /* maximum parameter constraints for noise model */ float * min_sconstr, /* minimum parameter constraints for signal model */ float * max_sconstr, /* maximum parameter constraints for signal model */ int nabs, /* use absolute constraints for noise parameters */ int ts_length, /* length of time series array */ float ** x_array, /* independent variable matrix */ float * ts_array, /* observed time series */ float * par_rdcd, /* estimated parameters for the reduced model */ float * parameters, /* estimated parameters */ float * sse /* error sum of squares */ ) { const int MAX_ITERATIONS = 50; /* maximum number of iterations */ const int MAX_RESTARTS = 5; /* maximum number of restarts */ const float EXPANSION_COEF = 2.0; /* expansion coefficient */ const float REFLECTION_COEF = 1.0; /* reflection coefficient */ const float CONTRACTION_COEF = 0.5; /* contraction coefficient */ const float TOLERANCE = 1.0e-4; /* solution convergence tolerance */ float ** simplex = NULL; /* the simplex itself */ float * centroid = NULL; /* center of mass of the simplex */ float * response = NULL; /* error sum of squares at each vertex */ float * step_size = NULL; /* controls random placement of new vertex */ float * test1 = NULL; /* test vertex */ float * test2 = NULL; /* test vertex */ float resp1, resp2; /* error sum of squares for test vertex */ int i; /* vertex index */ int worst; /* index of worst vertex in simplex */ int best; /* index of best vertex in simplex */ int next; /* index of next-to-worst vertex in simplex */ int num_iter; /* number of simplex algorithm iterations */ int num_restarts; /* number of restarts of simplex algorithm */ int done; /* boolean for search finished */ float fit; /* array of fitted time series values */ int dimension; /* dimension of parameter space */ /*----- dimension of parameter space -----*/ dimension = r + p; /*----- allocate memory -----*/ allocate_arrays (dimension, &simplex, ¢roid, &response, &step_size, &test1, &test2); /*----- initialization for simplex algorithm -----*/ initialize_simplex (dimension, nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, parameters, simplex, response, step_size, ts_length, x_array, ts_array); /* start loop to do simplex optimization */ num_iter = 0; num_restarts = 0; done = 0; while (!done) { /*----- find the worst vertex and compute centroid of remaining simplex, discarding the worst vertex -----*/ eval_vertices (dimension, response, &worst, &next, &best); calc_centroid (dimension, simplex, worst, centroid); /*----- reflect the worst point through the centroid -----*/ calc_reflection (dimension, simplex, centroid, worst, REFLECTION_COEF, test1); resp1 = calc_sse (nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, test1, ts_length, x_array, ts_array); /*----- test the reflection against the best vertex and expand it if the reflection is better. if not, keep the reflection -----*/ if (resp1 < response[best]) { /*----- try expanding -----*/ calc_reflection (dimension, simplex, centroid, worst, EXPANSION_COEF, test2); resp2 = calc_sse (nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, test2, ts_length, x_array, ts_array); if (resp2 <= resp1) /* keep expansion */ replace (dimension, simplex, response, worst, test2, resp2); else /* keep reflection */ replace (dimension, simplex, response, worst, test1, resp1); } else if (resp1 < response[next]) { /*----- new response is between the best and next worst so keep reflection -----*/ replace (dimension, simplex, response, worst, test1, resp1); } else { /*----- try contraction -----*/ if (resp1 >= response[worst]) calc_reflection (dimension, simplex, centroid, worst, -CONTRACTION_COEF, test2); else calc_reflection (dimension, simplex, centroid, worst, CONTRACTION_COEF, test2); resp2 = calc_sse (nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, test2, ts_length, x_array, ts_array); /*---- test the contracted response against the worst response ----*/ if (resp2 > response[worst]) { /*----- new contracted response is worse, so decrease step size and restart -----*/ num_iter = 0; num_restarts += 1; restart (dimension, nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, simplex, response, step_size, ts_length, x_array, ts_array); } else /*----- keep contraction -----*/ replace (dimension, simplex, response, worst, test2, resp2); } /*----- test to determine when to stop. first, check the number of iterations -----*/ num_iter += 1; /*----- increment iteration counter -----*/ if (num_iter >= MAX_ITERATIONS) { /*----- restart with smaller steps -----*/ num_iter = 0; num_restarts += 1; restart (dimension, nmodel, smodel, r, p, nabs, min_nconstr, max_nconstr, min_sconstr, max_sconstr, par_rdcd, simplex, response, step_size, ts_length, x_array, ts_array); } /*----- limit the number of restarts -----*/ if (num_restarts == MAX_RESTARTS) done = 1; /*----- compare relative standard deviation of vertex responses against a defined tolerance limit -----*/ fit = calc_good_fit (dimension, response); if (fit <= TOLERANCE) done = 1; /*----- if done, copy the best solution to the output array -----*/ if (done) { eval_vertices (dimension, response, &worst, &next, &best); for (i = 0; i < dimension; i++) parameters[i] = simplex[best][i]; *sse = response[best]; } } /*----- while (!done) -----*/ deallocate_arrays (dimension, &simplex, ¢roid, &response, &step_size, &test1, &test2); }
void simplex_optimization (float * parameters, float * sse) { const int MAX_ITERATIONS = 100; const int MAX_RESTARTS = 25; const float EXPANSION_COEF = 2.0; const float REFLECTION_COEF = 1.0; const float CONTRACTION_COEF = 0.5; const float TOLERANCE = 1.0e-10; float ** simplex = NULL; float * centroid = NULL; float * response = NULL; float * step_size = NULL; float * test1 = NULL; float * test2 = NULL; float resp1, resp2; int i, worst, best, next; int num_iter, num_restarts; int done; float fit; allocate_arrays (&simplex, ¢roid, &response, &step_size, &test1, &test2); simplex_initialize (parameters, simplex, response, step_size); /* start loop to do simplex optimization */ num_iter = 0; num_restarts = 0; done = 0; while (!done) { /* find the worst vertex and compute centroid of remaining simplex, discarding the worst vertex */ eval_vertices (response, &worst, &next, &best); calc_centroid (simplex, worst, centroid); /* reflect the worst point through the centroid */ calc_reflection (simplex, centroid, worst, REFLECTION_COEF, test1); resp1 = calc_error (test1); /* test the reflection against the best vertex and expand it if the reflection is better. if not, keep the reflection */ if (resp1 < response[best]) { /* try expanding */ calc_reflection (simplex, centroid, worst, EXPANSION_COEF, test2); resp2 = calc_error (test2); if (resp2 <= resp1) /* keep expansion */ replace (simplex, response, worst, test2, resp2); else /* keep reflection */ replace (simplex, response, worst, test1, resp1); } else if (resp1 < response[next]) { /* new response is between the best and next worst so keep reflection */ replace (simplex, response, worst, test1, resp1); } else { /* try contraction */ if (resp1 >= response[worst]) calc_reflection (simplex, centroid, worst, -CONTRACTION_COEF, test2); else calc_reflection (simplex, centroid, worst, CONTRACTION_COEF, test2); resp2 = calc_error (test2); /* test the contracted response against the worst response */ if (resp2 > response[worst]) { /* new contracted response is worse, so decrease step size and restart */ num_iter = 0; num_restarts += 1; restart (simplex, response, step_size); } else /* keep contraction */ replace (simplex, response, worst, test2, resp2); } /* test to determine when to stop. first, check the number of iterations */ num_iter += 1; /* increment iteration counter */ if (num_iter >= MAX_ITERATIONS) { /* restart with smaller steps */ num_iter = 0; num_restarts += 1; restart (simplex, response, step_size); } /* limit the number of restarts */ if (num_restarts == MAX_RESTARTS) done = 1; /* compare relative standard deviation of vertex responses against a defined tolerance limit */ fit = calc_good_fit (response); if (fit <= TOLERANCE) done = 1; /* if done, copy the best solution to the output array */ if (done) { eval_vertices (response, &worst, &next, &best); for (i = 0; i < DIMENSION; i++) parameters[i] = simplex[best][i]; *sse = response[best]; } } /* while (!done) */ number_restarts = num_restarts; deallocate_arrays (&simplex, ¢roid, &response, &step_size, &test1, &test2); }
void NLSSOLLeastSq::minimize_residuals() { //------------------------------------------------------------------ // Solve the problem. //------------------------------------------------------------------ // set the object instance pointers for use within the static member fns NLSSOLLeastSq* prev_nls_instance = nlssolInstance; SOLBase* prev_sol_instance = solInstance; nlssolInstance = this; solInstance = this; optLSqInstance = this; // set the constraint offset used in SOLBase::constraint_eval() constrOffset = numLeastSqTerms; fnEvalCntr = 0; // prevent current iterator from continuing previous counting // Use data structures in the NLSSOL call that are NOT updated in // constraint_eval or least_sq_eval [Using overlapping arrays causes // erroneous behavior]. int num_cv = numContinuousVars; double local_f_val = 0.; RealVector local_lsq_vals(numLeastSqTerms); RealVector local_lsq_offsets(numLeastSqTerms, true); double* local_lsq_grads = new double [numLeastSqTerms*numContinuousVars]; allocate_arrays(numContinuousVars, numNonlinearConstraints, iteratedModel.linear_ineq_constraint_coeffs(), iteratedModel.linear_eq_constraint_coeffs()); allocate_workspace(numContinuousVars, numNonlinearConstraints, numLinearConstraints, numLeastSqTerms); // NLSSOL requires a non-zero array size. Therefore, size the local // constraint arrays and matrices to a size of 1 if there are no nonlinear // constraints and to the proper size otherwise. RealVector local_c_vals(nlnConstraintArraySize); // initialize local_des_vars with DB initial point. Variables are updated // in constraint_eval/least_sq_eval RealVector local_des_vars; copy_data(iteratedModel.continuous_variables(), local_des_vars); // Augmentation of bounds appears here rather than in the constructor because // these bounds must be updated from model bounds each time an iterator is // run within the B&B strategy. RealVector augmented_l_bnds, augmented_u_bnds; copy_data(iteratedModel.continuous_lower_bounds(), augmented_l_bnds); copy_data(iteratedModel.continuous_upper_bounds(), augmented_u_bnds); augment_bounds(augmented_l_bnds, augmented_u_bnds, iteratedModel.linear_ineq_constraint_lower_bounds(), iteratedModel.linear_ineq_constraint_upper_bounds(), iteratedModel.linear_eq_constraint_targets(), iteratedModel.nonlinear_ineq_constraint_lower_bounds(), iteratedModel.nonlinear_ineq_constraint_upper_bounds(), iteratedModel.nonlinear_eq_constraint_targets()); NLSSOL_F77( numLeastSqTerms, num_cv, numLinearConstraints, numNonlinearConstraints, linConstraintArraySize, nlnConstraintArraySize, numLeastSqTerms, num_cv, linConstraintMatrixF77, augmented_l_bnds.values(), augmented_u_bnds.values(), constraint_eval, least_sq_eval, informResult, numberIterations, &constraintState[0], local_c_vals.values(), constraintJacMatrixF77, local_lsq_offsets.values(), local_lsq_vals.values(), local_lsq_grads, &cLambda[0], local_f_val, upperFactorHessianF77, local_des_vars.values(), &intWorkSpace[0], intWorkSpaceSize, &realWorkSpace[0], realWorkSpaceSize ); // NLSSOL completed. Do post-processing/output of final NLSSOL info and data: Cout << "\nNLSSOL exits with INFORM code = " << informResult << " (see \"Interpretation of output\" section of NPSOL manual)\n"; deallocate_arrays(); // SOLBase deallocate fn (shared with NPSOLOptimizer) delete [] local_lsq_grads; // Set best variables and response for use by strategy level. // local_des_vars, local_lsq_vals, & local_c_vals contain the optimal design // (not the final fn. eval) since NLSSOL performs this assignment internally // prior to exiting (see "Subroutine npsol" section of NPSOL manual). bestVariablesArray.front().continuous_variables(local_des_vars); RealVector best_fns(numFunctions); //copy_data_partial(local_lsq_vals, best_fns, 0); std::copy(local_lsq_vals.values(), local_lsq_vals.values() + numLeastSqTerms, best_fns.values()); if (numNonlinearConstraints) { //copy_data_partial(local_c_vals, best_fns, numLeastSqTerms); std::copy(local_c_vals.values(), local_c_vals.values() + nlnConstraintArraySize, best_fns.values() + numLeastSqTerms); } bestResponseArray.front().function_values(best_fns); /* // For better post-processing, could append fort.9 to dakota.out line // by line, but: THERE IS A PROBLEM WITH GETTING ALL OF THE FILE! // (FORTRAN output is lacking a final buffer flush?) Cout << "\nEcho NLSSOL's iteration output from fort.9 file:\n" << std::endl; std::ifstream npsol_fort_9( "fort.9" ); char fort_9_line[255]; while (npsol_fort_9) { npsol_fort_9.getline( fort_9_line, 255 ); Cout << fort_9_line << '\n'; } Cout << std::endl; */ Cout << "\nNOTE: see Fortran device 9 file (fort.9 or ftn09)" << "\n for complete NLSSOL iteration history." << std::endl; get_confidence_intervals(); // restore in case of recursion nlssolInstance = prev_nls_instance; solInstance = prev_sol_instance; optLSqInstance = prevMinInstance; }