// File: /workspace/github_cpp_makefile_star2_O2/ashlall[P]StreamStats/Test/GK_test.cpp
// Function: test_GK(int, int)
void test_GK(int stream_size, int sample_size)
{
	double epsilon = log(stream_size)/sample_size;
	
	double quantA,quantB,quantC,quantD,quantE,quantF,quantG,quantH;
	bool condA,condB,condC,condD,condE,condF,condG,condH;
	double upper,lower;
	
	int random_fix1 = rand()% RAND_MAX;
 	int random_fix2 = rand()% RAND_MAX;
 	int random_fix3 = rand()% RAND_MAX;
        
    	GK a(sample_size);
 	GK b(sample_size);
	GK c(sample_size);
	GK d(sample_size);
 	GK e(sample_size);
	GK f(sample_size);
	GK g(sample_size);
 	GK h(sample_size);

	
	for (double j = 0; j <= stream_size; j++) //inserting in decreasing order
   	{	
  		a.insert(j); 
    	}
    	bool condA1;
	int LA = a.get_stream_size(); //test the function get_stream_size()
	condA1= (LA == stream_size+1);
	assert(condA1 == true);

	for (double i = stream_size; i >= 0; i--) //inserting in desceding order
    	{
  		b.insert(i); 
    	}
    	bool condB1;
	int LB = b.get_stream_size(); //test the function get_stream_size()
	condB1= (LB == stream_size+1);
	assert(condB1 == true);

	/*
	Generate three uniform distribution with the following range. In order to have a "good" uniform distribution, recommend large stream size.
	*/
	int uni_lower_bound1 = 500;
	int uni_upper_bound1 = 1000;

	int uni_lower_bound2 = 1234;
	int uni_upper_bound2 = 5678;

	int uni_lower_bound3 = 0;
	int uni_upper_bound3 = 5000;
	for (int m = 1; m <= 3; m++) //create 3 "random" sequences that holds their randomness every time runs the code
  	{
		double data;
  		if (m == 1)
  		{	
			default_random_engine generator(5);
			uniform_real_distribution<double> distribution(uni_lower_bound1,uni_upper_bound1);
			for (int i = 0; i <= stream_size; i++)
			{
   				data = distribution(generator);
  				c.insert(data);
			} 
  		}
  		
  		else if(m == 2)
  		{
			default_random_engine generator(10);
			uniform_real_distribution<double> distribution(uni_lower_bound2,uni_upper_bound2);
			for (int i = 0; i <= stream_size; i++)
			{
   				data = distribution(generator);
  				d.insert(data);
			}
  		}	
  		
  		else 
  		{	
			default_random_engine generator(20);
			uniform_real_distribution<double> distribution(uni_lower_bound3,uni_upper_bound3);
			for (int i = 0; i <= stream_size; i++)
			{
   				data = distribution(generator);
  				e.insert(data);
			}
  		}
  	}
  	
  	  f.insert(random_fix1); //test corner case where n = 1
  	  g.insert(random_fix2); 
  	  h.insert(random_fix3);   	
  	  bool condF1,condG1,condH1;
	  long LF = f.get_stream_size(); //test the function get_stream_size()
	  long LG = g.get_stream_size();
 	  long LH = h.get_stream_size();
          condF1 = (LF == 1);
     	  condG1 = (LG == 1);
	  condH1 = (LH == 1);
	  assert(condF1 == true);
	  assert(condG1 == true);
	  assert(condH1 == true);  
	  	
  for (float i=1;i<=stream_size;i++)
  {
  	  double interval=i/stream_size; //getting each probabilty interval
  	  
  	  quantA=a.getQuantile(interval); //getting quantile for each probability interval
  	  quantB=b.getQuantile(interval);
  	  quantC=c.getQuantile(interval);
  	  quantD=d.getQuantile(interval);
  	  quantE=e.getQuantile(interval);
  	  quantF=f.getQuantile(interval);
  	  quantG=g.getQuantile(interval);
  	  quantH=h.getQuantile(interval);
  	  
  	  lower=(interval-epsilon)*stream_size;//Used for first two cases.
  	  upper=(interval+epsilon)*stream_size;
  	  //cout << "l: " << lower << "  " << "u: " << upper <<endl;

  	  condA= ((lower<=quantA) && (upper>=quantA));
  	  condB= ((lower<=quantB) && (upper >=quantB));
  	  //checking if quantile is within error range
  	  
	
	 // cout << "cao:" << quantD<<endl;
	  //cout << (uni_lower_bound2 + (uni_upper_bound2-uni_lower_bound2)*interval)+epsilon*stream_size << endl;
 	 //cout << (uni_lower_bound2 + (uni_upper_bound2 - uni_lower_bound2)*interval)-epsilon*stream_size << endl;
	 //cout << "" <<endl;

	 condC = (quantC >= (uni_lower_bound1+(uni_upper_bound1 - uni_lower_bound1)*interval)- epsilon*stream_size) && (quantC <= (uni_lower_bound1+(uni_upper_bound1 - uni_lower_bound1)*interval) + epsilon*stream_size);
	 condD = (quantD >= (uni_lower_bound2+(uni_upper_bound2 - uni_lower_bound2)*interval)- epsilon*stream_size) && (quantD <= (uni_lower_bound2+(uni_upper_bound2 - uni_lower_bound2)*interval) + epsilon*stream_size);
	 condE = (quantE >= (uni_lower_bound3+(uni_upper_bound3 - uni_lower_bound3)*interval)- epsilon*stream_size) && (quantE <= (uni_lower_bound3+(uni_upper_bound3 - uni_lower_bound3)*interval) + epsilon*stream_size);
  	  //checking if quantile is within error range
  	  
  	  
  	  condF= (random_fix1 == quantF);
  	  condG= (random_fix2 == quantG);
  	  condH= (random_fix3 == quantH);
  	  //checking if the condition holds in the corner case where stream size = 1

  	  
  	  assert(condA==true);
  	  assert(condB==true);
  	  assert(condC==true);
  	  assert(condD==true);
  	  assert(condE==true);
  	  assert(condF==true);
  	  assert(condG==true);
  	  assert(condH==true);
  } 	  
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x298, %rsp            # imm = 0x298
movl %esi, %r14d
movl %edi, %ebx
callq 0x219b
movapd %xmm0, -0x90(%rbp)
callq 0x1050
movl $0x7fffffff, %r15d      # imm = 0x7FFFFFFF
cltd
idivl %r15d
movl %edx, -0x58(%rbp)
callq 0x1050
cltd
idivl %r15d
movl %edx, %r13d
callq 0x1050
cltd
idivl %r15d
movl %edx, %r12d
leaq -0x230(%rbp), %rdi
movl %r14d, %esi
callq 0x12ba
leaq -0x200(%rbp), %rdi
movl %r14d, %esi
callq 0x12ba
leaq -0x2c0(%rbp), %rdi
movl %r14d, %esi
callq 0x12ba
leaq -0x290(%rbp), %rdi
movl %r14d, %esi
callq 0x12ba
leaq -0x260(%rbp), %rdi
movl %r14d, %esi
callq 0x12ba
leaq -0x1d0(%rbp), %rdi
movl %r14d, %esi
callq 0x12ba
leaq -0x1a0(%rbp), %rdi
movl %r14d, %esi
callq 0x12ba
leaq -0x170(%rbp), %rdi
movl %r14d, %esi
callq 0x12ba
cvtsi2sd %r14d, %xmm0
cvtsi2sd %ebx, %xmm1
movsd %xmm1, -0x48(%rbp)
movapd -0x90(%rbp), %xmm1
divsd %xmm0, %xmm1
movapd %xmm1, -0x90(%rbp)
xorpd %xmm1, %xmm1
leaq -0x230(%rbp), %r14
movsd -0x48(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x175c
movq %r14, %rdi
movsd %xmm1, -0x40(%rbp)
movapd %xmm1, %xmm0
callq 0x1368
movsd -0x40(%rbp), %xmm1
addsd 0x18b6(%rip), %xmm1     # 0x3010
jmp 0x1731
movl -0x208(%rbp), %r15d
leal 0x1(%rbx), %eax
cmpl %r15d, %eax
jne 0x1d8b
leaq -0x200(%rbp), %r14
movsd -0x48(%rbp), %xmm0
ucomisd 0x18b5(%rip), %xmm0     # 0x3038
jb 0x17a1
movq %r14, %rdi
movsd %xmm0, -0x40(%rbp)
callq 0x1368
movsd -0x40(%rbp), %xmm0
addsd 0x1869(%rip), %xmm0     # 0x3008
jmp 0x177b
movl %r13d, -0x50(%rbp)
movl %r12d, -0xa0(%rbp)
cmpl -0x1d8(%rbp), %r15d
jne 0x1da4
pushq $0x1
popq %rax
leaq -0x78(%rbp), %r13
leaq -0x60(%rbp), %r14
leaq -0x260(%rbp), %r15
cmpl $0x1, %eax
movl %eax, -0x40(%rbp)
je 0x186c
cmpl $0x2, %eax
je 0x1824
cmpl $0x4, %eax
je 0x18be
andq $0x0, -0x78(%rbp)
movq $0x14, -0x60(%rbp)
movabsq $0x40b3880000000000, %rax # imm = 0x40B3880000000000
movq %rax, -0x70(%rbp)
xorl %r12d, %r12d
cmpl %ebx, %r12d
jg 0x18b4
movq %r13, %rdi
movq %r14, %rsi
callq 0x21b4
movq %r15, %rdi
callq 0x1368
incl %r12d
jmp 0x1803
movq $0xa, -0x60(%rbp)
movabsq $0x4093480000000000, %rax # imm = 0x4093480000000000
movq %rax, -0x78(%rbp)
movabsq $0x40b62e0000000000, %rax # imm = 0x40B62E0000000000
movq %rax, -0x70(%rbp)
xorl %r12d, %r12d
cmpl %ebx, %r12d
jg 0x18b4
movq %r13, %rdi
movq %r14, %rsi
callq 0x21b4
leaq -0x290(%rbp), %rdi
callq 0x1368
incl %r12d
jmp 0x184b
movq $0x5, -0x60(%rbp)
movabsq $0x407f400000000000, %rax # imm = 0x407F400000000000
movq %rax, -0x78(%rbp)
movabsq $0x408f400000000000, %rax # imm = 0x408F400000000000
movq %rax, -0x70(%rbp)
xorl %r12d, %r12d
cmpl %ebx, %r12d
jg 0x18b4
movq %r13, %rdi
movq %r14, %rsi
callq 0x21b4
leaq -0x2c0(%rbp), %rdi
callq 0x1368
incl %r12d
jmp 0x1893
movl -0x40(%rbp), %eax
incl %eax
jmp 0x17cb
cvtsi2sdl -0x58(%rbp), %xmm0
leaq -0x1d0(%rbp), %rdi
movsd %xmm0, -0xb8(%rbp)
callq 0x1368
cvtsi2sdl -0x50(%rbp), %xmm0
leaq -0x1a0(%rbp), %rdi
movsd %xmm0, -0xb0(%rbp)
callq 0x1368
cvtsi2sdl -0xa0(%rbp), %xmm0
leaq -0x170(%rbp), %rdi
movsd %xmm0, -0xa8(%rbp)
callq 0x1368
cmpq $0x1, -0x1a8(%rbp)
jne 0x1dbd
cmpq $0x1, -0x178(%rbp)
jne 0x1dd6
cmpq $0x1, -0x148(%rbp)
jne 0x1def
cvtsi2ss %ebx, %xmm2
movapd 0x171e(%rip), %xmm3     # 0x3060
movapd -0x90(%rbp), %xmm0
xorpd %xmm0, %xmm3
movss 0x173a(%rip), %xmm4     # 0x3090
leaq -0x260(%rbp), %r12
leaq -0x1d0(%rbp), %r13
leaq -0x1a0(%rbp), %rbx
leaq -0x170(%rbp), %r14
movsd -0x48(%rbp), %xmm1
mulsd %xmm1, %xmm3
movapd %xmm0, %xmm5
mulsd %xmm1, %xmm5
leaq -0x200(%rbp), %r15
movaps %xmm4, %xmm0
movss %xmm2, -0x64(%rbp)
movapd %xmm3, -0xf0(%rbp)
movapd %xmm5, -0xe0(%rbp)
ucomiss %xmm0, %xmm2
jb 0x1c21
movss %xmm0, -0x68(%rbp)
divss %xmm2, %xmm0
cvtss2sd %xmm0, %xmm0
movaps %xmm0, -0x40(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x15be
movsd %xmm0, -0x58(%rbp)
leaq -0x2c0(%rbp), %rdi
movaps -0x40(%rbp), %xmm0
callq 0x15be
movaps %xmm0, -0xa0(%rbp)
leaq -0x290(%rbp), %rdi
movaps -0x40(%rbp), %xmm0
callq 0x15be
movaps %xmm0, -0x130(%rbp)
movq %r12, %rdi
movaps -0x40(%rbp), %xmm0
callq 0x15be
movaps %xmm0, -0x110(%rbp)
movq %r13, %rdi
movaps -0x40(%rbp), %xmm0
callq 0x15be
movsd %xmm0, -0xd0(%rbp)
movq %rbx, %rdi
movaps -0x40(%rbp), %xmm0
callq 0x15be
movsd %xmm0, -0xc8(%rbp)
movq %r14, %rdi
movaps -0x40(%rbp), %xmm0
callq 0x15be
movsd -0x58(%rbp), %xmm4
movapd -0x40(%rbp), %xmm2
movsd %xmm0, -0xc0(%rbp)
movapd %xmm2, %xmm3
movapd -0x90(%rbp), %xmm0
subsd %xmm0, %xmm3
movsd -0x48(%rbp), %xmm1
mulsd %xmm1, %xmm3
movsd %xmm3, -0x50(%rbp)
ucomisd %xmm3, %xmm4
movapd %xmm2, %xmm3
mulsd 0x159e(%rip), %xmm3     # 0x3020
addsd 0x159e(%rip), %xmm3     # 0x3028
movapd %xmm3, -0x120(%rbp)
movapd %xmm2, %xmm3
mulsd 0x1592(%rip), %xmm3     # 0x3030
movapd %xmm3, -0x100(%rbp)
jb 0x1cf0
addsd %xmm2, %xmm0
mulsd %xmm1, %xmm0
movapd %xmm0, -0x140(%rbp)
ucomisd %xmm4, %xmm0
jb 0x1cf0
movq %r15, %rdi
movapd %xmm2, %xmm0
callq 0x15be
ucomisd -0x50(%rbp), %xmm0
jb 0x1cd1
movapd -0x140(%rbp), %xmm1
ucomisd %xmm0, %xmm1
jb 0x1cd1
movsd 0x1521(%rip), %xmm0     # 0x3018
movapd -0x40(%rbp), %xmm1
mulsd %xmm0, %xmm1
addsd %xmm0, %xmm1
movapd -0xf0(%rbp), %xmm3
movapd %xmm3, %xmm0
addsd %xmm1, %xmm0
movapd -0xe0(%rbp), %xmm5
addsd %xmm5, %xmm1
movapd -0xa0(%rbp), %xmm2
cmplepd %xmm2, %xmm0
cmplepd %xmm1, %xmm2
andpd %xmm0, %xmm2
movd %xmm2, %eax
testb $0x1, %al
movss -0x64(%rbp), %xmm2
je 0x1cb2
movapd %xmm3, %xmm0
movapd -0x120(%rbp), %xmm4
addsd %xmm4, %xmm0
addsd %xmm5, %xmm4
movapd -0x130(%rbp), %xmm1
cmplepd %xmm1, %xmm0
cmplepd %xmm4, %xmm1
andpd %xmm0, %xmm1
movd %xmm1, %eax
testb $0x1, %al
je 0x1c93
movapd -0x100(%rbp), %xmm4
addsd 0x14ab(%rip), %xmm4     # 0x3038
movapd %xmm3, %xmm0
addsd %xmm4, %xmm0
addsd %xmm5, %xmm4
movapd -0x110(%rbp), %xmm1
cmplepd %xmm1, %xmm0
cmplepd %xmm4, %xmm1
andpd %xmm0, %xmm1
movd %xmm1, %eax
testb $0x1, %al
je 0x1d6c
movsd -0xd0(%rbp), %xmm0
ucomisd -0xb8(%rbp), %xmm0
movss -0x68(%rbp), %xmm0
jne 0x1d4d
jp 0x1d4d
movsd -0xc8(%rbp), %xmm1
ucomisd -0xb0(%rbp), %xmm1
jne 0x1d2e
jp 0x1d2e
movsd -0xc0(%rbp), %xmm1
ucomisd -0xa8(%rbp), %xmm1
jne 0x1d0f
jp 0x1d0f
addss 0x1474(%rip), %xmm0     # 0x3090
jmp 0x19a2
leaq -0x170(%rbp), %rdi
callq 0x1322
leaq -0x1a0(%rbp), %rdi
callq 0x1322
leaq -0x1d0(%rbp), %rdi
callq 0x1322
leaq -0x260(%rbp), %rdi
callq 0x1322
leaq -0x290(%rbp), %rdi
callq 0x1322
leaq -0x2c0(%rbp), %rdi
callq 0x1322
leaq -0x200(%rbp), %rdi
callq 0x1322
leaq -0x230(%rbp), %rdi
callq 0x1322
addq $0x298, %rsp            # imm = 0x298
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1494(%rip), %rdi      # 0x312e
leaq 0x140a(%rip), %rsi      # 0x30ab
leaq 0x140f(%rip), %rcx      # 0x30b7
movl $0x9f, %edx
callq 0x1070
leaq 0x1469(%rip), %rdi      # 0x3122
leaq 0x13eb(%rip), %rsi      # 0x30ab
leaq 0x13f0(%rip), %rcx      # 0x30b7
movl $0x9e, %edx
callq 0x1070
leaq 0x143e(%rip), %rdi      # 0x3116
leaq 0x13cc(%rip), %rsi      # 0x30ab
leaq 0x13d1(%rip), %rcx      # 0x30b7
movl $0x9d, %edx
callq 0x1070
leaq 0x1413(%rip), %rdi      # 0x310a
leaq 0x13ad(%rip), %rsi      # 0x30ab
leaq 0x13b2(%rip), %rcx      # 0x30b7
movl $0x9c, %edx
callq 0x1070
leaq 0x1448(%rip), %rdi      # 0x315e
leaq 0x138e(%rip), %rsi      # 0x30ab
leaq 0x1393(%rip), %rcx      # 0x30b7
movl $0xa3, %edx
callq 0x1070
leaq 0x141d(%rip), %rdi      # 0x3152
leaq 0x136f(%rip), %rsi      # 0x30ab
leaq 0x1374(%rip), %rcx      # 0x30b7
movl $0xa2, %edx
callq 0x1070
leaq 0x13f2(%rip), %rdi      # 0x3146
leaq 0x1350(%rip), %rsi      # 0x30ab
leaq 0x1355(%rip), %rcx      # 0x30b7
movl $0xa1, %edx
callq 0x1070
leaq 0x13c7(%rip), %rdi      # 0x313a
leaq 0x1331(%rip), %rsi      # 0x30ab
leaq 0x1336(%rip), %rcx      # 0x30b7
movl $0xa0, %edx
callq 0x1070
leaq 0x130a(%rip), %rdi      # 0x309c
leaq 0x1312(%rip), %rsi      # 0x30ab
leaq 0x1317(%rip), %rcx      # 0x30b7
pushq $0x2c
jmp 0x1e06
leaq 0x1323(%rip), %rdi      # 0x30ce
leaq 0x12f9(%rip), %rsi      # 0x30ab
leaq 0x12fe(%rip), %rcx      # 0x30b7
pushq $0x35
jmp 0x1e06
leaq 0x1319(%rip), %rdi      # 0x30dd
leaq 0x12e0(%rip), %rsi      # 0x30ab
leaq 0x12e5(%rip), %rcx      # 0x30b7
pushq $0x71
jmp 0x1e06
leaq 0x130f(%rip), %rdi      # 0x30ec
leaq 0x12c7(%rip), %rsi      # 0x30ab
leaq 0x12cc(%rip), %rcx      # 0x30b7
pushq $0x72
jmp 0x1e06
leaq 0x1305(%rip), %rdi      # 0x30fb
leaq 0x12ae(%rip), %rsi      # 0x30ab
leaq 0x12b3(%rip), %rcx      # 0x30b7
pushq $0x73
popq %rdx
callq 0x1070
movq %rax, %rbx
jmp 0x1e48
movq %rax, %rbx
jmp 0x1e54
movq %rax, %rbx
jmp 0x1e60
movq %rax, %rbx
jmp 0x1e6c
movq %rax, %rbx
jmp 0x1e78
movq %rax, %rbx
jmp 0x1e84
movq %rax, %rbx
jmp 0x1e90
jmp 0x1e39
jmp 0x1e39
jmp 0x1e39
jmp 0x1e39
jmp 0x1e39
movq %rax, %rbx
leaq -0x170(%rbp), %rdi
callq 0x1322
leaq -0x1a0(%rbp), %rdi
callq 0x1322
leaq -0x1d0(%rbp), %rdi
callq 0x1322
leaq -0x260(%rbp), %rdi
callq 0x1322
leaq -0x290(%rbp), %rdi
callq 0x1322
leaq -0x2c0(%rbp), %rdi
callq 0x1322
leaq -0x200(%rbp), %rdi
callq 0x1322
leaq -0x230(%rbp), %rdi
callq 0x1322
movq %rbx, %rdi
callq 0x1100