func Exact(AA, Aa, aa int64) (p float64) {
	// Enforce AA common, aa rare
	if aa > AA {
		AA, aa = aa, AA
	}

	// baseP is the probability of the exact base configuration.
	// baseP := exactFor(AA, Aa, aa)
	baseP := memoizedExactFor.(func(int64, int64, int64) float64)(AA, Aa, aa)

	// The P value is the sum of all probabilities at this exact configuration
	// *or more extreme*. See
	// http://courses.washington.edu/b516/lectures_2009/HWE_Lecture.pdf slides
	// 21-22.
	sumP := baseP

	// Start with the most extreme heterozygote situation
	// Aa += 2 * aa
	// AA, aa = AA-aa, 0
	origAA, origAa, origaa := AA, Aa, aa

	// Left tail: Start with the exact number of hets and increase until we're
	// at an extreme.
	for i := 0; ; i, Aa, AA, aa = i+1, Aa+2, AA-1, aa-1 {
		if aa < 0 {
			break
		}

		if i == 0 {
			continue
		}

		// newest := exactFor(AA, Aa, aa)
		newest := memoizedExactFor.(func(int64, int64, int64) float64)(AA, Aa, aa)

		if newest > baseP {
			continue
		}

		if newest <= math.SmallestNonzeroFloat64 {
			break
		}

		sumP += newest
	}

	// Right tail: Start with the exact number of hets and decrease until we're
	// at an extreme.
	AA, Aa, aa = origAA, origAa, origaa
	for i := 0; ; i, Aa, AA, aa = i+1, Aa-2, AA+1, aa+1 {
		if Aa < 0 {
			break
		}

		if i == 0 {
			continue
		}

		// newest := exactFor(AA, Aa, aa)
		newest := memoizedExactFor.(func(int64, int64, int64) float64)(AA, Aa, aa)

		if newest > baseP {
			continue
		}

		if newest <= math.SmallestNonzeroFloat64 {
			break
		}

		sumP += newest
	}

	return sumP
}
// Exact computes an exact Hardy-Weinberg equilibrium P-value, based on the
// Abecasis paper, itself based on RA Fisher's method. Exact is safe to call
// from concurrent goroutines. The resources used to create this were
// http://courses.washington.edu/b516/lectures_2009/HWE_Lecture.pdf slides 21-22
// and https://www.cog-genomics.org/software/stats for sanity checks.
Exact computes an exact Hardy-Weinberg equilibrium P-value, based on the
Abecasis paper, itself based on RA Fisher's method. Exact is safe to call
from concurrent goroutines.
// Exact computes an exact Hardy - Weinberg equilibrium P - value based on the // Abecasis paper itself based on RA Fisher ' s method . Exact is safe to call // from concurrent goroutines . The resources used to create this were // http : // courses . washington . edu / b516 / lectures_2009 / HWE_Lecture . pdf slides 21 - 22 // and https : // www . cog - genomics . org / software / stats for sanity checks .
func Exact(AA, Aa, aa int64) (p float64) {
	if aa > AA {
		AA, aa = aa, AA
	}
	baseP := memoizedExactFor.(func(int64, int64, int64) float64)(AA, Aa, aa)
	sumP := baseP
	origAA, origAa, origaa := AA, Aa, aa
	for i := 0; ; i, Aa, AA, aa = i+1, Aa+2, AA-1, aa-1 {
		if aa < 0 {
			break
		}
		if i == 0 {
			continue
		}
		newest := memoizedExactFor.(func(int64, int64, int64) float64)(AA, Aa, aa)
		if newest > baseP {
			continue
		}
		if newest <= math.SmallestNonzeroFloat64 {
			break
		}
		sumP += newest
	}
	AA, Aa, aa = origAA, origAa, origaa
	for i := 0; ; i, Aa, AA, aa = i+1, Aa-2, AA+1, aa+1 {
		if Aa < 0 {
			break
		}
		if i == 0 {
			continue
		}
		newest := memoizedExactFor.(func(int64, int64, int64) float64)(AA, Aa, aa)
		if newest > baseP {
			continue
		}
		if newest <= math.SmallestNonzeroFloat64 {
			break
		}
		sumP += newest
	}
	return sumP
}
func Exact ( AA , Aa , aa int64 ) ( p float64 ) { if aa > AA { AA , aa = aa , AA } baseP := memoizedExactFor . ( func ( int64 , int64 , int64 ) float64 ) ( AA , Aa , aa ) sumP := baseP origAA , origAa , origaa := AA , Aa , aa for i := 0 ; ; i , Aa , AA , aa = i + 1 , Aa + 2 , AA - 1 , aa - 1 { if aa < 0 { break } if i == 0 { continue } newest := memoizedExactFor . ( func ( int64 , int64 , int64 ) float64 ) ( AA , Aa , aa ) if newest > baseP { continue } if newest <= math . SmallestNonzeroFloat64 { break } sumP += newest } AA , Aa , aa = origAA , origAa , origaa for i := 0 ; ; i , Aa , AA , aa = i + 1 , Aa - 2 , AA + 1 , aa + 1 { if Aa < 0 { break } if i == 0 { continue } newest := memoizedExactFor . ( func ( int64 , int64 , int64 ) float64 ) ( AA , Aa , aa ) if newest > baseP { continue } if newest <= math . SmallestNonzeroFloat64 { break } sumP += newest } return sumP }
Exact computes an exact Hardy-Weinberg equilibrium P-value, based on the
Abecasis paper, itself based on RA Fisher's method.
Exact computes an exact Hardy - Weinberg equilibrium P - value based on the Abecasis paper itself based on RA Fisher ' s method .
// Enforce AA common, aa rare // baseP is the probability of the exact base configuration. // baseP := exactFor(AA, Aa, aa) // The P value is the sum of all probabilities at this exact configuration // *or more extreme*. See // http://courses.washington.edu/b516/lectures_2009/HWE_Lecture.pdf slides // 21-22. // Start with the most extreme heterozygote situation // Aa += 2 * aa // AA, aa = AA-aa, 0 // Left tail: Start with the exact number of hets and increase until we're // at an extreme. // newest := exactFor(AA, Aa, aa) // Right tail: Start with the exact number of hets and decrease until we're // at an extreme. // newest := exactFor(AA, Aa, aa)