/*******************************************************************************
 *
 *  Monte Carlo simulation, LP decoding, AWGN channel
 *  Copyright (C) 2006-2009 Misha Stepanov
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/

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

#define LDPCC_RANDOM yes
#define LDPCC_LP yes

#include "ldpcc-3.2/ldpcc.c"

#define UPDATE_STATISTICS \
  out = fopen(filename, "w");\
  fprintf(out, "%4.2f %4Ld %4Ld %Ld\n", SNR2, ERR, ERR_CW, NUM);\
  fclose(out);

int main(int argc, char **argv)
 {
  channel C;
  code H;
  long long int NUM, ERR, ERR_CW;
  real *xi, SNR2;

  int i, counter = 0;
  char filename[256];
  FILE *out, *out_conf;

  C.type = Gaussian_channel;
  SNR2 = atof(argv[1]); C.SNR = sqrt(SNR2);
  C.RNG_grown = 0; grow_RNG(&C);

  H.HiHa_grown = 0; H.ID_grown = 0; H.LP_grown = 0;
  read_H_matrix("matrix_H", &H, 0);
  grow_lp_decoder(&H);

  xi = (real *)malloc(H.bits * sizeof(real));
  if (xi == NULL) { printf("ERR: malloc\n"); exit(1); }

  sprintf(filename, "data_lp_mc_awgn/conf/conf_%4.2f", SNR2);
  out_conf = fopen(filename, "a");

  sprintf(filename, "data_lp_mc_awgn/num_%4.2f", SNR2);
  out = fopen(filename, "r");
  if (out != NULL)
   {
    fscanf(out, "%le %Ld %Ld %Ld", &(xi[0]), &ERR, &ERR_CW, &NUM);
    fclose(out);
   }
   else { NUM = 0; ERR = 0; ERR_CW = 0; }

  while (ERR < 1000)
   {
    toss_noise(&C, H.bits, xi, 0);
    lp_decoding(&H, &C, xi);
    NUM++;
    if (check_error(&H))
     {
      ERR++;
      if (check_codeword(&H)) ERR_CW++;
      UPDATE_STATISTICS

      for (i = 0; i < H.bits; i++) fprintf(out_conf, "%e ", xi[i]);
      fprintf(out_conf, "\n"); fflush(out_conf);
     }

    counter++;
    if (counter == 100)
     {
      UPDATE_STATISTICS
      counter = 0;
     }
   }

  fclose(out_conf);

  kill_RNG(&C);
  kill_lp_decoder(&H);
  kill_H_matrix(&H);

  return 0;
 }

