// File: gersteinlab[P]MUSIC/src/ms_combinatorics.cpp
// Function: buffer_binomial_pvalues(int, double*, int)
double** buffer_binomial_pvalues(int max_grand_total, double* log_factorials, int BINOMIAL_P_VAL_BIN_SIZE)
{
	double** binomial_vals = new double*[max_grand_total + 2];

	for(int cur_grand_total = 0; cur_grand_total <= max_grand_total; cur_grand_total++)
	{
		binomial_vals[cur_grand_total] = new double[cur_grand_total / BINOMIAL_P_VAL_BIN_SIZE + 10];

		double log_flip = log(.5);
		double cur_p_val = xlog(0.0);
		for(int cur_sig = 0; cur_sig <= cur_grand_total; cur_sig++)
		{
			double log_cur_half_pow = log_flip * cur_grand_total;
			double log_cur_perm = 0.0; // = xlog(1.0).

			// Compute the current permutation.
			log_cur_perm = xlog_div(log_factorials[cur_grand_total], xlog_mul(log_factorials[cur_sig], log_factorials[cur_grand_total-cur_sig]));
			cur_p_val = xlog_sum(cur_p_val, xlog_mul(log_cur_perm, log_cur_half_pow));

			// Add this value in case.
			if(cur_sig % BINOMIAL_P_VAL_BIN_SIZE == 0)
			{
				binomial_vals[cur_grand_total][cur_sig / BINOMIAL_P_VAL_BIN_SIZE] = cur_p_val;
			}
		} // i loop.
	} // grand_total

	return(binomial_vals);
}

// Assembly:
subq $0x68, %rsp
movl %edi, 0x64(%rsp)
movq %rsi, 0x58(%rsp)
movl %edx, 0x54(%rsp)
movl 0x64(%rsp), %eax
addl $0x2, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq %rax, 0x48(%rsp)
movl $0x0, 0x44(%rsp)
movl 0x44(%rsp), %eax
cmpl 0x64(%rsp), %eax
jg 0x3f390
movl 0x44(%rsp), %eax
cltd
idivl 0x54(%rsp)
addl $0xa, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq %rax, %rdx
movq 0x48(%rsp), %rax
movslq 0x44(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movsd 0x12dda(%rip), %xmm0    # 0x52038
callq 0x2140
movsd %xmm0, 0x38(%rsp)
xorps %xmm0, %xmm0
callq 0x441e0
movsd %xmm0, 0x30(%rsp)
movl $0x0, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x44(%rsp), %eax
jg 0x3f37e
movsd 0x38(%rsp), %xmm0
cvtsi2sdl 0x44(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x58(%rsp), %rax
movslq 0x44(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x58(%rsp), %rax
movslq 0x2c(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x58(%rsp), %rax
movl 0x44(%rsp), %ecx
subl 0x2c(%rsp), %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm1
callq 0x44510
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
callq 0x445a0
movsd %xmm0, 0x18(%rsp)
movsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
callq 0x44510
movaps %xmm0, %xmm1
movsd 0x10(%rsp), %xmm0
callq 0x44310
movsd %xmm0, 0x30(%rsp)
movl 0x2c(%rsp), %eax
cltd
idivl 0x54(%rsp)
cmpl $0x0, %edx
jne 0x3f36c
movsd 0x30(%rsp), %xmm0
movq 0x48(%rsp), %rax
movslq 0x44(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, (%rsp)
movl 0x2c(%rsp), %eax
cltd
idivl 0x54(%rsp)
movl %eax, %ecx
movq (%rsp), %rax
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0x3f36e
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x3f27f
jmp 0x3f380
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0x3f208
movq 0x48(%rsp), %rax
addq $0x68, %rsp
retq
nopw (%rax,%rax)