# include <math.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>

# include "dream.h"
# include "dream_user.h"
# include "pdflib.h"
# include "rnglib.h"

/******************************************************************************/

int main ( )

/******************************************************************************/
/*
  Purpose:

    MAIN is the main program for DREAM.

  Discussion:

    The DREAM program was originally developed by Guannan Zhang, of
    Oak Ridge National Laboratory (ORNL); it has been incorporated into 
    the DAKOTA package of Sandia National Laboratory, and is
    intended to form part of the ORNL package known as TASMANIA.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    28 May 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Reference:

    Jasper Vrugt, CJF ter Braak, CGH Diks, Bruce Robinson, James Hyman, 
    Dave Higdon,
    Accelerating Markov Chain Monte Carlo Simulation by Differential 
    Evolution with Self-Adaptive Randomized Subspace Sampling,
    International Journal of Nonlinear Sciences and Numerical Simulation,
    Volume 10, Number 3, March 2009, pages 271-288.

  Local parameters:

    Local, char *CHAIN_FILENAME, the "base" filename
    to be used for the chain files.  If this is NULL
    then the chain files will not be written.  This name should 
    include a string of 0's which will be replaced by the chain 
    indices.  For example, "chain000.txt" would work as long as the
    number of chains was 1000 or less.

    Local, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Local, int CR_NUM, the total number of CR values.
    1 <= CR_NUM.

    Local, double FIT[CHAIN_NUM*GEN_NUM], the likelihood of
    each sample.

    Local, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Local, double GR[PAR_NUM*GR_NUM], 
    the Gelman-Rubin R statistic.

    Local, logical GR_CONV, the Gelman-Rubin convergence flag.

    Local, int GR_COUNT, counts the number of generations
    at which the Gelman-Rubin statistic has been computed.

    Local, char *GR_FILENAME, the name of the file
    in which values of the Gelman-Rubin statistic will be recorded,
    or NULL if this file is not to be written.

    Local, int GR_NUM, the number of times the Gelman-Rubin
    statistic may be computed.

    Local, double GR_THRESHOLD, the convergence tolerance for
    the Gelman-Rubin statistic.

    Local, double JUMPRATE_TABLE[PAR_NUM], the jumprate table.

    Local, int JUMPSTEP, forces a "long jump" every
    JUMPSTEP generations.

    Local, double LIMITS[2*PAR_NUM], lower and upper bounds
    for each parameter.

    Local, int PAIR_NUM, the number of pairs of 
    crossover chains.
    0 <= PAIR_NUM.

    Local, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Local, int PRINTSTEP, the interval between generations on 
    which the Gelman-Rubin statistic will be computed and written to a file.

    Local, char *RESTART_READ_FILENAME, the name of the file
    containing restart information.  If this calculation is not a restart,
    then this should be NULL.

    Local, char *RESTART_WRITE_FILENAME, the name of the file
    to be written, containing restart information.  If a restart file is not
    to be written, this should be NULL.

    Local, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.
*/
{
  char *chain_filename = NULL;
  int chain_num;
  int cr_num;
  double *fit;
  int gen_num;
  double *gr;
  int gr_conv;
  int gr_count;
  char *gr_filename = NULL;
  int gr_num;
  double gr_threshold;
  double *jumprate_table;
  int jumpstep;
  double *limits;
  int pair_num;
  int par_num;
  int printstep;
  char *restart_read_filename = NULL;
  char *restart_write_filename = NULL;
  double *z;

  timestamp ( );

  printf ( "\n" );
  printf ( "DREAM\n" );
  printf ( "  C version\n" );
  printf ( "  MCMC acceleration by Differential Evolution.\n" );
/*
  Get the problem sizes.
*/
  problem_size ( &chain_num, &cr_num, &gen_num, &pair_num, &par_num );
/*
  Decide if the problem sizes are acceptable.
*/
  if ( chain_num < 3 )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "DREAM - Fatal error!\n" );
    fprintf ( stderr, "  CHAIN_NUM < 1.\n" );
    exit ( 1 );
  }
  if ( cr_num < 1 )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "DREAM - Fatal error!\n" );
    fprintf ( stderr, "  CR_NUM < 1.\n" );
    exit ( 1 );
  }
  if ( gen_num < 2 )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "DREAM - Fatal error!\n" );
    fprintf ( stderr, "  GEN_NUM < 2.\n" );
    exit ( 1 );
  }
  if ( pair_num < 0 )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "DREAM - Fatal error!\n" );
    fprintf ( stderr, "  PAIR_NUM < 0.\n" );
    exit ( 1 );
  }
  if ( par_num < 1 )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "DREAM - Fatal error!\n" );
    fprintf ( stderr, "  PAR_NUM < 1.\n" );
    exit ( 1 );
  }
/*
  Get the problem data values.
*/
  limits = r8mat_zero_new ( 2, par_num );

  problem_value ( &chain_filename, &gr_filename, &gr_threshold, &jumpstep,
    limits, par_num, &printstep, &restart_read_filename,
    &restart_write_filename );
/*
  Print the data as a job record.
*/
  input_print ( chain_filename, chain_num, cr_num, gr_filename, gr_threshold, 
    jumpstep, limits, gen_num, pair_num, par_num, 
    printstep, restart_read_filename, restart_write_filename );
/*
  Allocate and zero out memory.
*/
  gr_num = gen_num / printstep;

  fit = r8mat_zero_new ( chain_num, gen_num );
  gr = r8mat_zero_new ( par_num, gr_num );
  z = r8block_zero_new ( par_num, chain_num, gen_num );
/*
  Set the jump rate table.
*/
  jumprate_table = jumprate_table_init ( pair_num, par_num );

  jumprate_table_print ( jumprate_table, pair_num, par_num );
/*
  Initialize the Gelman-Rubin data.
*/
  gr_init ( gr, &gr_conv, &gr_count, gr_num, par_num );

  printf ( "\n" );
  printf ( "GR_PRINT:\n" );
  printf ( "  GR_CONV  = %d\n", gr_conv );
  printf ( "  GR_COUNT = %d\n", gr_count );
  printf ( "  GR_NUM   = %d\n", gr_num );
/*
  Set the first generation of the chains from restart data, or by sampling.
*/
  if ( ! restart_read_filename )
  {
    chain_init ( chain_num, fit, gen_num, par_num, z );
  }
  else
  {
    restart_read ( chain_num, fit, gen_num, par_num, restart_read_filename, z );
  }
  chain_init_print ( chain_num, fit, gen_num, par_num, restart_read_filename, 
    z );
/*
  Carry out the DREAM algorithm.
*/
  dream_algm ( chain_num, cr_num, fit, gen_num, gr, &gr_conv, &gr_count, 
    gr_num, gr_threshold, jumprate_table, jumpstep, limits, pair_num, 
    par_num, printstep, z );
/*
  Save Gelman-Rubin statistic values to a file.
*/
  if ( gr_filename )
  {
    gr_write ( gr, gr_filename, gr_num, par_num, printstep );
  }
/*
  Save parameter values for all chains at last generation.
*/
  if ( restart_write_filename )
  {
    restart_write ( chain_num, fit, gen_num, par_num, restart_write_filename, 
      z );
  }
/*
  Write each chain to a separate file.
*/
  if ( chain_filename )
  {
    chain_write ( chain_filename, chain_num, fit, gen_num, par_num, z );
  }
/*
  Free memory.
*/
  free ( fit );
  free ( gr );
  free ( jumprate_table );
  free ( limits );
  free ( z );
/*
  Terminate.
*/
  printf ( "\n" );
  printf ( "DREAM:\n" );
  printf ( "  Normal end of execution.\n" );
  printf ( "\n" );
  timestamp ( );

  return 0;
}
/******************************************************************************/

void chain_init ( int chain_num, double fit[], int gen_num, int par_num,  
  double z[] )

/******************************************************************************/
/*
  Purpose:

    CHAIN_INIT starts Markov chains from a prior distribution.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    24 May 2013

  Author:

    John Burkardt

  Parameters:

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Output, double FIT[CHAIN_NUM*GEN_NUM], the likelihood of
    each sample.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Output, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.
*/
{
  int c;
  int p;
  double *zp;

  for ( c = 0; c < chain_num; c++ )
  {
    zp = prior_sample ( par_num );

    for ( p = 0; p < par_num; p++ )
    {
      z[p+c*par_num+0*par_num*chain_num] = zp[p];
    }

    fit[c+0*chain_num] = sample_likelihood ( par_num, zp );

    free ( zp );
  }
  return;
}
/******************************************************************************/

void chain_init_print ( int chain_num, double fit[], int gen_num, int par_num, 
  char *restart_read_filename, double z[] )

/******************************************************************************/
/*
  Purpose:

    CHAIN_INIT_PRINT prints the initial values for Markov chains.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    23 April 2013

  Author:

    John Burkardt

  Parameters:

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input, double FIT[CHAIN_NUM*GEN_NUM], the likelihood of
    each sample.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, int RESTART_FLAG, is TRUE if the chains are to be initialized
    from a restart file.

    Input, char *RESTART_READ_FILENAME, the name of the 
    restart file.

    Input, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.
*/
{
  int i;
  int j;

  printf ( "\n" );
  printf ( "CHAIN_INIT_PRINT\n" );
  printf ( "  Display initial values of Markov chains.\n" );

  if ( restart_read_filename )
  {
    printf ( "  Initialization from restart file \"%s\"\n",
      restart_read_filename );
  }
  else
  {
    printf ( "  Initialization by sampling prior density.\n" );
  }
  for ( j = 0; j < chain_num; j++ )
  {
    printf ( "\n" );
    printf ( "  Chain %d\n", j );
    printf ( "  Fitness %g\n", fit[j+0*chain_num] );
    for ( i = 0; i < par_num; i++ )
    {
      printf ( "  %g", z[i+j*par_num+0*par_num*chain_num] );
      if ( ( i + 1 ) % 5 == 0 || i == par_num - 1 )
      {
        printf ( "\n" );
      }
    }
  }
  return;
}
/******************************************************************************/

void chain_outliers ( int chain_num, int gen_index, int gen_num, int par_num,
  double fit[], double z[] )

/******************************************************************************/
/*
  Purpose:

    CHAIN_OUTLIERS identifies and modifies outlier chains during burn-in.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    24 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Reference:

    Jasper Vrugt, CJF ter Braak, CGH Diks, Bruce Robinson, James Hyman, 
    Dave Higdon,
    Accelerating Markov Chain Monte Carlo Simulation by Differential 
    Evolution with Self-Adaptive Randomized Subspace Sampling,
    International Journal of Nonlinear Sciences and Numerical Simulation,
    Volume 10, Number 3, March 2009, pages 271-288.

  Parameters:

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input, int GEN_INDEX, the index of the current generation.
    2 <= GEN_INDEX <= GEN_NUM.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input/output, double FIT[CHAIN_NUM*GEN_NUM], the likelihood of
    each sample.

    Input/output, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov
    chain sample data.
*/
{
  double *avg;
  double avg_max;
  double *avg_sorted;
  int best;
  int i;
  int ind1;
  int ind3;
  int j;
  int klo;
  int knum;
  int k;
  int outlier_num;
  double q1;
  double q3;
  double qr;
  double t;

  klo = ( ( gen_index + 1 ) / 2 ) - 1;
  knum = gen_index + 1 - klo;

  avg = ( double * ) malloc ( chain_num * sizeof ( double ) );

  for ( j = 0; j < chain_num; j++ )
  {
    t = 0.0;
    for ( k = klo; k <= gen_index; k++ )
    {
      t = t + fit[j+k*chain_num];
    }
    avg[j] = t  / ( double ) ( knum );
  }
/*
  Set BEST to be the index of the chain with maximum average.
*/
  best = 0;
  avg_max = avg[0];
  for ( j = 1; j < chain_num; j++ )
  {
    if ( avg_max < avg[j] )
    {
      best = j;
      avg_max = avg[j];
    }
  }
/*
  Determine the indices of the chains having averages 1/4 "above" 
  and "below" the average.
*/
  avg_sorted = r8vec_copy_new ( chain_num, avg );

  r8vec_sort_heap_a ( chain_num, avg_sorted );

  ind1 = r8_round_i4 ( 0.25 * ( double ) ( chain_num ) );
  ind3 = r8_round_i4 ( 0.75 * ( double ) ( chain_num ) );

  q1 = avg_sorted[ind1];
  q3 = avg_sorted[ind3];
  qr = q3 - q1;

  free ( avg_sorted );
/*
  Identify outlier chains, and replace their later samples
  with values from the "best" chain.
*/
  outlier_num = 0;
  for ( j = 0; j < chain_num; j++ )
  {
    if ( avg[j] < q1 - 2.0 * qr )
    {
      outlier_num = outlier_num + 1;
      for ( i = 0; i < par_num; i++ )
      {
        z[i+j*par_num+gen_index*par_num*chain_num] = 
          z[i+best*par_num+gen_index*par_num*chain_num];
      }
      for ( k = klo; k <= gen_index; k++ )
      {
        fit[j+k*chain_num]  = fit[best+k*chain_num];
      }
    }
  }
/*
  List the outlier chains.
*/
  if ( 0 < outlier_num )
  {
    printf ( "\n" );
    printf ( "CHAIN_OUTLIERS:\n" );
    printf ( "  At iteration %d found %d outlier chains,\n", 
      gen_index, outlier_num );
    printf ( "  whose indices appear below, and for which samples\n" );
    printf ( "  from the chain with the largest log likelihood function,\n" );
    printf ( "  index number %d  will be substituted.\n", best );

    for ( j = 0; j < chain_num; j++ )
    {
      if ( avg[j] < q1 - 2.0 * qr )
      {
        printf ( "  %d\n", j );
      }
    }
  }

  free ( avg );

  return;
}
/******************************************************************************/

void chain_write ( char *chain_filename, int chain_num, double fit[], 
  int gen_num, int par_num, double z[] )

/******************************************************************************/
/*
  Purpose:

    CHAIN_WRITE writes samples of each chain to separate files.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    24 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version John Burkardt.

  Parameters:

    Input, char *CHAIN_FILENAME, the "base" filename
    to be used for the chain files.  If this is NULL
    then the chain files will not be written.  This name should 
    include a string of 0's which will be replaced by the chain 
    indices.  For example, "chain000.txt" would work as long as the
    number of chains was 1000 or less.

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input, double FIT[CHAIN_NUM*GEN_NUM], the likelihood of
    each sample.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.
*/
{
  FILE *chain_unit;
  char chain_filename2[255];
  int i;
  int j;
  int k;
/*
  Make a temporary copy of the filename template, which we can alter.
*/
  strcpy ( chain_filename2, chain_filename );
/*
  Write parameter samples of all chains.
*/
  printf ( "\n" );
  printf ( "CHAIN_WRITE:\n" );

  for ( j = 0; j < chain_num; j++ )
  {
    chain_unit = fopen ( chain_filename2, "wt" );

    if ( ! chain_unit )
    {
      fprintf ( stderr, "\n" );
      fprintf ( stderr, "CHAIN_WRITE - Fatal error!\n" );
      fprintf ( stderr, "  Could not open file \"%s\".\n", chain_filename2 );
      exit ( 1 );
    }

    fprintf ( chain_unit, 
      "DREAM.C:Parameters_and_log_likelihood_for_chain_#%d\n", j );
    for ( k = 0; k < gen_num; k++ )
    {
      fprintf ( chain_unit, "  %d  %g", k, fit[j+k*chain_num] );
      for ( i = 0; i < par_num; i++ )
      {
        fprintf ( chain_unit, "  %g", z[i+j*par_num+k*par_num*chain_num] );
      }
      fprintf ( chain_unit, "\n" );
    }

    fclose ( chain_unit );

    printf ( "  Created file \"%s\".\n", chain_filename2 );

    filename_inc ( chain_filename2 );
  }
  return;
}
/******************************************************************************/

void cr_dis_update ( int chain_index, int chain_num, double cr_dis[], 
  int cr_index, int cr_num, int cr_ups[], int gen_index, int gen_num, 
  int par_num, double z[] )

/******************************************************************************/
/*
  Purpose:

    CR_DIS_UPDATE updates the CR distance.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    29 August 2018

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Input, int CHAIN_INDEX, the index of the chain.
    0 <= CHAIN_INDEX < CHAIN_NUM.

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input/output, double CR_DIS[CR_NUM], the CR distances.

    Input, int CR_INDEX, the index of the CR.
    0 <= CR_INDEX < CR_NUM.

    Input, int CR_NUM, the total number of CR values.
    1 <= CR_NUM.

    Input/output, int CR_UPS[CR_NUM], the number of updates 
    for each CR.

    Input, int GEN_INDEX, the index of the generation.
    0 <= GEN_INDEX < GEN_NUM.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.
*/
{
  int i;
  int i1;
  int i2;
  double *std;
/*
  Compute the standard deviations.
*/
  std = std_compute ( chain_num, gen_index, gen_num, par_num, z );
/*
  Increment the update count.
*/
  cr_ups[cr_index] = cr_ups[cr_index] + 1;
/*
  Update the CR distance.
*/
  for ( i = 0; i < par_num; i++ )
  {
    i1 = i + chain_index * par_num +   gen_index       * par_num * chain_num;
    i2 = i + chain_index * par_num + ( gen_index - 1 ) * par_num * chain_num;
    cr_dis[cr_index] = cr_dis[cr_index] + pow ( ( z[i2] - z[i1] ) / std[i], 2 );
  }

  free ( std );

  return;
}
/******************************************************************************/

int cr_index_choose ( int cr_num, double cr_prob[] )

/******************************************************************************/
/*
  Purpose:

    CR_INDEX_CHOOSE chooses a CR index.

  Discussion:

    Index I is chosen with probability CR_PROB(I).

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    14 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Input, int CR_NUM, the total number of CR values.
    1 <= CR_NUM.

    Input, double CR_PROB[CR_NUM], the probability of each CR.

    Output, int CR_INDEX_CHOOSE, the index of the CR.
    0 <= CR_INDEX_CHOOSE < CR_NUM.
*/
{
  int cr_index;
  int i;
  int n;
  int *tmp_index;

  if ( cr_num == 1 )
  {
    cr_index = 0;
  }
  else
  { 
    n = 1;
    tmp_index = i4vec_multinomial_sample ( n, cr_prob, cr_num );

    for ( i = 0; i < cr_num; i++ )
    {
      if ( tmp_index[i] == 1 )
      {
        cr_index = i;
        break;
      }
    }
    free ( tmp_index );
  }
  return cr_index;
}
/******************************************************************************/

void cr_init ( double cr[], double cr_dis[], int cr_num, double cr_prob[], 
  int cr_ups[] )

/******************************************************************************/
/*
  Purpose:

    CR_INIT initializes the crossover probability values.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    13 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Output, double CR[CR_NUM], the CR values.

    Output, double CR_DIS[CR_NUM], the CR distances.

    Input, int CR_NUM, the total number of CR values.
    1 <= CR_NUM.

    Output, double CR_PROB[CR_NUM], the probability of each CR.

    Output, int CR_UPS[CR_NUM], the number of updates
    for each CR.
*/
{
  int i;

  for ( i = 0; i < cr_num; i++ )
  {
    cr[i] = ( double ) ( i + 1 ) / ( double ) ( cr_num );
    cr_dis[i] = 1.0;
    cr_prob[i] = 1.0 / ( double ) ( cr_num );
    cr_ups[i] = 1;
  }
  return;
}
/******************************************************************************/

void cr_prob_update ( double cr_dis[], int cr_num, double cr_prob[], 
  int cr_ups[] )

/******************************************************************************/
/*
  Purpose:

    CR_PROB_UPDATE updates the CR probabilities.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    14 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Input, double CR_DIS[CR_NUM], the CR distances.

    Input, int CR_NUM, the total number of CR values.
    1 <= CR_NUM.

    Output, double CR_PROB[CR_NUM], the updated CR probabilities.

    Input, int CR_UPS[CR_NUM], the number of updates 
    for each CR.
*/
{
  double cr_prob_sum;
  int i;
 
  for ( i = 0; i < cr_num - 1; i++ )
  {
    cr_prob[i] = cr_dis[i] / ( double ) cr_ups[i];
  }

  cr_prob_sum = r8vec_sum ( cr_num, cr_prob );

  for ( i = 0; i < cr_num - 1; i++ )
  {
    cr_prob[i] = cr_prob[i] / cr_prob_sum;
  }

  return;
}
/******************************************************************************/

double *diff_compute ( int chain_num, int gen_index, int gen_num, 
  int jump_dim[], int jump_num, int pair_num, int par_num, int r[], 
  double z[] ) 

/******************************************************************************/
/*
  Purpose:

    DIFF_COMPUTE computes the differential evolution.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    15 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Reference:

    Jasper Vrugt, CJF ter Braak, CGH Diks, Bruce Robinson, James Hyman, 
    Dave Higdon,
    Accelerating Markov Chain Monte Carlo Simulation by Differential 
    Evolution with Self-Adaptive Randomized Subspace Sampling,
    International Journal of Nonlinear Sciences and Numerical Simulation,
    Volume 10, Number 3, March 2009, pages 271-288.

  Parameters:

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input, int GEN_INDEX, the index of the current generation.
    1 <= GEN_INDEX <= GEN_NUM.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, int JUMP_DIM[JUMP_NUM], the dimensions in which
    a jump is to be made.

    Input, int JUMP_NUM, the number of dimensions in which
    a jump will be made.  0 <= JUMP_NUM <= PAR_NUM.

    Input, int PAIR_NUM, the number of pairs of 
    crossover chains.
    0 <= PAIR_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, int R[2*PAIR_NUM], pairs of chains used
    to compute differences.

    Input, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.

    Output, double DIFF_COMPUTE[PAR_NUM], the vector of pair differences.
*/
{
  double *diff;
  int i1;
  int i2;
  int j;
  int k;
  int pair;
  int r1;
  int r2;
/*
  Produce the difference of the pairs used for population evolution.
*/
  diff = r8vec_zero_new ( par_num );

  for ( pair = 0; pair < pair_num; pair++ )
  {
    r1 = r[0+pair*2];
    r2 = r[1+pair*2];
    for ( j = 0; j < jump_num; j++ )
    {
      k = jump_dim[j];
      i1 = k+r1*par_num+(gen_index-1)*par_num*chain_num;
      i2 = k+r2*par_num+(gen_index-1)*par_num*chain_num;
      diff[k] = diff[k] + ( z[i1] - z[i2] );
    }
  }

  return diff;
}
/******************************************************************************/

void dream_algm ( int chain_num, int cr_num, double fit[], int gen_num, 
  double gr[], int *gr_conv, int *gr_count, int gr_num, double gr_threshold, 
  double jumprate_table[], int jumpstep, double limits[], int pair_num, 
  int par_num, int printstep, double z[] )
    
/******************************************************************************/
/*
  Purpose:

    DREAM_ALGM gets a candidate parameter sample.

 Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    24 May 2013

  Author:

    John Burkardt

  Reference:

    Jasper Vrugt, CJF ter Braak, CGH Diks, Bruce Robinson, James Hyman, 
    Dave Higdon,
    Accelerating Markov Chain Monte Carlo Simulation by Differential 
    Evolution with Self-Adaptive Randomized Subspace Sampling,
    International Journal of Nonlinear Sciences and Numerical Simulation,
    Volume 10, Number 3, March 2009, pages 271-288.

  Parameters:

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input, int CR_NUM, the total number of CR values.
    1 <= CR_NUM.

    Input, double FIT[CHAIN_NUM*GEN_NUM], the likelihood of
    each sample.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, double GR[PAR_NUM*GR_NUM], 
    the Gelman-Rubin R statistic.

    Input/output, int *GR_CONV, the Gelman-Rubin convergence flag.

    Input/output, int *GR_COUNT, counts the number of generations
    at which the Gelman-Rubin statistic has been computed.

    Input, int GR_NUM, the number of times the Gelman-Rubin
    statistic may be computed.

    Input, double GR_THRESHOLD, the convergence tolerance for
    the Gelman-Rubin statistic.

    Input, double JUMPRATE_TABLE[PAR_NUM], the jumprate table.

    Input, int JUMPSTEP, forces a "long jump" every
    JUMPSTEP generations.

    Input, double LIMITS[2*PAR_NUM], lower and upper bounds
    for each parameter.

    Input, int PAIR_NUM, the number of pairs of 
    crossover chains.
    0 <= PAIR_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, int PRINTSTEP, the interval between generations on 
    which the Gelman-Rubin statistic will be computed and written to a file.

    Input/output, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.

  Local parameters:

    Local, int CHAIN_INDEX, the index of the current chain.
    1 <= CHAIN_INDEX <= CHAIN_NUM.

    Local, double CR[CR_NUM], the CR values.

    Local, double CR_DIS[CR_NUM], the CR distances.

    Local, int CR_INDEX, the index of the selected CR value.
    1 <= CR_INDEX <= CR_NUM.

    Local, double CR_PROB[CR_NUM], the probability of each CR.

    Local, double CR_UPS[CR_NUM], the number of updates for each CR.

    Local, int GEN_INDEX, the index of the current generation.
    1 <= GEN_INDEX <= GEN_NUM.

    Local, double ZP[PAR_NUM], a candidate sample.

    Local, int ZP_ACCEPT, the number of candidates accepted.

    Local, double ZP_ACCEPT_RATE, the rate at which generated
    candidates were accepted.

    Local, int ZP_COUNT, the number of candidates generated.

    Local, double ZP_RATIO, the Metropolis ratio for a candidate.
*/
{
  int chain_index;
  double *cr;
  double *cr_dis;
  int cr_index;
  double *cr_prob;
  int *cr_ups;
  int gen_index;
  int i;
  double pd1;
  double pd2;
  double r;
  double *zp;
  int zp_accept;
  double zp_accept_rate;
  int zp_count;
  double zp_fit;
  double *zp_old;
  double zp_old_fit;
  double zp_ratio;

  zp_old = ( double * ) malloc ( par_num * sizeof ( double ) );
  zp_count = 0;
  zp_accept = 0;
/*
  Initialize the CR values.
*/
  cr = ( double * ) malloc ( cr_num * sizeof ( double ) );
  cr_dis = ( double * ) malloc ( cr_num * sizeof ( double ) );
  cr_prob = ( double * ) malloc ( cr_num * sizeof ( double ) );
  cr_ups = ( int * ) malloc ( cr_num * sizeof ( int ) );

  cr_init ( cr, cr_dis, cr_num, cr_prob, cr_ups );

  for ( gen_index = 1; gen_index < gen_num; gen_index++ )
  {
    for ( chain_index = 0; chain_index < chain_num; chain_index++ )
    {
/*
  Choose CR_INDEX, the index of a CR.
*/
      cr_index = cr_index_choose ( cr_num, cr_prob );
/*    
  Generate a sample candidate ZP.
*/
      zp = sample_candidate ( chain_index, chain_num, cr, cr_index, cr_num, 
        gen_index, gen_num, jumprate_table, jumpstep, limits, pair_num, 
        par_num, z );

      zp_count = zp_count + 1;
/*
  Compute the log likelihood function for ZP.
*/
      zp_fit = sample_likelihood ( par_num, zp );

      for ( i = 0; i < par_num; i++ )
      {
        zp_old[i] = z[i+chain_index*par_num+(gen_index-1)*par_num*chain_num];
      }
      zp_old_fit = fit[chain_index+(gen_index-1)*chain_num];
/*
  Compute the Metropolis ratio for ZP.
*/
      pd1 = prior_density ( par_num, zp );

      pd2 = prior_density ( par_num, 
        z+0+chain_index*par_num+(gen_index-1)*par_num*chain_num );

      zp_ratio = exp ( 
        ( zp_fit     + log ( pd1 ) ) - 
        ( zp_old_fit + log ( pd2 ) ) );

      zp_ratio = r8_min ( zp_ratio, 1.0 );
/*
  Accept the candidate, or copy the value from the previous generation.
*/
      r = r8_uniform_01_sample ( );

      if ( r <= zp_ratio )
      {
        for ( i = 0; i < par_num; i++ )
        {
          z[i+chain_index*par_num+gen_index*par_num*chain_num] = zp[i];
        }
        zp_accept = zp_accept + 1;
        fit[chain_index+gen_index*chain_num] = zp_fit;
      }
      else
      {
        for ( i = 0; i < par_num; i++ )
        {
          z[i+chain_index*par_num+gen_index*par_num*chain_num] = zp_old[i];
        }
        fit[chain_index+gen_index*chain_num] = zp_old_fit; 
      }
/*
  Update the CR distance.
*/
      if ( ! gr_conv )
      {
        if ( 1 < cr_num )
        {
          cr_dis_update ( chain_index, chain_num, cr_dis, cr_index, 
            cr_num, cr_ups, gen_index, gen_num, par_num, z );
        }
      }

      free ( zp );
    }
/*
  Update the multinomial distribution of CR.
*/
    if ( ! gr_conv )
    {
      if ( 1 < cr_num )
      {
        if ( ( gen_index + 1 ) % 10 == 0 )
        {
          cr_prob_update ( cr_dis, cr_num, cr_prob, cr_ups );
        }
      }
    }
/*
  Every PRINTSTEP interval,
  * compute the Gelman Rubin R statistic for this generation,
    and determine if convergence has occurred.
*/
    if ( ( gen_index + 1 ) % printstep == 0 )
    {
      gr_compute ( chain_num, gen_index, gen_num, gr, gr_conv, gr_count, 
        gr_num, gr_threshold, par_num, z );
    }
/*
  Check for outlier chains.
*/
    if ( ! gr_conv )
    {
      if ( ( gen_index + 1 ) % 10 == 0 )
      {
        chain_outliers ( chain_num, gen_index, gen_num, par_num, fit, z );
      }
    }
  }    
/*
  Compute the acceptance rate.
*/
  zp_accept_rate = ( double ) ( zp_accept ) / ( double ) ( zp_count );

  printf ( "\n" );
  printf ( "  The acceptance rate is %g\n", zp_accept_rate );

  free ( cr );
  free ( cr_dis );
  free ( cr_prob );
  free ( cr_ups );
  free ( zp_old );

  return;
}
/******************************************************************************/

void filename_inc ( char *filename )

/******************************************************************************/
/*
  Purpose:

    FILENAME_INC increments a partially numeric file name.

  Discussion:

    It is assumed that the digits in the name, whether scattered or
    connected, represent a number that is to be increased by 1 on
    each call.  If this number is all 9's on input, the output number
    is all 0's.  Non-numeric letters of the name are unaffected.

    If the name is empty, then the routine stops.

    If the name contains no digits, the empty string is returned.

  Example:

      Input            Output
      -----            ------
      "a7to11.txt"     "a7to12.txt"  (typical case.  Last digit incremented)
      "a7to99.txt"     "a8to00.txt"  (last digit incremented, with carry.)
      "a9to99.txt"     "a0to00.txt"  (wrap around)
      "cat.txt"        " "           (no digits to increment)
      " "              STOP!         (error)

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    22 November 2011

  Author:

    John Burkardt

  Parameters:

    Input/output, char *FILENAME, the filename to be incremented.
*/
{
  int change;
  int n;
  char *t;

  n = strlen ( filename );

  if ( n <= 0 )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "FILENAME_INC - Fatal error!\n" );
    fprintf ( stderr, "  The input string is empty.\n" );
    exit ( 1 );
  }

  change = 0;

  t = filename + n - 1;
  
  while ( 0 < n )
  {
    if ( '0' <= *t && *t <= '9' )
    {
      change = change + 1;

      if ( *t == '9' )
      {
        *t = '0';
      }
      else
      {
        *t = *t + 1;
        return;
      }
    }
    t--;
    n--;
  }
/*
  No digits were found.  Return blank.
*/
  if ( change == 0 )
  {
    n = strlen ( filename );
    t = filename + n - 1;
    while ( 0 < n )
    {
      *t = ' ';
      t--;
      n--;
    }
  }

  return;
}
/******************************************************************************/

void gr_compute ( int chain_num, int gen_index, int gen_num, double gr[], 
  int *gr_conv, int *gr_count, int gr_num, double gr_threshold, int par_num, 
  double z[] )

/******************************************************************************/
/*
  Purpose:

    GR_COMPUTE computes the Gelman Rubin statistics R used to check convergence.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    15 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Reference:

    Jasper Vrugt, CJF ter Braak, CGH Diks, Bruce Robinson, James Hyman, 
    Dave Higdon,
    Accelerating Markov Chain Monte Carlo Simulation by Differential 
    Evolution with Self-Adaptive Randomized Subspace Sampling,
    International Journal of Nonlinear Sciences and Numerical Simulation,
    Volume 10, Number 3, March 2009, pages 271-288.

  Parameters:

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input, int GEN_INDEX, the index of the current generation.
    0 < GEN_INDEX < GEN_NUM.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Output, double GR[PAR_NUM*GR_NUM], the Gelman-Rubin R statistic.

    Output, int *GR_CONV, the Gelman-Rubin convergence flag.

    Input/output, int *GR_COUNT, counts the number of 
    generations at which the Gelman-Rubin statistic has been computed.

    Input, int GR_NUM, the number of times the Gelman-Rubin
    statistic may be computed.

    Input, double GR_THRESHOLD, the convergence tolerance for the
    Gelman-Rubin statistic.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.
*/
{
  double b_var;
  int chain_index;
  int ind0;
  int k;
  double mean_all;
  double *mean_chain;
  int par_index;
  double rnd0;
  double s;
  double s_sum;
  double var;
  double w_var;

  ind0 = ( ( gen_index + 1 ) / 2 ) - 1;
  rnd0 = ( double ) ( ind0 + 1 );

  mean_chain = ( double * ) malloc ( chain_num * sizeof ( double ) );

  for ( par_index = 0; par_index < par_num; par_index++ )
  {
    for ( chain_index = 0; chain_index < chain_num; chain_index++ )
    {
      mean_chain[chain_index] = 0.0;
      for ( k = ind0; k <= gen_index; k++ )
      {
        mean_chain[chain_index] = mean_chain[chain_index] 
          + z[par_index+chain_index*par_num+k*par_num*chain_num];
      }
      mean_chain[chain_index] = mean_chain[chain_index] / rnd0;
    }

    mean_all = r8vec_sum ( chain_num, mean_chain ) / ( double ) chain_num;

    b_var = 0.0;
    for ( chain_index = 0; chain_index < chain_num; chain_index++ )
    {
      b_var = b_var + pow ( mean_chain[chain_index] - mean_all, 2 );
    }
    b_var = rnd0 * b_var / ( double ) ( chain_num - 1 );

    s_sum = 0.0;
    for ( chain_index = 0; chain_index < chain_num; chain_index++ )
    {
      s = 0.0;
      for ( k = ind0; k <= gen_index; k++ )
      {
        s = s + pow ( z[par_index+chain_index*par_num+k*par_num*chain_num] 
          - mean_chain[chain_index], 2 );
      }
      s_sum = s_sum + s;
    }
    s_sum = s_sum / ( rnd0 - 1.0 );

    w_var = s_sum / ( double ) ( chain_num );

    var = ( ( rnd0 - 1.0 ) * w_var + b_var ) / rnd0;

    gr[par_index+(*gr_count)*par_num] = sqrt ( var / w_var );
  }
/*
  Set the convergence flag.
*/
  *gr_conv = 1;

  for ( par_index = 0; par_index < par_num; par_index++ )
  {
    if ( gr_threshold < gr[par_index+(*gr_count)*par_num] )
    {
      *gr_conv = 0;
      break;
    }
  }

  if ( *gr_conv ) 
  {
    printf ( "\n" );
    printf ( "GR_COMPUTE:\n" );
    printf ( "  GR convergence at iteration: %d\n", gen_index );
  }

  free ( mean_chain );

  *gr_count = *gr_count + 1;

  return;
}
/******************************************************************************/

void gr_init ( double gr[], int *gr_conv, int *gr_count, int gr_num, 
  int par_num )

/******************************************************************************/
/*
  Purpose:

    GR_INIT initializes Gelman-Rubin variables.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    15 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Output, double GR[PAR_NUM*GR_NUM], the Gelman-Rubin statistic.

    Output, int *GR_CONV, the convergence flag.

    Output, int *GR_COUNT, counts the number of generations
    at which the Gelman-Rubin statistic has been computed.

    Input, int GR_NUM, the number of times the Gelman-Rubin
    statistic may be computed.

    Input, int PAR_NUM, the number of parameters.
    1 <= PAR_NUM.
*/
{
  int i;
  int j;

  for ( j = 0; j < gr_num; j++ )
  {
    for ( i = 0; i < par_num; i++ )
    {
      gr[i+j*par_num] = 0.0;
    }
  }
  *gr_conv = 0;
  *gr_count = 0;

  return;
}
/******************************************************************************/

void gr_write ( double gr[], char *gr_filename, int gr_num, int par_num, 
  int printstep )

/******************************************************************************/
/*
  Purpose:

    GR_WRITE writes Gelman-Rubin R statistics into a file.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    24 May 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Input, double GR[PAR_NUM*GR_NUM], the Gelman-Rubin R statistic.

    Input, char *GR_FILENAME, the name of the file
    in which values of the Gelman-Rubin statistic will be recorded,
    or NULL if this file is not to be written.

    Input, int GR_NUM, the number of times the Gelman-Rubin
    statistic may be computed.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, int PRINTSTEP, the interval between generations on 
    which the Gelman-Rubin statistic will be computed and written to a file.
*/
{
  FILE *gr_unit;
  int i;
  int j;

  gr_unit = fopen ( gr_filename, "wt" );

  if ( ! gr_unit )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "GR_WRITE - Fatal error!\n" );
    fprintf ( stderr, "  Could not open the file \"%s\"\n", gr_filename );
    exit ( 1 );
  }

  fprintf ( gr_unit, 
    "DREAM.C:Monitored_parameter_interchains_Gelman_Rubin_R_statistic\n" );

  for ( j = 0; j < gr_num; j++ )
  {
    fprintf ( gr_unit, "%d", printstep * ( j + 1 ) - 1 );
    for ( i = 0; i < par_num; i++ )
    {
      fprintf ( gr_unit, "  %f", gr[i+j*par_num] );
    }
    fprintf ( gr_unit, "\n" );
  }

  fclose ( gr_unit );

  printf ( "\n" );
  printf ( "GR_WRITE:\n" );
  printf ( "  Created the file \"%s\".\n", gr_filename );

  return;
}
/******************************************************************************/

void i4mat_print ( int m, int n, int a[], char *title )

/******************************************************************************/
/*
  Purpose:

    I4MAT_PRINT prints an I4MAT.

  Discussion:

    An I4MAT is an MxN array of I4's, stored by (I,J) -> [I+J*M].

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    28 May 2008

  Author:

    John Burkardt

  Parameters:

    Input, int M, the number of rows in A.

    Input, int N, the number of columns in A.

    Input, int A[M*N], the M by N matrix.

    Input, char *TITLE, a title.
*/
{
  i4mat_print_some ( m, n, a, 1, 1, m, n, title );

  return;
}
/******************************************************************************/

void i4mat_print_some ( int m, int n, int a[], int ilo, int jlo, int ihi,
  int jhi, char *title )

/******************************************************************************/
/*
  Purpose:

    I4MAT_PRINT_SOME prints some of an I4MAT.

  Discussion:

    An I4MAT is an MxN array of I4's, stored by (I,J) -> [I+J*M].

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    20 August 2010

  Author:

    John Burkardt

  Parameters:

    Input, int M, the number of rows of the matrix.
    M must be positive.

    Input, int N, the number of columns of the matrix.
    N must be positive.

    Input, int A[M*N], the matrix.

    Input, int ILO, JLO, IHI, JHI, designate the first row and
    column, and the last row and column to be printed.

    Input, char *TITLE, a title.
*/
{
# define INCX 10

  int i;
  int i2hi;
  int i2lo;
  int j;
  int j2hi;
  int j2lo;

  fprintf ( stdout, "\n" );
  fprintf ( stdout, "%s\n", title );

  if ( m <= 0 || n <= 0 )
  {
    fprintf ( stdout, "\n" );
    fprintf ( stdout, "  (None)\n" );
    return;
  }
/*
  Print the columns of the matrix, in strips of INCX.
*/
  for ( j2lo = jlo; j2lo <= jhi; j2lo = j2lo + INCX )
  {
    j2hi = j2lo + INCX - 1;
    j2hi = i4_min ( j2hi, n );
    j2hi = i4_min ( j2hi, jhi );

    fprintf ( stdout, "\n" );
/*
  For each column J in the current range...

  Write the header.
*/
    fprintf ( stdout, "  Col:" );
    for ( j = j2lo; j <= j2hi; j++ )
    {
      fprintf ( stdout, "  %6d", j - 1 );
    }
    fprintf ( stdout, "\n" );
    fprintf ( stdout, "  Row\n" );
    fprintf ( stdout, "\n" );
/*
  Determine the range of the rows in this strip.
*/
    i2lo = i4_max ( ilo, 1 );
    i2hi = i4_min ( ihi, m );

    for ( i = i2lo; i <= i2hi; i++ )
    {
/*
  Print out (up to INCX) entries in row I, that lie in the current strip.
*/
      fprintf ( stdout, "%5d:", i - 1 );
      for ( j = j2lo; j <= j2hi; j++ )
      {
        fprintf ( stdout, "  %6d", a[i-1+(j-1)*m] );
      }
      fprintf ( stdout, "\n" );
    }
  }

  return;
# undef INCX
}
/******************************************************************************/

void i4vec_transpose_print ( int n, int a[], char *title )

/******************************************************************************/
/*
  Purpose:

    I4VEC_TRANSPOSE_PRINT prints an I4VEC "transposed".

  Discussion:

    An I4VEC is a vector of I4's.

  Example:

    A = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
    TITLE = "My vector:  "

    My vector:      1    2    3    4    5
                    6    7    8    9   10
                   11

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    13 December 2012

  Author:

    John Burkardt

  Parameters:

    Input, int N, the number of components of the vector.

    Input, int A[N], the vector to be printed.

    Input, char *TITLE, a title.
*/
{
  int i;
  int ihi;
  int ilo;
  int title_len;

  title_len = strlen ( title );

  for ( ilo = 1; ilo <= n; ilo = ilo + 5 )
  {
    ihi = i4_min ( ilo + 5 - 1, n );
    if ( ilo == 1 )
    {
      printf ( "%s", title );
    }
    else
    {
      for ( i = 1; i <= title_len; i++ )
      {
        printf ( " " );
      }
    }
    for ( i = ilo; i <= ihi; i++ )
    {
      printf ( "%12d", a[i-1] );
    }
    printf ( "\n" );
  }

  return;
}
/******************************************************************************/

int *i4vec_zero_new ( int n )

/******************************************************************************/
/*
  Purpose:

    I4VEC_ZERO_NEW creates and zeroes an I4VEC.

  Discussion:

    An I4VEC is a vector of I4's.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    05 September 2008

  Author:

    John Burkardt

  Parameters:

    Input, int N, the number of entries in the vector.

    Output, int I4VEC_ZERO_NEW[N], a vector of zeroes.
*/
{
  int *a;
  int i;

  a = ( int * ) malloc ( n * sizeof ( int ) );

  for ( i = 0; i < n; i++ )
  {
    a[i] = 0;
  }
  return a;
}
/******************************************************************************/

void input_print ( char *chain_filename, int chain_num, int cr_num, 
  char *gr_filename, double gr_threshold, int jumpstep, double limits[], 
  int gen_num, int pair_num, int par_num, int printstep, 
  char *restart_read_filename, char *restart_write_filename )

/******************************************************************************/
/*
  Purpose:

    INPUT_PRINT prints the data from the input file.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    26 May 2013

  Author:

    John Burkardt

  Parameters:

    Input, char *CHAIN_FILENAME, the "base" filename
    to be used for the chain files.  If this is NULL
    then the chain files will not be written.  This name should 
    include a string of 0's which will be replaced by the chain 
    indices.  For example, "chain000.txt" would work as long as the
    number of chains was 1000 or less.

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input, int CR_NUM, the total number of CR values.
    1 <= CR_NUM.

    Input, char *GR_FILENAME, the name of the file
    in which values of the Gelman-Rubin statistic will be recorded,
    or NULL if this file is not to be written.

    Input, double GR_THRESHOLD, the convergence tolerance for the
    Gelman-Rubin statistic.

    Input, int JUMPSTEP, forces a "long jump" every
    JUMPSTEP generations.

    Input, double LIMITS[2*PAR_NUM], lower and upper limits
    for each parameter.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, int PAIR_NUM, the number of pairs of 
    crossover chains.
    0 <= PAIR_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, int PRINTSTEP, the interval between generations on 
    which the Gelman-Rubin statistic will be computed and written to a file.

    Input, char *RESTART_READ_FILENAME, the name of the file
    containing restart information.  If this calculation is not a restart,
    then this should be NULL.

    Input, char *RESTART_WRITE_FILENAME, the name of the file
    to be written, containing restart information.  If a restart file is not
    to be written, this should be NULL.
*/
{
  int j;

  printf ( "\n" );
  printf ( "INPUT_PRINT:\n" );
  printf ( "\n" );
  printf ( "  Number of parameters\n" );
  printf ( "  PAR_NUM = %d\n", par_num );
  printf ( "\n" );
  printf ( "  LIMITS: Lower and upper limits for each parameter:\n" );
  printf ( "\n" );
  printf ( "  Index           Lower           Upper\n" );
  printf ( "\n" );
  for ( j = 0; j < par_num; j++ )
  {
    printf ( "  %5d  %14.6g  %14.6g\n", j, limits[0+j*2], limits[1+j*2] );
  }
  printf ( "\n" );
  printf ( "  Number of generations:\n" );
  printf ( "  GEN_NUM = %d\n", gen_num );
  printf ( "\n" );
  printf ( "  Number of simultaneous chains:\n" );
  printf ( "  CHAIN_NUM = %d\n", chain_num );
  printf ( "\n" );
  printf ( "  Chain filename base:\n" );
  if ( chain_filename )
  {
    printf ( "  CHAIN_FILENAME = \"%s\"\n", chain_filename );
  }
  else
  {
    printf ( "  CHAIN_FILENAME = \"(Null)\"\n" );
  }
  printf ( "\n" );
  printf ( "  Number of pairs of chains for crossover:\n" );
  printf ( "  PAIR_NUM = %d\n", pair_num );
  printf ( "\n" );
  printf ( "  Number of crossover values:\n" );
  printf ( "  CR_NUM = %d\n", cr_num );
  printf ( "\n" );
  printf ( "  Number of steps til a long jump:\n" );
  printf ( "  JUMPSTEP = %d\n", jumpstep );
  printf ( "\n" );
  printf ( "  Interval between Gelman-Rubin computations:\n" );
  printf ( "  PRINTSTEP = %d\n", printstep );
  printf ( "\n" );
  printf ( "  Gelman-Rubin data filename:\n" );
  if ( gr_filename )
  {
    printf ( "  GR_FILENAME = \"%s\"\n", gr_filename );
  }
  else
  {
    printf ( "  GR_FILENAME = \"(Null)\"\n" );
  }
  printf ( "\n" );
  printf ( "  Gelman-Rubin convergence tolerance:\n" );
  printf ( "  GR_THRESHOLD = %g\n", gr_threshold );
  printf ( "\n" );
  printf ( "  Restart read filename:\n" );
  if ( restart_read_filename )
  {
    printf ( "  RESTART_READ_FILENAME = \"%s\"\n", restart_read_filename );
  }
  else
  {
    printf ( "  RESTART_READ_FILENAME = \"(Null)\"\n" );
  }
  printf ( "\n" );
  printf ( "  Restart write filename:\n" );
  if ( restart_write_filename )
  {
    printf ( "  RESTART_WRITE_FILENAME = \"%s\"\n", restart_write_filename );
  }
  else
  {
    printf ( "  RESTART_WRITE_FILENAME = \"(Null)\"\n" );
  }

  return;
}
/******************************************************************************/

void jumprate_choose ( double cr[], int cr_index, int cr_num, int gen_index,
  int jump_dim[], int *jump_num, double *jumprate, double jumprate_table[],
  int jumpstep, int par_num )

/******************************************************************************/
/*
  Purpose:

    JUMPRATE_CHOOSE chooses a jump rate from the jump rate table.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    29 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Reference:

    Jasper Vrugt, CJF ter Braak, CGH Diks, Bruce Robinson, James Hyman, 
    Dave Higdon,
    Accelerating Markov Chain Monte Carlo Simulation by Differential 
    Evolution with Self-Adaptive Randomized Subspace Sampling,
    International Journal of Nonlinear Sciences and Numerical Simulation,
    Volume 10, Number 3, March 2009, pages 271-288.

  Parameters:

    Input, double CR[CR_NUM], the CR values.

    Input, int CR_INDEX, the index of the CR.
    1 <= CR_INDEX <= CR_NUM.

    Input, int CR_NUM, the total number of CR values.
    1 <= CR_NUM.

    Input, int GEN_INDEX, the current generation.
    1 <= GEN_INDEX <= GEN_NUM.

    Output, int JUMP_DIM[PAR_NUM], the indexes of the
    parameters to be updated.

    Output, int *JUMP_NUM, the number of dimensions in which
    a jump will be made.  0 <= JUMP_NUM <= PAR_NUM.

    Output, double *JUMPRATE, the jump rate.

    Input, double JUMPRATE_TABLE[PAR_NUM], the jump rate table.

    Input, int JUMPSTEP, forces a "long jump" every
    JUMPSTEP generations.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.
*/
{
  int i;
  double r;
/*
  Determine the dimensions that will be updated.
*/
  *jump_num = 0;
  for ( i = 0; i < par_num; i++ )
  {
    jump_dim[i] = 0;
  }

  for ( i = 0; i < par_num; i++ )
  {
    r = r8_uniform_01_sample ( );

    if ( 1.0 - cr[cr_index] < r )
    {
      jump_dim[*jump_num] = i;
      *jump_num = *jump_num + 1;
    }
  }
/*
  Calculate the general jump rate.
*/
  if ( *jump_num == 0 )
  {
    *jumprate = 0.0;
  }
  else
  {
    *jumprate = jumprate_table[*jump_num-1];
  }
/*
  If parameter dimension is 1, 2, or 3, fix the jump rate to 0.6.
*/
  if ( par_num <= 3 )
  {
    *jumprate = 0.6;
  }
/*
  Determine if a long jump is forced.
*/
  if ( ( gen_index % jumpstep ) == 0 )
  {
    *jumprate = 0.98;
  }
  return;
}
/******************************************************************************/

double *jumprate_table_init ( int pair_num, int par_num )

/******************************************************************************/
/*
  Purpose:

    JUMPRATE_TABLE_INIT initializes the jump rate table.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    14 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Input, int PAIR_NUM, the number of pairs of 
    crossover chains.
    0 <= PAIR_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Output, double JUMPRATE_TABLE_INIT[PAR_NUM], the jumprate table.
*/
{
  double c;
  int i;
  double *jumprate_table;
 
  jumprate_table = ( double * ) malloc ( par_num * sizeof ( double ) );

  c = 2.38 / sqrt ( ( double ) ( 2 * pair_num ) );

  for ( i = 0; i < par_num; i++ )
  {
    jumprate_table[i] = c / sqrt ( ( double ) ( i + 1 ) );
  }

  return jumprate_table;
}
/******************************************************************************/

void jumprate_table_print ( double jumprate_table[], int pair_num, int par_num )

/******************************************************************************/
/*
  Purpose:

    JUMPRATE_TABLE_PRINT prints the jump rate table.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    14 April 2013

  Author:

    John Burkardt

  Parameters:

    Input, double JUMPRATE_TABLE[PAR_NUM], the jumprate table.

    Input, int PAIR_NUM, the number of pairs of 
    crossover chains.
    0 <= PAIR_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.
*/
{
  int i;
 
  printf ( "\n" );
  printf ( "JUMPRATE_TABLE_PRINT\n" );
  printf ( "\n" );
  printf ( "   I        Jumprate\n" );
  printf ( "\n" );
  for ( i = 0; i < par_num; i++ )
  {
    printf ( "  %2d  %14.6g\n", i, jumprate_table[i] );
  }
  return;
}
/******************************************************************************/

int r8_round_i4 ( double x )

/******************************************************************************/
/*
  Purpose:

    R8_ROUND_I4 rounds an R8, returning an I4.

  Example:

        X         Value

      1.3         1
      1.4         1
      1.5         1 or 2
      1.6         2
      0.0         0
     -0.7        -1
     -1.1        -1
     -1.6        -2

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    25 March 2013

  Author:

    John Burkardt

  Parameters:

    Input, double X, the value.

    Output, int R8_ROUND_I4, the rounded value.
*/
{
  int value;

  if ( x < 0.0 )
  {
    value = - floor ( - x + 0.5 );
  }
  else
  {
    value =   floor (   x + 0.5 );
  }

  return value;
}
/******************************************************************************/

double *r8block_zero_new ( int l, int m, int n )

/******************************************************************************/
/*
  Purpose:

    R8BLOCK_ZERO_NEW returns a new zeroed R8BLOCK.

  Discussion:

    An R8BLOCK is a triple dimensioned array of R8 values, stored as a vector
    in column-major order.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    13 April 2013

  Author:

    John Burkardt

  Parameters:

    Input, int L, M, N, the number of rows, columns, and levels.

    Output, double R8BLOCK_ZERO_NEW[L*M*N], the new zeroed matrix.
*/
{
  double *a;
  int i;
  int j;
  int k;

  a = ( double * ) malloc ( l * m * n * sizeof ( double ) );

  for ( k = 0; k < n; k++ )
  {
    for ( j = 0; j < m; j++ )
    {
      for ( i = 0; i < l; i++ )
      {
        a[i+j*l+k*l*m] = 0.0;
      }
    }
  }
  return a;
}
/******************************************************************************/

double *r8mat_zero_new ( int m, int n )

/******************************************************************************/
/*
  Purpose:

    R8MAT_ZERO_NEW returns a new zeroed R8MAT.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    26 September 2008

  Author:

    John Burkardt

  Parameters:

    Input, int M, N, the number of rows and columns.

    Output, double R8MAT_ZERO_NEW[M*N], the new zeroed matrix.
*/
{
  double *a;
  int i;
  int j;

  a = ( double * ) malloc ( m * n * sizeof ( double ) );

  for ( j = 0; j < n; j++ )
  {
    for ( i = 0; i < m; i++ )
    {
      a[i+j*m] = 0.0;
    }
  }
  return a;
}
/******************************************************************************/

double *r8vec_copy_new ( int n, double a1[] )

/******************************************************************************/
/*
  Purpose:

    R8VEC_COPY_NEW copies an R8VEC.

  Discussion:

    An R8VEC is a vector of R8's.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    26 August 2008

  Author:

    John Burkardt

  Parameters:

    Input, int N, the number of entries in the vectors.

    Input, double A1[N], the vector to be copied.

    Output, double R8VEC_COPY_NEW[N], the copy of A1.
*/
{
  double *a2;
  int i;

  a2 = ( double * ) malloc ( n * sizeof ( double ) );

  for ( i = 0; i < n; i++ )
  {
    a2[i] = a1[i];
  }
  return a2;
}
/******************************************************************************/

void r8vec_heap_d ( int n, double a[] )

/******************************************************************************/
/*
  Purpose:

    R8VEC_HEAP_D reorders an R8VEC into a descending heap.

  Discussion:

    An R8VEC is a vector of R8's.

    A heap is an array A with the property that, for every index J,
    A[J] >= A[2*J+1] and A[J] >= A[2*J+2], (as long as the indices
    2*J+1 and 2*J+2 are legal).

  Diagram:

                  A(0)
                /      \
            A(1)         A(2)
          /     \        /  \
      A(3)       A(4)  A(5) A(6)
      /  \       /   \
    A(7) A(8)  A(9) A(10)

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    31 May 2009

  Author:

    John Burkardt

  Reference:

    Albert Nijenhuis, Herbert Wilf,
    Combinatorial Algorithms,
    Academic Press, 1978, second edition,
    ISBN 0-12-519260-6.

  Parameters:

    Input, int N, the size of the input array.

    Input/output, double A[N].
    On input, an unsorted array.
    On output, the array has been reordered into a heap.
*/
{
  int i;
  int ifree;
  double key;
  int m;
/*
  Only nodes (N/2)-1 down to 0 can be "parent" nodes.
*/
  for ( i = (n/2)-1; 0 <= i; i-- )
  {
/*
  Copy the value out of the parent node.
  Position IFREE is now "open".
*/
    key = a[i];
    ifree = i;

    for ( ; ; )
    {
/*
  Positions 2*IFREE + 1 and 2*IFREE + 2 are the descendants of position
  IFREE.  (One or both may not exist because they equal or exceed N.)
*/
      m = 2 * ifree + 1;
/*
  Does the first position exist?
*/
      if ( n <= m )
      {
        break;
      }
      else
      {
/*
  Does the second position exist?
*/
        if ( m + 1 < n )
        {
/*
  If both positions exist, take the larger of the two values,
  and update M if necessary.
*/
          if ( a[m] < a[m+1] )
          {
            m = m + 1;
          }
        }
/*
  If the large descendant is larger than KEY, move it up,
  and update IFREE, the location of the free position, and
  consider the descendants of THIS position.
*/
        if ( key < a[m] )
        {
          a[ifree] = a[m];
          ifree = m;
        }
        else
        {
          break;
        }
      }
    }
/*
  When you have stopped shifting items up, return the item you
  pulled out back to the heap.
*/
    a[ifree] = key;
  }

  return;
}
/******************************************************************************/

void r8vec_sort_heap_a ( int n, double a[] )

/******************************************************************************/
/*
  Purpose:

    R8VEC_SORT_HEAP_A ascending sorts an R8VEC using heap sort.

  Discussion:

    An R8VEC is a vector of R8's.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    31 May 2009

  Author:

    John Burkardt

  Reference:

    Albert Nijenhuis, Herbert Wilf,
    Combinatorial Algorithms,
    Academic Press, 1978, second edition,
    ISBN 0-12-519260-6.

  Parameters:

    Input, int N, the number of entries in the array.

    Input/output, double A[N].
    On input, the array to be sorted;
    On output, the array has been sorted.
*/
{
  int n1;
  double temp;

  if ( n <= 1 )
  {
    return;
  }
/*
  1: Put A into descending heap form.
*/
  r8vec_heap_d ( n, a );
/*
  2: Sort A.

  The largest object in the heap is in A[0].
  Move it to position A[N-1].
*/
  temp = a[0];
  a[0] = a[n-1];
  a[n-1] = temp;
/*
  Consider the diminished heap of size N1.
*/
  for ( n1 = n - 1; 2 <= n1; n1-- )
  {
/*
  Restore the heap structure of the initial N1 entries of A.
*/
    r8vec_heap_d ( n1, a );
/*
  Take the largest object from A[0] and move it to A[N1-1].
*/
    temp = a[0];
    a[0] = a[n1-1];
    a[n1-1] = temp;
  }

  return;
}
/******************************************************************************/

double r8vec_sum ( int n, double a[] )

/******************************************************************************/
/*
  Purpose:

    R8VEC_SUM returns the sum of an R8VEC.

  Discussion:

    An R8VEC is a vector of R8's.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    26 August 2008

  Author:

    John Burkardt

  Parameters:

    Input, int N, the number of entries in the vector.

    Input, double A[N], the vector.

    Output, double R8VEC_SUM, the sum of the vector.
*/
{
  int i;
  double value;

  value = 0.0;
  for ( i = 0; i < n; i++ )
  {
    value = value + a[i];
  }

  return value;
}
/******************************************************************************/

void r8vec_transpose_print ( int n, double a[], char *title )

/******************************************************************************/
/*
  Purpose:

    R8VEC_TRANSPOSE_PRINT prints an R8VEC "transposed".

  Discussion:

    An R8VEC is a vector of R8's.

  Example:

    A = (/ 1.0, 2.1, 3.2, 4.3, 5.4, 6.5, 7.6, 8.7, 9.8, 10.9, 11.0 /)
    TITLE = 'My vector:  '

    My vector:

        1.0    2.1    3.2    4.3    5.4
        6.5    7.6    8.7    9.8   10.9
       11.0

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    12 November 2010

  Author:

    John Burkardt

  Parameters:

    Input, int N, the number of components of the vector.

    Input, double A[N], the vector to be printed.

    Input, char *TITLE, a title.
*/
{
  int i;
  int ihi;
  int ilo;

  printf ( "\n" );
  printf ( "%s\n", title );
  printf ( "\n" );

  if ( n <= 0 )
  {
    printf ( "  (Empty)\n" );
    return;
  }

  for ( ilo = 0; ilo < n; ilo = ilo + 5 )
  {
    ihi = i4_min ( ilo + 5, n );
    for ( i = ilo; i < ihi; i++ )
    {
      printf ( "  %12g", a[i] );
    }
    printf ( "\n" );
  }

  return;
}
/******************************************************************************/

double *r8vec_zero_new ( int n )

/******************************************************************************/
/*
  Purpose:

    R8VEC_ZERO_NEW creates and zeroes an R8VEC.

  Discussion:

    An R8VEC is a vector of R8's.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    25 March 2009

  Author:

    John Burkardt

  Parameters:

    Input, int N, the number of entries in the vector.

    Output, double R8VEC_ZERO_NEW[N], a vector of zeroes.
*/
{
  double *a;
  int i;

  a = ( double * ) malloc ( n * sizeof ( double ) );

  for ( i = 0; i < n; i++ )
  {
    a[i] = 0.0;
  }
  return a;
}
/******************************************************************************/

void restart_read ( int chain_num, double fit[], int gen_num, int par_num, 
  char *restart_read_filename, double z[] )

/******************************************************************************/
/*
  Purpose:

    RESTART_READ reads parameter sample data from a restart file.

  Discussion:

    Only a single generation (presumably the last one) was written to the file.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    13 May 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Output, double FIT[CHAIN_NUM*GEN_NUM], the likelihood of
    each sample.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, char *RESTART_READ_FILENAME, the name of 
    the restart file.

    Output, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.
*/
{
  int chain_index;
  int gen_index;
  int index;
  int k;
  char *line;
  size_t n;
  int par_index;
  FILE *restart_unit;

  n = 255;
  line = ( char * ) malloc ( n + 1 );

  restart_unit = fopen ( restart_read_filename, "rt" );

  if ( ! restart_unit )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "RESTART_READ - Fatal error!\n" );
    fprintf ( stderr, "  Could not open the file \"%s\".\n",
      restart_read_filename );
    exit ( 1 );
  }
/*
  Assume only one generation.
*/
  gen_index = 0;
/*
  Read and ignore line 1.
*/
  fgets ( line, 255, restart_unit );

  for ( chain_index = 0; chain_index < chain_num; chain_index++ )
  {
    index = chain_index+chain_num*gen_index;
    fscanf ( restart_unit, "%d%lf", &k, fit+index );
    for ( par_index = 0; par_index < par_num; par_index++ )
    {
      index = par_index+par_num*chain_index+par_num*chain_num*gen_index;
      fscanf ( restart_unit, "%lf", z+index );
    }
  }

  fclose ( restart_unit );

  free ( line );

  return;
}
/******************************************************************************/

void restart_write ( int chain_num, double fit[], int gen_num, int par_num, 
  char *restart_write_filename, double z[] )

/******************************************************************************/
/*
  Purpose:

    RESTART_WRITE writes a restart file.

  Discussion:

    Only data for the final generation is written.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    23 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input, double FIT[CHAIN_NUM*GEN_NUM], the likelihood of
    each sample.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, char *RESTART_WRITE_FILENAME, the name of the 
    restart file.

    Input, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.
*/
{
  int c;
  int p;
  FILE *restart_unit;

  restart_unit = fopen ( restart_write_filename, "wt" );   

  if ( !restart_unit )
  {
    fprintf ( stderr, "\n" );
    fprintf ( stderr, "RESTART_WRITE - Fatal error!\n" );
    fprintf ( stderr, 
      "  Could not open the file \"%s\".\n", restart_write_filename );
    exit ( 1 );
  }

  fprintf ( restart_unit, "DREAM.C:Parameter_values_for_restart.\n" );

  for ( c = 0; c < chain_num; c++ )
  {
    fprintf ( restart_unit, "%d  %14.7g", c, fit[c+(gen_num-1)*chain_num] );
    for ( p = 0; p < par_num; p++ )
    {
      fprintf ( restart_unit, "  %14.7g", 
        z[p+c*par_num+(gen_num-1)*par_num*chain_num] );
    }
    fprintf ( restart_unit, "\n" ); 
  }

  fclose ( restart_unit );

  printf ( "\n" );
  printf ( "RESTART_WRITE:\n" );
  printf ( "  Created restart file \"%s\".\n", restart_write_filename );

  return;
}
/******************************************************************************/

double *sample_candidate ( int chain_index, int chain_num, double cr[], 
  int cr_index, int cr_num, int gen_index, int gen_num, 
  double jumprate_table[], int jumpstep, double limits[], int pair_num, 
  int par_num, double z[] )

/******************************************************************************/
/*
  Purpose:

    SAMPLE_CANDIDATE generates candidate parameter samples.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    30 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Reference:

    Jasper Vrugt, CJF ter Braak, CGH Diks, Bruce Robinson, James Hyman, 
    Dave Higdon,
    Accelerating Markov Chain Monte Carlo Simulation by Differential 
    Evolution with Self-Adaptive Randomized Subspace Sampling,
    International Journal of Nonlinear Sciences and Numerical Simulation,
    Volume 10, Number 3, March 2009, pages 271-288.

  Parameters:

    Input, int CHAIN_INDEX, the chain index.
    0 <= CHAIN_INDEX < CHAIN_NUM.

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input, double CR[CR_NUM], the CR values.

    Input, int CR_INDEX, the index of the chosen CR value.
    0 <= CR_INDEX < CR_NUM.

    Input, int CR_NUM, the total number of CR values.
    1 <= CR_NUM.

    Input, int GEN_INDEX, the current generation.
    0 <= GEN_INDEX < GEN_NUM.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, double JUMPRATE_TABLE[PAR_NUM], the jumprate table.

    Input, int JUMPSTEP, forces a "long jump" every
    JUMPSTEP generations.

    Input, double LIMITS[2*PAR_NUM], limits for the parameters.

    Input, int PAIR_NUM, the number of pairs of 
    crossover chains.
    0 <= PAIR_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.

    Output, double SAMPLE_CANDIDATE[PAR_NUM], a candidate parameter sample.

  Local parameters:

    Local, int JUMP_DIM[JUMP_NUM], the dimensions in which
    a jump is to be made.

    Local, int JUMP_NUM, the number of dimensions in which
    a jump will be made.  0 <= JUMP_NUM <= PAR_NUM.

    Local, double JUMPRATE, the jump rate.
*/
{
  double av;
  double b;
  double *diff;
  double *eps;
  int i;
  int *jump_dim;
  int jump_num;
  double jumprate;
  double *noise_e;
  int pair[2];
  int *r;
  double r2;
  double sd;
  double *zp;
/*
  Used to calculate E following a uniform distribution on (-B,+B).
  Because B is currently zero, the noise term is suppressed.
*/
  b = 0.0;
/*
  Pick pairs of other chains for crossover.
*/
  r = ( int * ) malloc ( 2 * pair_num * sizeof ( int ) );

  for ( i = 0; i < pair_num; i++ )
  {
    while ( 1 )
    {
      r2 = r8_uniform_01_sample ( );
      pair[0] = ( int ) ( r2 * ( double ) chain_num );
      r2 = r8_uniform_01_sample ( );
      pair[1] = ( int ) ( r2 * ( double ) chain_num );

      if ( pair[0] != pair[1] &&
           pair[0] != chain_index && 
           pair[1] != chain_index )
      {
        break;
      }
    }
    r[0+i*2] = pair[0];
    r[1+i*2] = pair[1];
  }
/*
  Determine the jump rate.
*/
  jump_dim = ( int * ) malloc ( par_num * sizeof ( int ) );

  jumprate_choose ( cr, cr_index, cr_num, gen_index, jump_dim, &jump_num, 
    &jumprate, jumprate_table, jumpstep, par_num );
/*
  Calculate E in equation 4 of Vrugt.
*/
  noise_e = ( double * ) malloc ( par_num * sizeof ( noise_e ) );

  for ( i = 0; i < par_num; i++ )
  {
    noise_e[i] = b * ( 2.0 * r8_uniform_01_sample ( ) - 1.0 );
  }
/*
  Get epsilon value from multinormal distribution                      
*/
  eps = ( double * ) malloc ( par_num * sizeof ( double ) );

  av = 0.0;
  sd = 1.0E-10;
  for ( i = 0; i < par_num; i++ )
  {
    eps[i] = r8_normal_sample ( av, sd );
  }
/*
  Generate the candidate sample ZP based on equation 4 of Vrugt.
*/
  diff = diff_compute ( chain_num, gen_index, gen_num, jump_dim, jump_num, 
    pair_num, par_num, r, z );

  zp = ( double * ) malloc ( par_num * sizeof ( double ) );

  for ( i = 0; i < par_num; i++ )
  {
    zp[i] = z[i+chain_index*par_num+(gen_index-1)*par_num*chain_num];
  }
  for ( i = 0; i < par_num; i++ )
  {
    zp[i] = zp[i] + ( 1.0 + noise_e[i] ) * jumprate * diff[i] + eps[i];
  }
/*
  Enforce limits on the sample ZP.
*/
  sample_limits ( limits, par_num, zp );

  free ( diff );
  free ( eps );
  free ( jump_dim );
  free ( noise_e );
  free ( r );

  return zp;
}
/******************************************************************************/

void sample_limits ( double limits[], int par_num, double zp[] )

/******************************************************************************/
/*
  Purpose:

    SAMPLE_LIMITS enforces limits on a sample variable.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    29 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Input, double LIMITS[2*PAR_NUM], the parameter limits.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input/output, double ZP[PAR_NUM], a variable, whose entries,
    if necessary, will be "folded" so that they lie within the limits.
*/
{
  int i;
  double w;

  for ( i = 0; i < par_num; i++ )
  {
    w = limits[1+i*2] - limits[0+i*2];

    if ( w == 0.0 )
    {
      zp[i] = limits[0+i*2];
    }
    else if ( w < 0.0 )
    {
      fprintf ( stderr, "\n" );
      fprintf ( stderr, "SAMPLE_LIMITS - Fatal error!\n" );
      fprintf ( stderr, "  Upper limit less than lower limit.\n" );
      exit ( 1 );
    }
    else
    {
      while ( zp[i] < limits[0+i*2] )
      {
        zp[i] = zp[i] + w;
      }
      while ( limits[1+i*2] < zp[i] )
      {
        zp[i] = zp[i] - w;
      }
    }
  }
  return;
}
/******************************************************************************/

double *std_compute ( int chain_num, int gen_index, int gen_num, int par_num, 
  double z[] )

/******************************************************************************/
/*
  Purpose:

    STD_COMPUTE computes the current standard deviations, for each parameter.

  Discussion:

    The computation encompasses all chains and generations up to the
    current ones.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    14 April 2013

  Author:

    Original FORTRAN90 version by Guannan Zhang.
    C version by John Burkardt.

  Parameters:

    Input, int CHAIN_NUM, the total number of chains.
    3 <= CHAIN_NUM.

    Input, int GEN_INDEX, the current generation.
    0 <= GEN_INDEX < GEN_NUM.

    Input, int GEN_NUM, the total number of generations.
    2 <= GEN_NUM.

    Input, int PAR_NUM, the total number of parameters.
    1 <= PAR_NUM.

    Input, double Z[PAR_NUM*CHAIN_NUM*GEN_NUM], the Markov chain 
    sample data.

    Output, double STD_COMPUTE[PAR_NUM], the standard deviations.
*/
{
  int i;
  int j;
  int k;
  double mean;
  double *std;

  std = ( double * ) malloc ( par_num * sizeof ( double ) );

  for ( i = 0; i < par_num; i++ )
  {
    mean = 0.0;
    for ( k = 0; k <= gen_index; k++ )
    {
      for ( j = 0; j < chain_num; j++ )
      {
        mean = mean + z[i+j*par_num+k*par_num*chain_num];
      }
    }
    mean = mean / ( double ) ( chain_num ) / ( double ) ( gen_index );

    std[i] = 0.0;
    for ( k = 0; k <= gen_index; k++ )
    {
      for ( j = 0; j < chain_num; j++ )
      {
        std[i] = std[i] + pow ( z[i+j*par_num+k*par_num*chain_num] - mean, 2 );
      }
    }
    std[i] = sqrt ( std[i] / ( double ) ( chain_num * gen_index - 1 ) );
  }

  return std;
}