//===================================================== file = parity.c =====
//=  A simulation of the effectiveness of parity for error detection        =
//=   - Correlation of bit errors is included in this model                 =
//===========================================================================
//=  Notes:                                                                 =
//=    1) #define NUM_WORD tunes the execution time                         =
//=    2) Maximum word size is 100 bits (includeing parity bit)             =
//=    3) Assume word is received and that parity can detect only an odd    =
//=       number of errors                                                  =
//=    4) The "factor" input allows for modeling of correlation.  Given     =
//=       a bit error, the next bit has factor * p probability of being     =
//=       in error.                                                         =
//=-------------------------------------------------------------------------=
//= Example execution:                                                      =
//=                                                                         =
//=  Enter number of bits in a word =====================> 4                =
//=  Enter probability of a bit error ===================> 0.01             =
//=  Enter correlation factor (1.0 for independent) =====> 1.0              =
//=  --------------------------------------------- parity.c -----           =
//=  -  Results for 10000000 iterations...                                  =
//=  -    Pr[no error]            = 0.9605554                               =
//=  -    Pr[error]               = 0.0394446                               =
//=  -    Pr[detetable error]     = 0.0388776                               =
//=  -    Pr[undetectable error]  = 0.0005670                               =
//=  -                                                                      =
//=  -    Pr[ 0] bit errors       = 0.9605554                               =
//=  -    Pr[ 1] bit errors       = 0.0388740                               =
//=  -    Pr[ 2] bit errors       = 0.0005670                               =
//=  -    Pr[ 3] bit errors       = 0.0000036                               =
//=  -    Pr[ 4] bit errors       = 0.0000000                               =
//=  ------------------------------------------------------------           =
//=-------------------------------------------------------------------------=
//=  Build: bcc32 parity.c                                                  =
//=-------------------------------------------------------------------------=
//=  Execute: parity                                                        =
//=-------------------------------------------------------------------------=
//=  Author: Kenneth J. Christensen                                         =
//=          University of South Florida                                    =
//=          WWW: http://www.csee.usf.edu/~christen                         =
//=          Email: christen@csee.usf.edu                                   =
//=-------------------------------------------------------------------------=
//=  History: KJC (01/20/00) - Genesis                                      =
//=           KJC (02/04/00) - Fixed bug with not considering "last bit"    =
//=                            in computation of pr_det and pr_undet        =
//=           KJC (08/16/02) - Clarified section computing correlated       =
//=                            errors                                       =
//===========================================================================

//----- Include files -------------------------------------------------------
#include <stdio.h>                 // Needed for printf()
#include <stdlib.h>                // Needed for rand(), RAND_MAX, and ato*()

//----- Defines -------------------------------------------------------------
#define TRUE                    1  // Boolean true
#define FALSE                   0  // Boolean false
#define NUM_WORD         10000000  // Number of words to simulate

//===== Main program ========================================================
void main(void)
{
  int      N;                        // Number of bits in word
  double   p;                        // Probability of bit error
  double   factor;                   // Factor affecting subsequent bit
  int      error[4096];              // Error count vector
  int      error_count;              // Error count for an iteration
  int      error_flag;               // Flag that last bit was in error
  double   pr_noerr;                 // Probability of no error
  double   pr_det;                   // Probability of detectable error
  double   pr_undet;                 // Probability of undetectable error
  double   z;                        // Uniform RV between 0.0 and 1.0
  char     temp_string[80];          // Temporary string
  int      i, j;                     // Loop counters

  // Prompt for number of bits in a word (N)
  printf("Enter number of bits in a word =====================> ");
  scanf("%s", temp_string);
  N = atoi(temp_string);

  // Prompt for probability of a bit error (p)
  printf("Enter probability of a bit error ===================> ");
  scanf("%s", temp_string);
  p = atof(temp_string);

  // Prompt for correlation "factor" (factor)
  printf("Enter correlation factor (1.0 for independent) =====> ");
  scanf("%s", temp_string);
  factor = atof(temp_string);

  // Clear the error count vector
  for (i=0; i<=N; i++)
    error[i] = 0;

  // Simulate for NUM_WORD words
  for (i=0; i<NUM_WORD; i++)
  {
    error_count = 0;
    error_flag = FALSE;
    for (j=0; j<N; j++)
    {
      // Pull a uniform RV between 0 and 1
      z = (double) rand() / RAND_MAX;

      // Determine if this bit is in error
      if (error_flag == FALSE)
      {
        if (z < p)
        {
          error_count++;
          error_flag = TRUE;
        }
        else
          error_flag = FALSE;
      }
      else if (error_flag == TRUE)
      {
        if (z < (factor * p))
        {
          error_count++;
          error_flag = TRUE;
        }
        else
          error_flag = FALSE;
      }
    }

    // Increment the appropriate error[] value
    error[error_count]++;
  }

  // Compute probabilities of interest
  pr_noerr = ((double) error[0] / NUM_WORD);
  pr_det = pr_undet = 0.0;
  for (i=1; i<=N; i=i+2)
    pr_det = pr_det + ((double) error[i] / NUM_WORD);
  for (i=2; i<=N; i=i+2)
    pr_undet = pr_undet + ((double) error[i] / NUM_WORD);

  // Output the results
  printf("--------------------------------------------- parity.c ----- \n");
  printf("-  Results for %d iterations...       \n", NUM_WORD);
  printf("-    Pr[no error]            = %3.7f  \n", pr_noerr);
  printf("-    Pr[error]               = %3.7f  \n", 1.0 - pr_noerr);
  printf("-    Pr[detetable error]     = %3.7f  \n", pr_det);
  printf("-    Pr[undetectable error]  = %3.7f  \n", pr_undet);
  printf("- \n");
  for (i=0; i<=N; i++)
    printf("-    Pr[%2d] bit errors       = %3.7f \n",
      i, ((double) error[i] / NUM_WORD));
  printf("------------------------------------------------------------ \n");
}

