| 1009 | ]; |
| 1010 | candidates.sort((p, q) => p.w.abs() - q.w.abs()); |
| 1011 | |
| 1012 | let sawDegenerateCandidate = false; |
| 1013 | for (const cand of candidates) { |
| 1014 | const { kind, w } = cand; |
| 1015 | if (w.abs() > W_MAX) break; // sorted: no further candidate fits |
| 1016 | if (cand.degenerate) { |
| 1017 | sawDegenerateCandidate = true; |
| 1018 | continue; |
| 1019 | } |
| 1020 | const maxTerms = w.abs() <= W_PREFERRED ? 10_000 : 250_000; |
| 1021 | |
| 1022 | switch (kind) { |
| 1023 | case 'direct': |
| 1024 | return gauss2F1SeriesC(a, b, c, z, maxTerms); |
| 1025 | |
| 1026 | case 'pfaff': |
| 1027 | // A&S 15.3.4: (1−z)^{−a}·₂F₁(a, c−b; c; z/(z−1)) |
| 1028 | return one |
| 1029 | .sub(z) |
| 1030 | .pow(a.neg()) |
| 1031 | .mul(gauss2F1SeriesC(a, c.sub(b), c, w, maxTerms)); |
| 1032 | |
| 1033 | case 'one-minus-z': { |
| 1034 | // A&S 15.3.6, w = 1−z, s = c−a−b ∉ ℤ |