// File: sergiosvieira[P]ptd2ns2/ranvar.cc
// Function: GammaRandomVariable::value()
double GammaRandomVariable::value() {
	// Proposed by Marsaglia in 2000:
	// G. Marsaglia, W. W. Tsang: A simple method for gereating Gamma variables
	// ACM Transactions on mathematical software, Vol. 26, No. 3, Sept. 2000
	if (alpha_ < 1) {
		double u = rng_->uniform(1.0);
		return GammaRandomVariable(1.0 + alpha_, beta_).value() * pow(u,
				1.0 / alpha_);
	}

	double x, v, u;
	double d = alpha_ - 1.0 / 3.0;
	double c = (1.0 / 3.0) / sqrt(d);

	while (1) {
		do {
			x = rng_->normal(0.0, 1.0);
			v = 1.0 + c * x;
		} while (v <= 0);

		v = v * v * v;
		u = rng_->uniform(1.0);
		if (u < 1 - 0.0331 * x * x * x * x)
			break;
		if (log(u) < 0.5 * x * x + d * (1 - v + log(v)))
			break;
	}
	return beta_ * d * v;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movsd 0x40f1(%rip), %xmm0     # 0xa010
ucomisd 0x10(%rax), %xmm0
jbe 0x5f9e
movq -0x68(%rbp), %rax
movq 0x8(%rax), %rdi
movsd 0x40da(%rip), %xmm0     # 0xa010
callq 0x6d40
movq -0x68(%rbp), %rax
movsd %xmm0, -0x18(%rbp)
movsd 0x40c4(%rip), %xmm0     # 0xa010
addsd 0x10(%rax), %xmm0
movsd 0x18(%rax), %xmm1
leaq -0x38(%rbp), %rdi
callq 0x5eb0
leaq -0x38(%rbp), %rdi
callq 0x5f00
movq -0x68(%rbp), %rax
movsd %xmm0, -0x70(%rbp)
movsd -0x18(%rbp), %xmm0
movsd 0x4092(%rip), %xmm1     # 0xa010
divsd 0x10(%rax), %xmm1
callq 0x3330
movaps %xmm0, %xmm1
movsd -0x70(%rbp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, -0x8(%rbp)
jmp 0x6153
movq -0x68(%rbp), %rax
movsd 0x10(%rax), %xmm0
movsd 0x4279(%rip), %xmm1     # 0xa228
subsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rbp)
movsd -0x58(%rbp), %xmm0
callq 0x3160
movaps %xmm0, %xmm1
movsd 0x425b(%rip), %xmm0     # 0xa228
divsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rbp)
jmp 0x5fd8
movq -0x68(%rbp), %rax
movq 0x8(%rax), %rdi
xorps %xmm0, %xmm0
movsd 0x4025(%rip), %xmm1     # 0xa010
callq 0x71c0
movsd %xmm0, -0x40(%rbp)
movsd -0x60(%rbp), %xmm0
movsd -0x40(%rbp), %xmm1
mulsd %xmm1, %xmm0
movsd 0x4005(%rip), %xmm1     # 0xa010
addsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rbp)
xorps %xmm0, %xmm0
ucomisd -0x48(%rbp), %xmm0
jae 0x5fd8
movq -0x68(%rbp), %rax
movsd -0x48(%rbp), %xmm0
mulsd -0x48(%rbp), %xmm0
mulsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x48(%rbp)
movq 0x8(%rax), %rdi
movsd 0x3fce(%rip), %xmm0     # 0xa010
callq 0x6d40
movsd %xmm0, -0x50(%rbp)
movsd -0x50(%rbp), %xmm1
movsd 0x41d7(%rip), %xmm0     # 0xa230
mulsd -0x40(%rbp), %xmm0
mulsd -0x40(%rbp), %xmm0
mulsd -0x40(%rbp), %xmm0
movsd -0x40(%rbp), %xmm2
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd %xmm2, %xmm0
movsd 0x3f80(%rip), %xmm2     # 0xa010
addsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jbe 0x609f
jmp 0x613b
movsd -0x50(%rbp), %xmm0
callq 0x3180
movsd %xmm0, -0x80(%rbp)
movsd 0x3f92(%rip), %xmm0     # 0xa048
mulsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x78(%rbp)
movsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x88(%rbp)
movsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
movsd 0x3f2e(%rip), %xmm0     # 0xa010
subsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x98(%rbp)
movsd -0x48(%rbp), %xmm0
callq 0x3180
movsd -0x98(%rbp), %xmm4
movsd -0x90(%rbp), %xmm2
movsd -0x88(%rbp), %xmm3
movsd -0x80(%rbp), %xmm1
movaps %xmm0, %xmm5
movsd -0x78(%rbp), %xmm0
addsd %xmm5, %xmm4
mulsd %xmm4, %xmm2
mulsd %xmm3, %xmm0
addsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jbe 0x6136
jmp 0x613b
jmp 0x5fd6
movq -0x68(%rbp), %rax
movsd 0x18(%rax), %xmm0
mulsd -0x58(%rbp), %xmm0
mulsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movsd -0x8(%rbp), %xmm0
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)