// File: ashlall[P]StreamStats/Test/Chi_Square_test.cpp
// Function: test_chi_square_2nd()
void test_chi_square_2nd() //Two-sample test
{
 	int sketch_method = 1;
  	cout << "Enter the number 1-3 to choose sketch method that you want to use: "<<endl;
  	cout << "1. Greenwald sketch/default." <<endl;
  	cout << "2. Q-Digest sketch." <<endl;
  	cout << "3. Reservoir Sampling sketch." <<endl;
  	cin >> sketch_method;

	int stream_size1;
	int stream_size2;
  	cout << "Enter the first stream's size: "<<endl;
  	cin >> stream_size1;
	cout << "Enter the second stream's size: "<<endl;
	cin >> stream_size2;

  	int sample_size1;
	int sample_size2;
  	cout << "Enter the memory capacity for the first sample size: "<<endl;
 	cin >> sample_size1;
  	cout << "Enter the memory capacity for the second sample size: "<<endl;
 	cin >> sample_size2;
  
	int k;
 	cout << "Enter the number of bins you want to use: " <<endl;
 	cin >> k;

	double mean1, SD1;
	double mean2, SD2;
	cout << "Enter the mean of the first normal distribution: "<<endl;
	cin >> mean1;
	cout << "Enter the mean of the second normal distribution: "<<endl;
	cin >> mean2;
 	cout << "Enter the standard deviation of the first normal distribution: "<<endl;
	cin >> SD1;
 	cout << "Enter the standard deviation of the second normal distribution: "<<endl;
	cin >> SD2;

	ChiSquareContinuous c1(sample_size1, sketch_method), c2(sample_size2, sketch_method); 
	ChiSquareContinuous c3(sample_size1, sketch_method), c4(sample_size2, sketch_method); 
	ChiSquareContinuous c5(sample_size1, sketch_method), c6(sample_size2, sketch_method);

	double *items1=new double[stream_size1]; //used for storing all the generated data for calculating the actual chi^2.
	double *items2=new double[stream_size2];
	double data1;
	double data2;
	default_random_engine generator(5);
	normal_distribution<double> distribution(mean1,SD1);

	for (int i=0; i<stream_size1; i++) 
  	{
   		data1 = distribution(generator);
		items1[i] = data1;
  		c1.insert(data1);
		c3.insert(data1);
		c5.insert(data1);
 	}

	default_random_engine generator2(5);
	normal_distribution<double> distribution2(mean2,SD2);
 	for (int i = 0; i < stream_size2; i++)
  	{
		data2 = distribution2(generator2);
		items2[i] = data2;
		c2.insert(data2);
		c4.insert(data2);
		c6.insert(data2);
 	}

	double chiEestimated;
        chiEestimated = c1.two_sample_statistic(c2, k);
   	double chiActual=0;

   	double *Upper=c1.get_upper();
   	double *Lower=c1.get_lower();
	double constant_1 = sqrt((double)stream_size2/stream_size1);
 	double constant_2 = sqrt((double)stream_size1/stream_size2);

   	/*timeval timeBefore, timeAfter;
   	long diffSeconds, diffUSeconds;
   	gettimeofday(&timeBefore, NULL);*/
   	for (int i=1;i<=k;i++)
   	{	
    		double E=0;
        	for(int j=0;j<stream_size1;j++)
    	    	{
    	    		if(( items1[j]<=Upper[i]) && (items1[j]>=Lower[i]))
		        	E++;
    	    	}
	
    		double O=0;
        	for(int j=0;j<stream_size2;j++)
    	    	{
    	    		if(( items2[j]<=Upper[i]) && (items2[j]>=Lower[i]))
		        	O++;
    	    	}
                //cout <<"actual S_i and R_i: " << E << " " << O<< endl;
	
      	    	double lambda= E*constant_1 - O*constant_2;
	 
	    	//cout<<"i: "<< i << " Expected: "<<E << " "<<"actual:" << O <<endl;

    	   	chiActual=chiActual+((lambda*lambda)/(E+O)); 	    
    	}	
    /*gettimeofday(&timeAfter, NULL);
    diffSeconds = timeAfter.tv_sec - timeBefore.tv_sec;
    diffUSeconds = timeAfter.tv_usec - timeBefore.tv_usec;
    cout << "1st way: " << diffSeconds + diffUSeconds/1000000.0 << endl;

    gettimeofday(&timeBefore, NULL);
    int *frequencies = get_frequencies(Upper, Lower, items, k, stream_size);
    for (int i = 1; i <= k; i++)
      { 
	chiActual2 += (frequencies[i] - E) * (frequencies[i] - E)/E;
	}*/
    /*gettimeofday(&timeAfter, NULL);
    diffSeconds= timeAfter.tv_sec - timeBefore.tv_sec;
    diffUSeconds = timeAfter.tv_usec - timeBefore.tv_usec;
    cout << "2nd way: "<< diffSeconds + diffUSeconds/1000000.0<<" seconds\n";*/
  	cout << "chiEestimated: " << chiEestimated << endl;
	cout << "chiActual: " << chiActual << endl;
	cout << "pvalue: "<<c3.two_sample_pvalue(c4,k) <<endl;
	cout << "decision: "<<c5.two_sample_final_decision(c6,k,0.05) <<endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2b0, %rsp            # imm = 0x2B0
movl $0x1, -0x4(%rbp)
movq 0x124af(%rip), %rdi     # 0x18fc8
movq %rdi, -0x230(%rbp)
leaq 0xa994(%rip), %rsi      # 0x114bb
callq 0x2170
movq %rax, %rdi
movq 0x12482(%rip), %rsi     # 0x18fb8
movq %rsi, -0x228(%rbp)
callq 0x2190
movq -0x230(%rbp), %rdi
leaq 0xa734(%rip), %rsi      # 0x11284
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x230(%rbp), %rdi
leaq 0xa72f(%rip), %rsi      # 0x112a1
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x230(%rbp), %rdi
leaq 0xa721(%rip), %rsi      # 0x112b5
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq 0x12429(%rip), %rdi     # 0x18fd8
movq %rdi, -0x220(%rbp)
leaq -0x4(%rbp), %rsi
callq 0x20f0
movq -0x230(%rbp), %rdi
leaq 0xa932(%rip), %rsi      # 0x114ff
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x220(%rbp), %rdi
leaq -0x8(%rbp), %rsi
callq 0x20f0
movq -0x230(%rbp), %rdi
leaq 0xa920(%rip), %rsi      # 0x1151f
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x220(%rbp), %rdi
leaq -0xc(%rbp), %rsi
callq 0x20f0
movq -0x230(%rbp), %rdi
leaq 0xa90f(%rip), %rsi      # 0x11540
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x220(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0x20f0
movq -0x230(%rbp), %rdi
leaq 0xa913(%rip), %rsi      # 0x11576
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x220(%rbp), %rdi
leaq -0x14(%rbp), %rsi
callq 0x20f0
movq -0x230(%rbp), %rdi
leaq 0xa69b(%rip), %rsi      # 0x11330
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x220(%rbp), %rdi
leaq -0x18(%rbp), %rsi
callq 0x20f0
movq -0x230(%rbp), %rdi
leaq 0xa8e6(%rip), %rsi      # 0x115ad
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x220(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x2140
movq -0x230(%rbp), %rdi
leaq 0xa8e6(%rip), %rsi      # 0x115df
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x220(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x2140
movq -0x230(%rbp), %rdi
leaq 0xa8e7(%rip), %rsi      # 0x11612
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x220(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x2140
movq -0x230(%rbp), %rdi
leaq 0xa8f5(%rip), %rsi      # 0x11652
callq 0x2170
movq -0x228(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq -0x220(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x2140
cvtsi2sdl -0x10(%rbp), %xmm0
movl -0x4(%rbp), %esi
leaq -0x60(%rbp), %rdi
callq 0x5190
cvtsi2sdl -0x14(%rbp), %xmm0
movl -0x4(%rbp), %esi
leaq -0x88(%rbp), %rdi
callq 0x5190
jmp 0x6da8
cvtsi2sdl -0x10(%rbp), %xmm0
movl -0x4(%rbp), %esi
leaq -0xc0(%rbp), %rdi
callq 0x5190
jmp 0x6dbe
cvtsi2sdl -0x14(%rbp), %xmm0
movl -0x4(%rbp), %esi
leaq -0xe8(%rbp), %rdi
callq 0x5190
jmp 0x6dd4
cvtsi2sdl -0x10(%rbp), %xmm0
movl -0x4(%rbp), %esi
leaq -0x110(%rbp), %rdi
callq 0x5190
jmp 0x6dea
cvtsi2sdl -0x14(%rbp), %xmm0
movl -0x4(%rbp), %esi
leaq -0x138(%rbp), %rdi
callq 0x5190
jmp 0x6e00
movslq -0x8(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x238(%rbp)
jmp 0x6e28
movq -0x238(%rbp), %rax
movq %rax, -0x140(%rbp)
movslq -0xc(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x2030
movq %rax, -0x240(%rbp)
jmp 0x6e5e
movq -0x240(%rbp), %rax
movq %rax, -0x148(%rbp)
leaq -0x160(%rbp), %rdi
movl $0x5, %esi
callq 0x83d0
jmp 0x6e7f
movsd -0x20(%rbp), %xmm0
movsd -0x28(%rbp), %xmm1
leaq -0x180(%rbp), %rdi
callq 0x8400
jmp 0x6e97
movl $0x0, -0x184(%rbp)
movl -0x184(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x6fe3
leaq -0x180(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x8450
movsd %xmm0, -0x248(%rbp)
jmp 0x6ecd
movsd -0x248(%rbp), %xmm0
movsd %xmm0, -0x150(%rbp)
movsd -0x150(%rbp), %xmm0
movq -0x140(%rbp), %rax
movslq -0x184(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd -0x150(%rbp), %xmm0
leaq -0x60(%rbp), %rdi
callq 0x53b0
jmp 0x6f0b
movsd -0x150(%rbp), %xmm0
leaq -0xc0(%rbp), %rdi
callq 0x53b0
jmp 0x6f21
movsd -0x150(%rbp), %xmm0
leaq -0x110(%rbp), %rdi
callq 0x53b0
jmp 0x6f37
jmp 0x6f39
movl -0x184(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x184(%rbp)
jmp 0x6ea1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x754d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x7541
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x7535
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x7529
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
jmp 0x751d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x138(%rbp), %rdi
callq 0x5340
jmp 0x751d
leaq -0x190(%rbp), %rdi
movl $0x5, %esi
callq 0x83d0
jmp 0x6ff6
movsd -0x30(%rbp), %xmm0
movsd -0x38(%rbp), %xmm1
leaq -0x1b0(%rbp), %rdi
callq 0x8400
jmp 0x700e
movl $0x0, -0x1b4(%rbp)
movl -0x1b4(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x70c7
leaq -0x1b0(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq 0x8450
movsd %xmm0, -0x250(%rbp)
jmp 0x7044
movsd -0x250(%rbp), %xmm0
movsd %xmm0, -0x158(%rbp)
movsd -0x158(%rbp), %xmm0
movq -0x148(%rbp), %rax
movslq -0x1b4(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd -0x158(%rbp), %xmm0
leaq -0x88(%rbp), %rdi
callq 0x53b0
jmp 0x7085
movsd -0x158(%rbp), %xmm0
leaq -0xe8(%rbp), %rdi
callq 0x53b0
jmp 0x709b
movsd -0x158(%rbp), %xmm0
leaq -0x138(%rbp), %rdi
callq 0x53b0
jmp 0x70b1
jmp 0x70b3
movl -0x1b4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1b4(%rbp)
jmp 0x7018
movl -0x18(%rbp), %edx
leaq -0x60(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x5f70
movsd %xmm0, -0x258(%rbp)
jmp 0x70e4
movsd -0x258(%rbp), %xmm0
movsd %xmm0, -0x1c0(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x1c8(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x62f0
movq %rax, -0x1d0(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x62d0
movq %rax, -0x1d8(%rbp)
cvtsi2sdl -0xc(%rbp), %xmm0
cvtsi2sdl -0x8(%rbp), %xmm1
divsd %xmm1, %xmm0
callq 0x2120
movsd %xmm0, -0x1e0(%rbp)
cvtsi2sdl -0x8(%rbp), %xmm0
cvtsi2sdl -0xc(%rbp), %xmm1
divsd %xmm1, %xmm0
callq 0x2120
movsd %xmm0, -0x1e8(%rbp)
movl $0x1, -0x1ec(%rbp)
movl -0x1ec(%rbp), %eax
cmpl -0x18(%rbp), %eax
jg 0x734d
xorps %xmm0, %xmm0
movsd %xmm0, -0x1f8(%rbp)
movl $0x0, -0x1fc(%rbp)
movl -0x1fc(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x7214
movq -0x140(%rbp), %rax
movslq -0x1fc(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
movq -0x1d0(%rbp), %rax
movslq -0x1ec(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd %xmm1, %xmm0
jb 0x71fe
movq -0x140(%rbp), %rax
movslq -0x1fc(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x1d8(%rbp), %rax
movslq -0x1ec(%rbp), %rcx
ucomisd (%rax,%rcx,8), %xmm0
jb 0x71fe
movsd 0x9e1a(%rip), %xmm0     # 0x11008
addsd -0x1f8(%rbp), %xmm0
movsd %xmm0, -0x1f8(%rbp)
jmp 0x7200
movl -0x1fc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1fc(%rbp)
jmp 0x7183
xorps %xmm0, %xmm0
movsd %xmm0, -0x208(%rbp)
movl $0x0, -0x20c(%rbp)
movl -0x20c(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x72ba
movq -0x148(%rbp), %rax
movslq -0x20c(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm1
movq -0x1d0(%rbp), %rax
movslq -0x1ec(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd %xmm1, %xmm0
jb 0x72a4
movq -0x148(%rbp), %rax
movslq -0x20c(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq -0x1d8(%rbp), %rax
movslq -0x1ec(%rbp), %rcx
ucomisd (%rax,%rcx,8), %xmm0
jb 0x72a4
movsd 0x9d74(%rip), %xmm0     # 0x11008
addsd -0x208(%rbp), %xmm0
movsd %xmm0, -0x208(%rbp)
jmp 0x72a6
movl -0x20c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20c(%rbp)
jmp 0x7229
movsd -0x1f8(%rbp), %xmm0
movsd -0x1e0(%rbp), %xmm2
movsd -0x208(%rbp), %xmm1
mulsd -0x1e8(%rbp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x218(%rbp)
movsd -0x1c8(%rbp), %xmm0
movsd -0x218(%rbp), %xmm1
mulsd -0x218(%rbp), %xmm1
movsd -0x1f8(%rbp), %xmm2
addsd -0x208(%rbp), %xmm2
divsd %xmm2, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x1c8(%rbp)
movl -0x1ec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1ec(%rbp)
jmp 0x715f
movq 0x11c74(%rip), %rdi     # 0x18fc8
leaq 0xa338(%rip), %rsi      # 0x11693
callq 0x2170
movq %rax, -0x260(%rbp)
jmp 0x7369
movq -0x260(%rbp), %rdi
movsd -0x1c0(%rbp), %xmm0
callq 0x2290
movq %rax, -0x268(%rbp)
jmp 0x7386
movq -0x268(%rbp), %rdi
movq 0x11c24(%rip), %rsi     # 0x18fb8
callq 0x2190
jmp 0x739b
movq 0x11c26(%rip), %rdi     # 0x18fc8
leaq 0xa050(%rip), %rsi      # 0x113f9
callq 0x2170
movq %rax, -0x270(%rbp)
jmp 0x73b7
movq -0x270(%rbp), %rdi
movsd -0x1c8(%rbp), %xmm0
callq 0x2290
movq %rax, -0x278(%rbp)
jmp 0x73d4
movq -0x278(%rbp), %rdi
movq 0x11bd6(%rip), %rsi     # 0x18fb8
callq 0x2190
jmp 0x73e9
movq 0x11bd8(%rip), %rdi     # 0x18fc8
leaq 0xa2ac(%rip), %rsi      # 0x116a3
callq 0x2170
movq %rax, -0x280(%rbp)
jmp 0x7405
movl -0x18(%rbp), %edx
leaq -0xc0(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x6220
movsd %xmm0, -0x288(%rbp)
jmp 0x7425
movsd -0x288(%rbp), %xmm0
movq -0x280(%rbp), %rdi
callq 0x2290
movq %rax, -0x290(%rbp)
jmp 0x7442
movq -0x290(%rbp), %rdi
movq 0x11b68(%rip), %rsi     # 0x18fb8
callq 0x2190
jmp 0x7457
movq 0x11b6a(%rip), %rdi     # 0x18fc8
leaq 0xa247(%rip), %rsi      # 0x116ac
callq 0x2170
movq %rax, -0x298(%rbp)
jmp 0x7473
movl -0x18(%rbp), %edx
leaq -0x110(%rbp), %rdi
leaq -0x138(%rbp), %rsi
movsd 0x9cc4(%rip), %xmm0     # 0x11150
callq 0x6270
movb %al, -0x299(%rbp)
jmp 0x7499
movq -0x298(%rbp), %rdi
movb -0x299(%rbp), %al
movzbl %al, %esi
andl $0x1, %esi
callq 0x2270
movq %rax, -0x2a8(%rbp)
jmp 0x74ba
movq -0x2a8(%rbp), %rdi
movq 0x11af0(%rip), %rsi     # 0x18fb8
callq 0x2190
jmp 0x74cf
leaq -0x138(%rbp), %rdi
callq 0x5340
leaq -0x110(%rbp), %rdi
callq 0x5340
leaq -0xe8(%rbp), %rdi
callq 0x5340
leaq -0xc0(%rbp), %rdi
callq 0x5340
leaq -0x88(%rbp), %rdi
callq 0x5340
leaq -0x60(%rbp), %rdi
callq 0x5340
addq $0x2b0, %rsp            # imm = 0x2B0
popq %rbp
retq
leaq -0x110(%rbp), %rdi
callq 0x5340
leaq -0xe8(%rbp), %rdi
callq 0x5340
leaq -0xc0(%rbp), %rdi
callq 0x5340
leaq -0x88(%rbp), %rdi
callq 0x5340
leaq -0x60(%rbp), %rdi
callq 0x5340
movq -0x90(%rbp), %rdi
callq 0x2260
nopw %cs:(%rax,%rax)