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;
}
Exemple #2
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, &centroid, &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, &centroid, &response, &step_size,
		     &test1, &test2);

}
Exemple #3
0
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, &centroid, &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, &centroid, &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;
}