// File: tonymugen[P]sampleSNPs/random.cpp
// Function: sampFiles::RanDraw::vitterA(double const&, double const&)
volatile uint64_t RanDraw::vitterA(const double &n, const double &N){
	// The notation follows Vitter's (1987) as closely as possible
	// Note that my runif() is on [0,1] (Vitter assumes (0,1)), so I have to sometimes adjust accordingly
	uint64_t S  = 0;
	double top  = N - n;
	double quot = top/N;
	double v;
	
	// some trivial conditions first
	if ( (n == 0) || (n > N) ) {
		return S;
	} else if (n == 1) {
		do {
			S = static_cast<uint64_t>(floor(N * this->runif()));
			
		} while (S == static_cast<uint64_t>(N)); // s == N would be a problem because it would overshoot the end of the array/file (in base-0 space); effectively sampling [0,1) uniform to prevent this
		return S;
	}
	// [0,1) uniform
	do {
		v = this->runif();
	} while (v == 1.0); // i.e. only repeat if v == 1.0
	
	double Nloc = N;
	while (quot > v) {
		S++;
		top--;
		Nloc--;
		quot = quot*top/Nloc;
	}
	
	return S;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movq $0x0, -0x28(%rbp)
movq -0x20(%rbp), %rax
movsd (%rax), %xmm0
movq -0x18(%rbp), %rax
subsd (%rax), %xmm0
movsd %xmm0, -0x30(%rbp)
movsd -0x30(%rbp), %xmm0
movq -0x20(%rbp), %rax
divsd (%rax), %xmm0
movsd %xmm0, -0x38(%rbp)
movq -0x18(%rbp), %rax
movsd (%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x22620
jp 0x22620
jmp 0x22632
movq -0x18(%rbp), %rax
movsd (%rax), %xmm0
movq -0x20(%rbp), %rax
ucomisd (%rax), %xmm0
jbe 0x2263f
movq -0x28(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x2278a
movq -0x18(%rbp), %rax
movsd (%rax), %xmm0
movsd 0xe89(%rip), %xmm1      # 0x234d8
ucomisd %xmm1, %xmm0
jne 0x226fa
jp 0x226fa
jmp 0x22661
movq -0x50(%rbp), %rdi
movq -0x20(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x58(%rbp)
callq 0x22cb0
movaps %xmm0, %xmm1
movsd -0x58(%rbp), %xmm0
mulsd %xmm1, %xmm0
callq 0x45b0
movaps %xmm0, %xmm1
cvttsd2si %xmm1, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
movsd 0x1a81(%rip), %xmm1     # 0x24120
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq -0x20(%rbp), %rcx
movsd (%rcx), %xmm0
movsd 0x1a5a(%rip), %xmm2     # 0x24120
movaps %xmm0, %xmm1
subsd %xmm2, %xmm1
cvttsd2si %xmm1, %rdx
cvttsd2si %xmm0, %rcx
movq %rcx, %rsi
sarq $0x3f, %rsi
andq %rsi, %rdx
orq %rdx, %rcx
cmpq %rcx, %rax
je 0x22661
movq -0x28(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x2278a
jmp 0x226fc
jmp 0x226fe
movq -0x50(%rbp), %rdi
callq 0x22cb0
movsd %xmm0, -0x40(%rbp)
movsd -0x40(%rbp), %xmm0
movsd 0xdbf(%rip), %xmm1      # 0x234d8
ucomisd %xmm1, %xmm0
jne 0x22723
jp 0x22723
jmp 0x226fe
movq -0x20(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x48(%rbp)
movsd -0x38(%rbp), %xmm0
ucomisd -0x40(%rbp), %xmm0
jbe 0x22782
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
movsd 0x19c8(%rip), %xmm0     # 0x24118
addsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movsd 0x19b6(%rip), %xmm0     # 0x24118
addsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x48(%rbp)
movsd -0x38(%rbp), %xmm0
mulsd -0x30(%rbp), %xmm0
divsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
jmp 0x22730
movq -0x28(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)