#ifndef __UTIL_H
#define __UTIL_H

#include <time.h>

static bool init_flag = false;

//メルセンヌ・ツイスタ用
#include "mt19937ar.h"
static int randMT(){
  if(!init_flag){
    init_genrand((unsigned long)time(NULL));
    init_flag = true;
  }
  return (int)genrand_int31();
}

static double drandMT(){
  if(!init_flag){
    init_genrand((unsigned long)time(NULL));
    init_flag = true;
  }
  return genrand_real1();
}

/*
//通常のC言語の標準rand()、性能悪し
#include <stdlib.h>
static int randC(){
  if(!init_flag){
    srand((unsigned int)time(NULL));
    init_flag = true;
  }
  return rand();
}

static double drandC(){
  if(!init_flag){
    srand((unsigned int)time(NULL));
    init_flag = true;
  }
  return (double)rand() / RAND_MAX;
}*/

#define rand() randMT()
#define drand() drandMT()

/**
 * 正規化ノイズを発生させます。
 * 
 * @param mu 平均
 * @param sigma 偏差
 */
static double rand_regularized(double mu, double sigma){
  static double v_1, v_2, s;
  static bool flag = false;
  if(flag = !flag){
    do{
      v_1 = drand() * 2 - 1;
      v_2 = drand() * 2 - 1;
    }while((s = v_1 * v_1 + v_2 * v_2) >= 1.0 || s == 0);
    return sigma * v_1 * sqrt(-2 * log(s) / s) + mu;
  }else{
    return sigma * v_2 * sqrt(-2 * log(s) / s) + mu;
  }
}

#define min(x, y) (x < y ? x : y)
#define max(x, y) (x > y ? x : y)

#endif /* __UTIL_H */
