// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x198, %rsp            # imm = 0x198
leaq -0x40(%rbp), %rbx
movl $0x1, (%rbx)
movq 0x8558(%rip), %r14      # 0xcfc8
leaq 0x3a80(%rip), %rsi      # 0x84f7
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0x3832(%rip), %rsi      # 0x82c0
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0x3838(%rip), %rsi      # 0x82dd
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq 0x3835(%rip), %rsi      # 0x82f1
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
movq 0x8505(%rip), %r15      # 0xcfd8
movq %r15, %rdi
movq %rbx, %rsi
callq 0x2100
leaq 0x3a56(%rip), %rsi      # 0x853b
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq -0x38(%rbp), %rsi
movq %r15, %rdi
callq 0x2100
leaq 0x3a53(%rip), %rsi      # 0x855b
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq -0x34(%rbp), %rsi
movq %r15, %rdi
callq 0x2100
leaq 0x3a51(%rip), %rsi      # 0x857c
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq -0x50(%rbp), %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0x2100
leaq 0x3a61(%rip), %rsi      # 0x85b2
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq -0x4c(%rbp), %r13
movq %r15, %rdi
movq %r13, %rsi
callq 0x2100
leaq 0x37f5(%rip), %rsi      # 0x836c
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq -0x3c(%rbp), %rsi
movq %r15, %rdi
callq 0x2100
leaq 0x3a4f(%rip), %rsi      # 0x85e9
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq -0x88(%rbp), %rsi
movq %r15, %rdi
callq 0x2110
leaq 0x3a5b(%rip), %rsi      # 0x861b
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq -0x78(%rbp), %rsi
movq %r15, %rdi
callq 0x2110
leaq 0x3a6b(%rip), %rsi      # 0x864e
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq -0x80(%rbp), %rsi
movq %r15, %rdi
callq 0x2110
leaq 0x3a88(%rip), %rsi      # 0x868e
movq %r14, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20b0
leaq -0x70(%rbp), %rsi
movq %r15, %rdi
callq 0x2110
cvtsi2sdl (%r12), %xmm0
movl (%rbx), %esi
leaq -0xb0(%rbp), %rdi
callq 0x3bbc
cvtsi2sdl (%r13), %xmm0
movl (%rbx), %esi
leaq -0x178(%rbp), %rdi
callq 0x3bbc
cvtsi2sdl -0x50(%rbp), %xmm0
movl -0x40(%rbp), %esi
leaq -0x150(%rbp), %rdi
callq 0x3bbc
cvtsi2sdl -0x4c(%rbp), %xmm0
movl -0x40(%rbp), %esi
leaq -0x128(%rbp), %rdi
callq 0x3bbc
cvtsi2sdl -0x50(%rbp), %xmm0
movl -0x40(%rbp), %esi
leaq -0x100(%rbp), %rdi
callq 0x3bbc
cvtsi2sdl -0x4c(%rbp), %xmm0
movl -0x40(%rbp), %esi
leaq -0xd8(%rbp), %rdi
callq 0x3bbc
movslq -0x38(%rbp), %r15
leaq (,%r15,8), %rdi
testq %r15, %r15
pushq $-0x1
popq %r14
cmovsq %r14, %rdi
callq 0x2030
movq %rax, %rbx
movslq -0x34(%rbp), %rax
leaq (,%rax,8), %rdi
testq %rax, %rax
cmovsq %r14, %rdi
callq 0x2030
movq %rax, %r14
leaq -0x68(%rbp), %rax
movq $0x5, (%rax)
movsd -0x88(%rbp), %xmm0
movsd -0x80(%rbp), %xmm1
leaq -0x1b8(%rbp), %rax
movsd %xmm0, (%rax)
movsd %xmm1, 0x8(%rax)
andq $0x0, 0x10(%rax)
movb $0x0, 0x18(%rax)
movq -0x90(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x130(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0xe0(%rbp), %r12
xorl %r13d, %r13d
movslq %r15d, %rax
cmpq %rax, %r13
jge 0x4d7b
leaq -0x1b8(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x535c
movsd %xmm0, (%rbx,%r13,8)
movq -0x48(%rbp), %rdi
movq (%rdi), %rax
movsd %xmm0, -0x30(%rbp)
movsd -0x30(%rbp), %xmm0
callq *(%rax)
movq -0x58(%rbp), %rdi
movq (%rdi), %rax
movsd -0x30(%rbp), %xmm0
callq *(%rax)
movsd -0x30(%rbp), %xmm0
movq (%r12), %rax
movq %r12, %rdi
callq *(%rax)
incq %r13
movl -0x38(%rbp), %r15d
jmp 0x4d25
leaq -0x60(%rbp), %rax
movq $0x5, (%rax)
movsd -0x78(%rbp), %xmm0
movsd -0x70(%rbp), %xmm1
leaq -0x198(%rbp), %rax
movsd %xmm0, (%rax)
movsd %xmm1, 0x8(%rax)
andq $0x0, 0x10(%rax)
movb $0x0, 0x18(%rax)
movq -0x158(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x108(%rbp), %r15
movq -0xb8(%rbp), %r12
xorl %r13d, %r13d
movslq -0x34(%rbp), %rax
cmpq %rax, %r13
jge 0x4e17
leaq -0x198(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x535c
movsd %xmm0, (%r14,%r13,8)
movq -0x48(%rbp), %rdi
movq (%rdi), %rax
movsd %xmm0, -0x30(%rbp)
movsd -0x30(%rbp), %xmm0
callq *(%rax)
movq (%r15), %rax
movq %r15, %rdi
movsd -0x30(%rbp), %xmm0
callq *(%rax)
movsd -0x30(%rbp), %xmm0
movq (%r12), %rax
movq %r12, %rdi
callq *(%rax)
incq %r13
jmp 0x4dc5
movl -0x3c(%rbp), %edx
leaq -0xb0(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x4336
movsd %xmm0, -0x48(%rbp)
movq -0xa0(%rbp), %r15
movq -0x98(%rbp), %r12
cvtsi2sdl -0x34(%rbp), %xmm0
cvtsi2sdl -0x38(%rbp), %xmm1
divsd %xmm1, %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jb 0x4e5e
sqrtsd %xmm0, %xmm6
jmp 0x4e6b
callq 0x2140
xorpd %xmm2, %xmm2
movapd %xmm0, %xmm6
cvtsi2sdl -0x38(%rbp), %xmm0
cvtsi2sdl -0x34(%rbp), %xmm1
divsd %xmm1, %xmm0
ucomisd %xmm2, %xmm0
jb 0x4e85
sqrtsd %xmm0, %xmm0
jmp 0x4e94
movsd %xmm6, -0x30(%rbp)
callq 0x2140
movsd -0x30(%rbp), %xmm6
movl -0x38(%rbp), %eax
xorl %esi, %esi
testl %eax, %eax
cmovlel %esi, %eax
movl -0x34(%rbp), %ecx
testl %ecx, %ecx
cmovlel %esi, %ecx
movl -0x3c(%rbp), %edx
testl %edx, %edx
cmovlel %esi, %edx
incl %edx
xorpd %xmm1, %xmm1
movsd %xmm1, -0x30(%rbp)
pushq $0x1
popq %rsi
movsd 0x314c(%rip), %xmm1     # 0x8010
cmpq %rdx, %rsi
je 0x4f5e
xorpd %xmm2, %xmm2
xorl %edi, %edi
cmpq %rdi, %rax
je 0x4efa
movsd (%rbx,%rdi,8), %xmm3
movsd (%r15,%rsi,8), %xmm4
ucomisd %xmm3, %xmm4
jb 0x4ef5
ucomisd (%r12,%rsi,8), %xmm3
jb 0x4ef5
addsd %xmm1, %xmm2
incq %rdi
jmp 0x4ed3
xorpd %xmm3, %xmm3
xorl %edi, %edi
cmpq %rdi, %rcx
je 0x4f28
movsd (%r14,%rdi,8), %xmm4
movsd (%r15,%rsi,8), %xmm5
ucomisd %xmm4, %xmm5
jb 0x4f23
ucomisd (%r12,%rsi,8), %xmm4
jb 0x4f23
addsd %xmm1, %xmm3
incq %rdi
jmp 0x4f00
movapd %xmm0, %xmm4
mulsd %xmm3, %xmm4
movapd %xmm2, %xmm5
mulsd %xmm6, %xmm5
subsd %xmm4, %xmm5
mulsd %xmm5, %xmm5
addsd %xmm3, %xmm2
divsd %xmm2, %xmm5
movsd -0x30(%rbp), %xmm2
addsd %xmm5, %xmm2
movsd %xmm2, -0x30(%rbp)
incq %rsi
jmp 0x4ec4
movq 0x8063(%rip), %rdi      # 0xcfc8
leaq 0x3763(%rip), %rsi      # 0x86cf
callq 0x2180
movq %rax, %rdi
movsd -0x48(%rbp), %xmm0
callq 0x21f0
movq %rax, %rdi
callq 0x20b0
movq 0x803b(%rip), %rdi      # 0xcfc8
leaq 0x34a1(%rip), %rsi      # 0x8435
callq 0x2180
movq %rax, %rdi
movsd -0x30(%rbp), %xmm0
callq 0x21f0
movq %rax, %rdi
callq 0x20b0
movq 0x8013(%rip), %rdi      # 0xcfc8
leaq 0x3723(%rip), %rsi      # 0x86df
callq 0x2180
movq %rax, %rbx
movl -0x3c(%rbp), %edx
leaq -0x150(%rbp), %rdi
leaq -0x128(%rbp), %rsi
callq 0x451e
movq %rbx, %rdi
callq 0x21f0
movq %rax, %rdi
callq 0x20b0
movq 0x7fd7(%rip), %rdi      # 0xcfc8
leaq 0x36f0(%rip), %rsi      # 0x86e8
callq 0x2180
movq %rax, %rbx
movl -0x3c(%rbp), %edx
leaq -0x100(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x451e
movsd 0x314a(%rip), %xmm1     # 0x8168
xorl %esi, %esi
ucomisd %xmm0, %xmm1
seta %sil
movq %rbx, %rdi
callq 0x2230
movq %rax, %rdi
callq 0x20b0
leaq -0xd8(%rbp), %rdi
callq 0x3cb2
leaq -0x100(%rbp), %rdi
callq 0x3cb2
leaq -0x128(%rbp), %rdi
callq 0x3cb2
leaq -0x150(%rbp), %rdi
callq 0x3cb2
leaq -0x178(%rbp), %rdi
callq 0x3cb2
leaq -0xb0(%rbp), %rdi
callq 0x3cb2
addq $0x198, %rsp            # imm = 0x198
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x50b5
jmp 0x50b5
jmp 0x50b5
movq %rax, %rbx
jmp 0x50c4
movq %rax, %rbx
jmp 0x50d0
movq %rax, %rbx
jmp 0x50dc
movq %rax, %rbx
jmp 0x50e8
movq %rax, %rbx
jmp 0x50f4
jmp 0x50b5
jmp 0x50b5
movq %rax, %rbx
leaq -0xd8(%rbp), %rdi
callq 0x3cb2
leaq -0x100(%rbp), %rdi
callq 0x3cb2
leaq -0x128(%rbp), %rdi
callq 0x3cb2
leaq -0x150(%rbp), %rdi
callq 0x3cb2
leaq -0x178(%rbp), %rdi
callq 0x3cb2
leaq -0xb0(%rbp), %rdi
callq 0x3cb2
movq %rbx, %rdi
callq 0x2280