#include <iostream>
#include "graph_holder.h"
#include <math.h>
#include <ctime>
#include <cstdlib>

using namespace std ;

int factorial(int n);
double choose(int n, int r);
void gen_gauss(double mean, double var2, int size, double *arr);

int factorial(int n) {

int ret=n;
int i;

for(i=n-1;i>=2;i--)
	ret = ret*i;

if (n==0)
	ret=1;


return ret;
}

double choose(int n, int r) {

double ret = (double) factorial(n)/(factorial(r)*factorial(n-r)) ;

return ret;


}

void gen_gauss(double mean, double var2,  int size, double *arr) {
// size must be even
// arr must be an array of size "size"
double w;
srand( (unsigned)time(NULL));
int i;
for(i = 0;i < size;i=i+2) {
	do {
	arr[i] = 2.0* rand()/RAND_MAX-1.0;
	arr[i+1] = 2.0* rand()/RAND_MAX-1.0;
		w = arr[i]*arr[i]+arr[i+1]*arr[i+1];
	} while( w >= 1.0);

	//std::cout << "\n x1 = " << x1;
	//std::cout << "\n x2 = " << x2;
	w = sqrt((-2.0*log(w))/w);
	arr[i] = mean+var2*arr[i]*w;
	arr[i+1] = mean+var2*arr[i+1]*w;

}
}

void add_noise(double *input, int size, double SNR) {
// input assumed to consist of 1's and -1's
double *arr = new double[size];
int i;
//std::cout << "\n input:";
//for(i=0;i<size;i++)
//	std::cout << " " << input[i];
gen_gauss(0,1/SNR,size,arr);

//std::cout << "\n random noise generated by gen_gauss:";
//for(i=0;i<size;i++)
//	std::cout << " " << arr[i];
for (i=0;i<size;i++) {
	input[i]=input[i]+arr[i];
}

//std::cout << "\n what add_noise is returning:";
//for(i=0;i<size;i++)
//	std::cout << " " << input[i];
delete[] arr;
}




