You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
return prefix * exp(a * log(x * c / a) + b * log(y * c / b)) * scaled_tgamma_no_lanczos(c, pol) / (scaled_tgamma_no_lanczos(a, pol) * scaled_tgamma_no_lanczos(b, pol));
523
+
if (!(boost::math::isnormal)(power1) || !(boost::math::isnormal)(power2))
524
+
{
525
+
need_logs = true;
526
+
}
527
+
}
528
+
if (need_logs)
529
+
{
530
+
//
531
+
// We want:
532
+
//
533
+
// (xc / a)^a (yc / b)^b
534
+
//
535
+
// But we know that one or other term will over / underflow and combining the logs will be next to useless as that will cause significant cancellation.
536
+
// If we assume b > a and express z ^ b as(z ^ b / a) ^ a with z = (yc / b) then we can move one power term inside the other :
537
+
//
538
+
// ((xc / a) * (yc / b)^(b / a))^a
539
+
//
540
+
// However, we're not quite there yet, as the term being exponentiated is quite likely to be close to unity, so let:
541
+
//
542
+
// xc / a = 1 + (xb - ya) / a
543
+
//
544
+
// analogously let :
545
+
//
546
+
// 1 + p = (yc / b) ^ (b / a) = 1 + expm1((b / a) * log1p((ya - xb) / b))
547
+
//
548
+
// so putting the two together we have :
549
+
//
550
+
// exp(a * log1p((xb - ya) / a + p + p(xb - ya) / a))
551
+
//
552
+
// Analogously, when a > b we can just swap all the terms around.
553
+
//
554
+
// Finally, there are a few cases (x or y is unity) when the above logic can't be used
555
+
// or where there is no logarithmic cancellation and accuracy is better just using
0 commit comments