Traktor/myenv/Lib/site-packages/scipy/special/tests/test_hyp2f1.py
2024-05-23 01:57:24 +02:00

2181 lines
77 KiB
Python

"""Tests for hyp2f1 for complex values.
Author: Albert Steppi, with credit to Adam Kullberg (FormerPhycisist) for
the implementation of mp_hyp2f1 below, which modifies mpmath's hyp2f1 to
return the same branch as scipy's on the standard branch cut.
"""
import sys
import pytest
import numpy as np
from typing import NamedTuple
from numpy.testing import assert_allclose
from scipy.special import hyp2f1
from scipy.special._testutils import check_version, MissingModule
try:
import mpmath
except ImportError:
mpmath = MissingModule("mpmath")
def mp_hyp2f1(a, b, c, z):
"""Return mpmath hyp2f1 calculated on same branch as scipy hyp2f1.
For most values of a,b,c mpmath returns the x - 0j branch of hyp2f1 on the
branch cut x=(1,inf) whereas scipy's hyp2f1 calculates the x + 0j branch.
Thus, to generate the right comparison values on the branch cut, we
evaluate mpmath.hyp2f1 at x + 1e-15*j.
The exception to this occurs when c-a=-m in which case both mpmath and
scipy calculate the x + 0j branch on the branch cut. When this happens
mpmath.hyp2f1 will be evaluated at the original z point.
"""
on_branch_cut = z.real > 1.0 and abs(z.imag) < 1.0e-15
cond1 = abs(c - a - round(c - a)) < 1.0e-15 and round(c - a) <= 0
cond2 = abs(c - b - round(c - b)) < 1.0e-15 and round(c - b) <= 0
# Make sure imaginary part is *exactly* zero
if on_branch_cut:
z = z.real + 0.0j
if on_branch_cut and not (cond1 or cond2):
z_mpmath = z.real + 1.0e-15j
else:
z_mpmath = z
return complex(mpmath.hyp2f1(a, b, c, z_mpmath))
class Hyp2f1TestCase(NamedTuple):
a: float
b: float
c: float
z: complex
expected: complex
rtol: float
class TestHyp2f1:
"""Tests for hyp2f1 for complex values.
Expected values for test cases were computed using mpmath. See
`scipy.special._precompute.hyp2f1_data`. The verbose style of specifying
test cases is used for readability and to make it easier to mark individual
cases as expected to fail. Expected failures are used to highlight cases
where improvements are needed. See
`scipy.special._precompute.hyp2f1_data.make_hyp2f1_test_cases` for a
function to generate the boilerplate for the test cases.
Assertions have been added to each test to ensure that the test cases match
the situations that are intended. A final test `test_test_hyp2f1` checks
that the expected values in the test cases actually match what is computed
by mpmath. This test is marked slow even though it isn't particularly slow
so that it won't run by default on continuous integration builds.
"""
@pytest.mark.parametrize(
"hyp2f1_test_case",
[
pytest.param(
Hyp2f1TestCase(
a=0.5,
b=0.2,
c=-10,
z=0.2 + 0.2j,
expected=np.inf + 0j,
rtol=0
)
),
pytest.param(
Hyp2f1TestCase(
a=0.5,
b=0.2,
c=-10,
z=0 + 0j,
expected=1 + 0j,
rtol=0
),
),
pytest.param(
Hyp2f1TestCase(
a=0.5,
b=0,
c=-10,
z=0.2 + 0.2j,
expected=1 + 0j,
rtol=0
),
),
pytest.param(
Hyp2f1TestCase(
a=0.5,
b=0,
c=0,
z=0.2 + 0.2j,
expected=1 + 0j,
rtol=0,
),
),
pytest.param(
Hyp2f1TestCase(
a=0.5,
b=0.2,
c=0,
z=0.2 + 0.2j,
expected=np.inf + 0j,
rtol=0,
),
),
pytest.param(
Hyp2f1TestCase(
a=0.5,
b=0.2,
c=0,
z=0 + 0j,
expected=np.nan + 0j,
rtol=0,
),
),
pytest.param(
Hyp2f1TestCase(
a=0.5,
b=-5,
c=-10,
z=0.2 + 0.2j,
expected=(1.0495404166666666+0.05708208333333334j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=0.5,
b=-10,
c=-10,
z=0.2 + 0.2j,
expected=(1.092966013125+0.13455014673750001j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-10,
b=-20,
c=-10,
z=0.2 + 0.2j,
expected=(-0.07712512000000005+0.12752814080000005j),
rtol=1e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1,
b=3.2,
c=-1,
z=0.2 + 0.2j,
expected=(1.6400000000000001+0.6400000000000001j),
rtol=1e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-2,
b=1.2,
c=-4,
z=1 + 0j,
expected=1.8200000000000001 + 0j,
rtol=1e-15,
),
),
]
)
def test_c_non_positive_int(self, hyp2f1_test_case):
a, b, c, z, expected, rtol = hyp2f1_test_case
assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
@pytest.mark.parametrize(
"hyp2f1_test_case",
[
pytest.param(
Hyp2f1TestCase(
a=0.5,
b=0.2,
c=1.5,
z=1 + 0j,
expected=1.1496439092239847 + 0j,
rtol=1e-15
),
),
pytest.param(
Hyp2f1TestCase(
a=12.3,
b=8.0,
c=20.31,
z=1 + 0j,
expected=69280986.75273195 + 0j,
rtol=1e-15
),
),
pytest.param(
Hyp2f1TestCase(
a=290.2,
b=321.5,
c=700.1,
z=1 + 0j,
expected=1.3396562400934e117 + 0j,
rtol=1e-12,
),
),
# Note that here even mpmath produces different results for
# results that should be equivalent.
pytest.param(
Hyp2f1TestCase(
a=9.2,
b=621.5,
c=700.1,
z=(1+0j),
expected=(952726652.4158565+0j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=621.5,
b=9.2,
c=700.1,
z=(1+0j),
expected=(952726652.4160284+0j),
rtol=5e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=-101.2,
b=-400.4,
c=-172.1,
z=(1+0j),
expected=(2.2253618341394838e+37+0j),
rtol=1e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-400.4,
b=-101.2,
c=-172.1,
z=(1+0j),
expected=(2.2253618341394838e+37+0j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=172.5,
b=-201.3,
c=151.2,
z=(1+0j),
expected=(7.072266653650905e-135+0j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-201.3,
b=172.5,
c=151.2,
z=(1+0j),
expected=(7.072266653650905e-135+0j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-102.1,
b=-20.3,
c=1.3,
z=1 + 0j,
expected=2.7899070752746906e22 + 0j,
rtol=3e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-202.6,
b=60.3,
c=1.5,
z=1 + 0j,
expected=-1.3113641413099326e-56 + 0j,
rtol=1e-12,
),
),
],
)
def test_unital_argument(self, hyp2f1_test_case):
"""Tests for case z = 1, c - a - b > 0.
Expected answers computed using mpmath.
"""
a, b, c, z, expected, rtol = hyp2f1_test_case
assert z == 1 and c - a - b > 0 # Tests the test
assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
@pytest.mark.parametrize(
"hyp2f1_test_case",
[
pytest.param(
Hyp2f1TestCase(
a=0.5,
b=0.2,
c=1.3,
z=-1 + 0j,
expected=0.9428846409614143 + 0j,
rtol=1e-15),
),
pytest.param(
Hyp2f1TestCase(
a=12.3,
b=8.0,
c=5.300000000000001,
z=-1 + 0j,
expected=-4.845809986595704e-06 + 0j,
rtol=1e-15
),
),
pytest.param(
Hyp2f1TestCase(
a=221.5,
b=90.2,
c=132.3,
z=-1 + 0j,
expected=2.0490488728377282e-42 + 0j,
rtol=1e-7,
),
),
pytest.param(
Hyp2f1TestCase(
a=-102.1,
b=-20.3,
c=-80.8,
z=-1 + 0j,
expected=45143784.46783885 + 0j,
rtol=1e-7,
),
marks=pytest.mark.xfail(
condition=sys.maxsize < 2**32,
reason="Fails on 32 bit.",
)
),
],
)
def test_special_case_z_near_minus_1(self, hyp2f1_test_case):
"""Tests for case z ~ -1, c ~ 1 + a - b
Expected answers computed using mpmath.
"""
a, b, c, z, expected, rtol = hyp2f1_test_case
assert abs(1 + a - b - c) < 1e-15 and abs(z + 1) < 1e-15
assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
@pytest.mark.parametrize(
"hyp2f1_test_case",
[
pytest.param(
Hyp2f1TestCase(
a=-4,
b=2.02764642551431,
c=1.0561196186065624,
z=(0.9473684210526314-0.10526315789473695j),
expected=(0.0031961077109535375-0.0011313924606557173j),
rtol=1e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=-8,
b=-7.937789122896016,
c=-15.964218273004214,
z=(2-0.10526315789473695j),
expected=(0.005543763196412503-0.0025948879065698306j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-8,
b=8.095813935368371,
c=4.0013768449590685,
z=(0.9473684210526314-0.10526315789473695j),
expected=(-0.0003054674127221263-9.261359291755414e-05j),
rtol=1e-10,
),
),
pytest.param(
Hyp2f1TestCase(
a=-4,
b=-3.956227226099288,
c=-3.9316537064827854,
z=(1.1578947368421053-0.3157894736842106j),
expected=(-0.0020809502580892937-0.0041877333232365095j),
rtol=5e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=-4,
c=2.050308316530781,
z=(0.9473684210526314-0.10526315789473695j),
expected=(0.0011282435590058734+0.0002027062303465851j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=-8,
c=-15.964218273004214,
z=(1.3684210526315788+0.10526315789473673j),
expected=(-9.134907719238265e-05-0.00040219233987390723j),
rtol=5e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=-4,
c=4.0013768449590685,
z=(0.9473684210526314-0.10526315789473695j),
expected=(-0.000519013062087489-0.0005855883076830948j),
rtol=5e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=-10000,
b=2.2,
c=93459345.3,
z=(2+2j),
expected=(0.9995292071559088-0.00047047067522659253j),
rtol=1e-12,
),
),
]
)
def test_a_b_negative_int(self, hyp2f1_test_case):
a, b, c, z, expected, rtol = hyp2f1_test_case
assert a == int(a) and a < 0 or b == int(b) and b < 0 # Tests the test
assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
@pytest.mark.parametrize(
"hyp2f1_test_case",
[
pytest.param(
Hyp2f1TestCase(
a=-0.5,
b=-0.9629749245209605,
c=-15.5,
z=(1.1578947368421053-1.1578947368421053j),
expected=(0.9778506962676361+0.044083801141231616j),
rtol=3e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.5,
b=-3.9316537064827854,
c=1.5,
z=(0.9473684210526314-0.10526315789473695j),
expected=(4.0793167523167675-10.11694246310966j),
rtol=6e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.5,
b=-0.9629749245209605,
c=2.5,
z=(1.1578947368421053-0.10526315789473695j),
expected=(-2.9692999501916915+0.6394599899845594j),
rtol=1e-11,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.5,
b=-0.9629749245209605,
c=-15.5,
z=(1.5789473684210522-1.1578947368421053j),
expected=(0.9493076367106102-0.04316852977183447j),
rtol=1e-11,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=-0.5,
c=-15.5,
z=(0.5263157894736841+0.10526315789473673j),
expected=(0.9844377175631795-0.003120587561483841j),
rtol=1e-10,
),
),
],
)
def test_a_b_neg_int_after_euler_hypergeometric_transformation(
self, hyp2f1_test_case
):
a, b, c, z, expected, rtol = hyp2f1_test_case
assert ( # Tests the test
(abs(c - a - int(c - a)) < 1e-15 and c - a < 0) or
(abs(c - b - int(c - b)) < 1e-15 and c - b < 0)
)
assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
@pytest.mark.parametrize(
"hyp2f1_test_case",
[
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=-0.9629749245209605,
c=-15.963511401609862,
z=(0.10526315789473673-0.3157894736842106j),
expected=(0.9941449585778349+0.01756335047931358j),
rtol=1e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.0272592605282642,
b=-0.9629749245209605,
c=-15.963511401609862,
z=(0.5263157894736841+0.5263157894736841j),
expected=(1.0388722293372104-0.09549450380041416j),
rtol=5e-11,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=1.0561196186065624,
c=-7.93846038215665,
z=(0.10526315789473673+0.7368421052631575j),
expected=(2.1948378809826434+24.934157235172222j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=16.088264119063613,
c=8.031683612216888,
z=(0.3157894736842106-0.736842105263158j),
expected=(-0.4075277891264672-0.06819344579666956j),
rtol=2e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=2.050308316530781,
c=8.031683612216888,
z=(0.7368421052631575-0.10526315789473695j),
expected=(2.833535530740603-0.6925373701408158j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=2.050308316530781,
c=4.078873014294075,
z=(0.10526315789473673-0.3157894736842106j),
expected=(1.005347176329683-0.3580736009337313j),
rtol=5e-16,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=-0.9629749245209605,
c=-15.963511401609862,
z=(0.3157894736842106-0.5263157894736843j),
expected=(0.9824353641135369+0.029271018868990268j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=-0.9629749245209605,
c=-159.63511401609862,
z=(0.3157894736842106-0.5263157894736843j),
expected=(0.9982436200365834+0.002927268199671111j),
rtol=1e-7,
),
marks=pytest.mark.xfail(reason="Poor convergence.")
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=16.088264119063613,
c=8.031683612216888,
z=(0.5263157894736841-0.5263157894736843j),
expected=(-0.6906825165778091+0.8176575137504892j),
rtol=5e-13,
),
),
]
)
def test_region1(self, hyp2f1_test_case):
"""|z| < 0.9 and real(z) >= 0."""
a, b, c, z, expected, rtol = hyp2f1_test_case
assert abs(z) < 0.9 and z.real >= 0 # Tests the test
assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
@pytest.mark.parametrize(
"hyp2f1_test_case",
[
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=1.0561196186065624,
c=4.078873014294075,
z=(-0.3157894736842106+0.7368421052631575j),
expected=(0.7751915029081136+0.24068493258607315j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.087593263474208,
b=16.088264119063613,
c=2.0397202577726152,
z=(-0.9473684210526316-0.3157894736842106j),
expected=(6.564549348474962e-07+1.6761570598334562e-06j),
rtol=5e-09,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.0272592605282642,
b=2.050308316530781,
c=16.056809865262608,
z=(-0.10526315789473695-0.10526315789473695j),
expected=(0.9862043298997204-0.013293151372712681j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=8.077282662161238,
c=16.056809865262608,
z=(-0.3157894736842106-0.736842105263158j),
expected=(0.16163826638754716-0.41378530376373734j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=2.050308316530781,
c=-0.906685989801748,
z=(-0.5263157894736843+0.3157894736842106j),
expected=(-6.256871535165936+0.13824973858225484j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=8.077282662161238,
c=-3.9924618758357022,
z=(-0.9473684210526316-0.3157894736842106j),
expected=(75.54672526086316+50.56157041797548j),
rtol=5e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.087593263474208,
b=8.077282662161238,
c=-1.9631175993998025,
z=(-0.5263157894736843+0.5263157894736841j),
expected=(282.0602536306534-82.31597306936214j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.095813935368371,
b=-3.9316537064827854,
c=8.031683612216888,
z=(-0.5263157894736843-0.10526315789473695j),
expected=(5.179603735575851+1.4445374002099813j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=-7.949900487447654,
c=1.0651378143226575,
z=(-0.3157894736842106-0.9473684210526316j),
expected=(2317.623517606141-269.51476321010324j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.087593263474208,
b=-1.92872979730171,
c=2.0397202577726152,
z=(-0.736842105263158-0.3157894736842106j),
expected=(29.179154096175836+22.126690357535043j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.095813935368371,
b=-3.9316537064827854,
c=-15.963511401609862,
z=(-0.736842105263158-0.10526315789473695j),
expected=(0.20820247892032057-0.04763956711248794j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.0272592605282642,
b=-15.964218273004214,
c=-1.9631175993998025,
z=(-0.3157894736842106-0.5263157894736843j),
expected=(-157471.63920142158+991294.0587828817j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.095813935368371,
b=-7.949900487447654,
c=-7.93846038215665,
z=(-0.10526315789473695-0.10526315789473695j),
expected=(0.30765349653210194-0.2979706363594157j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.956227226099288,
b=1.0561196186065624,
c=8.031683612216888,
z=(-0.9473684210526316-0.10526315789473695j),
expected=(1.6787607400597109+0.10056620134616838j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=16.088264119063613,
c=4.078873014294075,
z=(-0.5263157894736843-0.736842105263158j),
expected=(7062.07842506049-12768.77955655703j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=16.088264119063613,
c=2.0397202577726152,
z=(-0.3157894736842106+0.7368421052631575j),
expected=(54749.216391029935-23078.144720887536j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.956227226099288,
b=1.0561196186065624,
c=-0.906685989801748,
z=(-0.10526315789473695-0.10526315789473695j),
expected=(1.21521766411428-4.449385173946672j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.980848054962111,
b=4.0013768449590685,
c=-1.9631175993998025,
z=(-0.736842105263158+0.5263157894736841j),
expected=(19234693144.196907+1617913967.7294445j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.9214641416286231,
b=1.0561196186065624,
c=-15.963511401609862,
z=(-0.5263157894736843+0.3157894736842106j),
expected=(0.9345201094534371+0.03745712558992195j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=-0.9629749245209605,
c=2.0397202577726152,
z=(-0.10526315789473695+0.10526315789473673j),
expected=(0.605732446296829+0.398171533680972j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.9214641416286231,
b=-15.964218273004214,
c=2.0397202577726152,
z=(-0.10526315789473695-0.5263157894736843j),
expected=(-9.753761888305416-4.590126012666959j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.956227226099288,
b=-1.92872979730171,
c=2.0397202577726152,
z=(-0.10526315789473695+0.3157894736842106j),
expected=(0.45587226291120714+1.0694545265819797j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=-7.949900487447654,
c=-0.906685989801748,
z=(-0.736842105263158+0.3157894736842106j),
expected=(12.334808243233418-76.26089051819054j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=-7.949900487447654,
c=-15.963511401609862,
z=(-0.5263157894736843+0.10526315789473673j),
expected=(1.2396019687632678-0.047507973161146286j),
rtol=1e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.980848054962111,
b=-0.9629749245209605,
c=-0.906685989801748,
z=(-0.3157894736842106-0.5263157894736843j),
expected=(97.7889554372208-18.999754543400016j),
rtol=5e-13,
),
),
]
)
def test_region2(self, hyp2f1_test_case):
"""|z| < 1 and real(z) < 0."""
a, b, c, z, expected, rtol = hyp2f1_test_case
assert abs(z) < 1 and z.real < 0 # Tests the test
assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
@pytest.mark.parametrize(
"hyp2f1_test_case",
[
pytest.param(
Hyp2f1TestCase(
a=16.25,
b=4.25,
c=2.5,
z=(0.4931034482758623-0.7965517241379311j),
expected=(38.41207903409937-30.510151276075792j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.0,
b=16.087593263474208,
c=16.088264119063613,
z=(0.5689655172413794-0.7965517241379311j),
expected=(-0.6667857912761286-1.0206224321443573j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.0,
b=1.0272592605282642,
c=-7.949900487447654,
z=(0.4931034482758623-0.7965517241379311j),
expected=(1679024.1647997478-2748129.775857212j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=16.0,
c=-7.949900487447654,
z=(0.4931034482758623-0.7965517241379311j),
expected=(424747226301.16986-1245539049327.2856j),
rtol=1e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=-15.964218273004214,
c=4.0,
z=(0.4931034482758623-0.7965517241379311j),
expected=(-0.0057826199201757595+0.026359861999025885j),
rtol=5e-06,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=-0.9629749245209605,
c=2.0397202577726152,
z=(0.5689655172413794-0.7965517241379311j),
expected=(0.4671901063492606+0.7769632229834897j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.0,
b=-3.956227226099288,
c=-7.949900487447654,
z=(0.4931034482758623+0.7965517241379312j),
expected=(0.9422283708145973+1.3476905754773343j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.0,
b=-15.980848054962111,
c=-15.964218273004214,
z=(0.4931034482758623-0.7965517241379311j),
expected=(0.4168719497319604-0.9770953555235625j),
rtol=5e-10,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.5,
b=16.088264119063613,
c=2.5,
z=(0.5689655172413794+0.7965517241379312j),
expected=(1.279096377550619-2.173827694297929j),
rtol=5e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.9214641416286231,
b=4.0013768449590685,
c=2.0397202577726152,
z=(0.4931034482758623+0.7965517241379312j),
expected=(-2.071520656161738-0.7846098268395909j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=8.0,
c=-0.9629749245209605,
z=(0.5689655172413794-0.7965517241379311j),
expected=(-7.740015495862889+3.386766435696699j),
rtol=5e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.9214641416286231,
b=16.088264119063613,
c=-7.93846038215665,
z=(0.4931034482758623+0.7965517241379312j),
expected=(-6318.553685853241-7133.416085202879j),
rtol=1e-10,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.980848054962111,
b=-3.9316537064827854,
c=16.056809865262608,
z=(0.5689655172413794+0.7965517241379312j),
expected=(-0.8854577905547399+8.135089099967278j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.9214641416286231,
b=-0.9629749245209605,
c=4.078873014294075,
z=(0.4931034482758623+0.7965517241379312j),
expected=(1.224291301521487+0.36014711766402485j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.75,
b=-0.75,
c=-1.5,
z=(0.4931034482758623+0.7965517241379312j),
expected=(-1.5765685855028473-3.9399766961046323j),
rtol=1e-3,
),
marks=pytest.mark.xfail(
reason="Unhandled parameters."
)
),
pytest.param(
Hyp2f1TestCase(
a=-15.980848054962111,
b=-1.92872979730171,
c=-7.93846038215665,
z=(0.5689655172413794-0.7965517241379311j),
expected=(56.794588688231194+4.556286783533971j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.5,
b=4.5,
c=2.050308316530781,
z=(0.5689655172413794+0.7965517241379312j),
expected=(-4.251456563455306+6.737837111569671j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.5,
b=8.5,
c=-1.92872979730171,
z=(0.4931034482758623-0.7965517241379311j),
expected=(2177143.9156599627-3313617.2748088865j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.5,
b=-1.5,
c=4.0013768449590685,
z=(0.4931034482758623-0.7965517241379311j),
expected=(0.45563554481603946+0.6212000158060831j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.5,
b=-7.5,
c=-15.964218273004214,
z=(0.4931034482758623+0.7965517241379312j),
expected=(61.03201617828073-37.185626416756214j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.5,
b=16.5,
c=4.0013768449590685,
z=(0.4931034482758623+0.7965517241379312j),
expected=(-33143.425963520735+20790.608514722644j),
rtol=1e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.5,
b=4.5,
c=-0.9629749245209605,
z=(0.5689655172413794+0.7965517241379312j),
expected=(30.778600270824423-26.65160354466787j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.5,
b=-3.5,
c=16.088264119063613,
z=(0.5689655172413794-0.7965517241379311j),
expected=(1.0629792615560487-0.08308454486044772j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.5,
b=-7.5,
c=-0.9629749245209605,
z=(0.4931034482758623-0.7965517241379311j),
expected=(17431.571802591767+3553.7129767034507j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.25,
b=8.25,
c=16.5,
z=(0.11379310344827598+0.9482758620689657j),
expected=(0.4468600750211926+0.7313214934036885j),
rtol=1e-3,
),
marks=pytest.mark.xfail(
reason="Unhandled parameters."
)
),
pytest.param(
Hyp2f1TestCase(
a=8.25,
b=16.25,
c=4.5,
z=(0.3413793103448277+0.8724137931034486j),
expected=(-3.905704438293991+3.693347860329299j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.25,
b=4.25,
c=-0.5,
z=(0.11379310344827598-0.9482758620689655j),
expected=(-40.31777941834244-89.89852492432011j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.0272592605282642,
b=8.0,
c=-15.964218273004214,
z=(0.11379310344827598-0.9482758620689655j),
expected=(52584.347773055284-109197.86244309516j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.095813935368371,
b=-15.964218273004214,
c=16.056809865262608,
z=(0.03793103448275881+0.9482758620689657j),
expected=(-1.187733570412592-1.5147865053584582j),
rtol=5e-10,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=-3.9316537064827854,
c=1.0651378143226575,
z=(0.26551724137931054+0.9482758620689657j),
expected=(13.077494677898947+35.071599628224966j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=-3.5,
c=-3.5,
z=(0.26551724137931054+0.8724137931034486j),
expected=(-0.5359656237994614-0.2344483936591811j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.25,
b=-3.75,
c=-1.5,
z=(0.26551724137931054+0.9482758620689657j),
expected=(1204.8114871663133+64.41022826840198j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.9214641416286231,
b=16.0,
c=4.0013768449590685,
z=(0.03793103448275881-0.9482758620689655j),
expected=(-9.85268872413994+7.011107558429154j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=16.0,
c=4.0013768449590685,
z=(0.3413793103448277-0.8724137931034484j),
expected=(528.5522951158454-1412.21630264791j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.5,
b=1.0561196186065624,
c=-7.5,
z=(0.4172413793103451+0.8724137931034486j),
expected=(133306.45260685298+256510.7045225382j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=8.077282662161238,
c=-15.963511401609862,
z=(0.3413793103448277-0.8724137931034484j),
expected=(-0.998555715276967+2.774198742229889j),
rtol=5e-11,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.75,
b=-0.75,
c=1.5,
z=(0.11379310344827598-0.9482758620689655j),
expected=(2.072445019723025-2.9793504811373515j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.5,
b=-1.92872979730171,
c=1.5,
z=(0.11379310344827598-0.9482758620689655j),
expected=(-41.87581944176649-32.52980303527139j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.75,
b=-15.75,
c=-0.5,
z=(0.11379310344827598-0.9482758620689655j),
expected=(-3729.6214864209774-30627.510509112635j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.956227226099288,
b=-15.964218273004214,
c=-0.906685989801748,
z=(0.03793103448275881+0.9482758620689657j),
expected=(-131615.07820609974+145596.13384245415j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.5,
b=16.5,
c=16.088264119063613,
z=(0.26551724137931054+0.8724137931034486j),
expected=(0.18981844071070744+0.7855036242583742j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.5,
b=8.5,
c=-3.9316537064827854,
z=(0.11379310344827598-0.9482758620689655j),
expected=(110224529.2376068+128287212.04290268j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.5,
b=-7.5,
c=4.0013768449590685,
z=(0.3413793103448277-0.8724137931034484j),
expected=(0.2722302180888523-0.21790187837266162j),
rtol=1e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.5,
b=-7.5,
c=-15.964218273004214,
z=(0.11379310344827598-0.9482758620689655j),
expected=(-2.8252338010989035+2.430661949756161j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.5,
b=16.5,
c=4.0013768449590685,
z=(0.03793103448275881+0.9482758620689657j),
expected=(-20.604894257647945+74.5109432558078j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.5,
b=8.5,
c=-0.9629749245209605,
z=(0.3413793103448277+0.8724137931034486j),
expected=(-2764422.521269463-3965966.9965808876j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.5,
b=-0.5,
c=1.0561196186065624,
z=(0.26551724137931054+0.9482758620689657j),
expected=(1.2262338560994905+0.6545051266925549j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.5,
b=-15.5,
c=-7.949900487447654,
z=(0.4172413793103451-0.8724137931034484j),
expected=(-2258.1590330318213+8860.193389158803j),
rtol=1.4e-10,
),
),
]
)
def test_region4(self, hyp2f1_test_case):
"""0.9 <= |z| <= 1 and |1 - z| >= 1.
This region is unhandled by of the standard transformations and
needs special care.
"""
a, b, c, z, expected, rtol = hyp2f1_test_case
assert 0.9 <= abs(z) <= 1 and abs(1 - z) >= 0.9 # Tests the test
assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
@pytest.mark.parametrize(
"hyp2f1_test_case",
[
pytest.param(
Hyp2f1TestCase(
a=4.5,
b=16.088264119063613,
c=8.5,
z=(0.6448275862068968+0.8724137931034486j),
expected=(0.018601324701770394-0.07618420586062377j),
rtol=5e-08,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.25,
b=4.25,
c=4.5,
z=(0.6448275862068968-0.8724137931034484j),
expected=(-1.391549471425551-0.118036604903893j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=2.050308316530781,
c=-1.9631175993998025,
z=(0.6448275862068968+0.8724137931034486j),
expected=(-2309.178768155151-1932.7247727595172j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.087593263474208,
b=1.0,
c=-15.964218273004214,
z=(0.6448275862068968+0.8724137931034486j),
expected=(85592537010.05054-8061416766688.324j),
rtol=2e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.095813935368371,
b=-0.5,
c=1.5,
z=(0.6448275862068968+0.8724137931034486j),
expected=(1.2334498208515172-2.1639498536219732j),
rtol=5e-11,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.087593263474208,
b=-15.964218273004214,
c=4.0,
z=(0.6448275862068968+0.8724137931034486j),
expected=(102266.35398605966-44976.97828737755j),
rtol=1e-3,
),
marks=pytest.mark.xfail(
reason="Unhandled parameters."
)
),
pytest.param(
Hyp2f1TestCase(
a=4.0,
b=-3.956227226099288,
c=-15.964218273004214,
z=(0.6448275862068968-0.8724137931034484j),
expected=(-2.9590030930007236-4.190770764773225j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=-15.5,
c=-7.5,
z=(0.5689655172413794-0.8724137931034484j),
expected=(-112554838.92074208+174941462.9202412j),
rtol=5e-05,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.980848054962111,
b=2.050308316530781,
c=1.0,
z=(0.6448275862068968-0.8724137931034484j),
expected=(3.7519882374080145+7.360753798667486j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=2.050308316530781,
c=4.0,
z=(0.6448275862068968-0.8724137931034484j),
expected=(0.000181132943964693+0.07742903103815582j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=4.0013768449590685,
c=-1.9631175993998025,
z=(0.5689655172413794+0.8724137931034486j),
expected=(386338.760913596-386166.51762171905j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.980848054962111,
b=8.0,
c=-1.92872979730171,
z=(0.6448275862068968+0.8724137931034486j),
expected=(1348667126.3444858-2375132427.158893j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.5,
b=-0.9629749245209605,
c=4.5,
z=(0.5689655172413794+0.8724137931034486j),
expected=(1.428353429538678+0.6472718120804372j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=-0.9629749245209605,
c=2.0397202577726152,
z=(0.5689655172413794-0.8724137931034484j),
expected=(3.1439267526119643-3.145305240375117j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.9214641416286231,
b=-15.964218273004214,
c=-7.93846038215665,
z=(0.6448275862068968-0.8724137931034484j),
expected=(75.27467675681773+144.0946946292215j),
rtol=1e-07,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.75,
b=-7.75,
c=-7.5,
z=(0.5689655172413794+0.8724137931034486j),
expected=(-0.3699450626264222+0.8732812475910993j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.5,
b=16.5,
c=1.0561196186065624,
z=(0.5689655172413794-0.8724137931034484j),
expected=(5.5361025821300665-2.4709693474656285j),
rtol=5e-09,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.5,
b=8.5,
c=-3.9316537064827854,
z=(0.6448275862068968-0.8724137931034484j),
expected=(-782805.6699207705-537192.581278909j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.5,
b=-15.5,
c=1.0561196186065624,
z=(0.6448275862068968+0.8724137931034486j),
expected=(12.345113400639693-14.993248992902007j),
rtol=0.0005,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.5,
b=-0.5,
c=-15.964218273004214,
z=(0.6448275862068968+0.8724137931034486j),
expected=(23.698109392667842+97.15002033534108j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.5,
b=16.5,
c=4.0013768449590685,
z=(0.6448275862068968-0.8724137931034484j),
expected=(1115.2978631811834+915.9212658718577j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.5,
b=16.5,
c=-0.9629749245209605,
z=(0.6448275862068968+0.8724137931034486j),
expected=(642077722221.6489+535274495398.21027j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.5,
b=-3.5,
c=4.0013768449590685,
z=(0.5689655172413794+0.8724137931034486j),
expected=(-5.689219222945697+16.877463062787143j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.5,
b=-1.5,
c=-0.9629749245209605,
z=(0.5689655172413794-0.8724137931034484j),
expected=(-44.32070290703576+1026.9127058617403j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.25,
b=2.25,
c=4.5,
z=(0.11379310344827598-1.024137931034483j),
expected=(-0.021965227124574663+0.009908300237809064j),
rtol=1e-3,
),
marks=pytest.mark.xfail(
reason="Unhandled parameters."
)
),
pytest.param(
Hyp2f1TestCase(
a=2.02764642551431,
b=1.5,
c=16.5,
z=(0.26551724137931054+1.024137931034483j),
expected=(1.0046072901244183+0.19945500134119992j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.087593263474208,
b=1.0,
c=-3.9316537064827854,
z=(0.3413793103448277+0.9482758620689657j),
expected=(21022.30133421465+49175.98317370489j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=16.088264119063613,
c=-1.9631175993998025,
z=(0.4172413793103451-0.9482758620689655j),
expected=(-7024239.358547302+2481375.02681063j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.25,
b=-15.75,
c=1.5,
z=(0.18965517241379315+1.024137931034483j),
expected=(92371704.94848-403546832.548352j),
rtol=5e-06,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.5,
b=-7.949900487447654,
c=8.5,
z=(0.26551724137931054-1.024137931034483j),
expected=(1.9335109845308265+5.986542524829654j),
rtol=5e-10,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.095813935368371,
b=-1.92872979730171,
c=-7.93846038215665,
z=(0.4931034482758623+0.8724137931034486j),
expected=(-122.52639696039328-59.72428067512221j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.25,
b=-1.75,
c=-1.5,
z=(0.4931034482758623+0.9482758620689657j),
expected=(-90.40642053579428+50.50649180047921j),
rtol=5e-08,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.5,
b=8.077282662161238,
c=16.5,
z=(0.4931034482758623+0.9482758620689657j),
expected=(-0.2155745818150323-0.564628986876639j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=1.0561196186065624,
c=8.031683612216888,
z=(0.4172413793103451-0.9482758620689655j),
expected=(0.9503140488280465+0.11574960074292677j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.75,
b=2.25,
c=-15.5,
z=(0.4172413793103451+0.9482758620689657j),
expected=(0.9285862488442175+0.8203699266719692j),
rtol=5e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.75,
b=4.25,
c=-15.5,
z=(0.3413793103448277-0.9482758620689655j),
expected=(-1.0509834850116921-1.1145522325486075j),
rtol=1e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=-0.9629749245209605,
c=2.0397202577726152,
z=(0.4931034482758623-0.9482758620689655j),
expected=(2.88119116536769-3.4249933450696806j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.5,
b=-15.964218273004214,
c=16.5,
z=(0.18965517241379315+1.024137931034483j),
expected=(199.65868451496038+347.79384207302877j),
rtol=1e-13,
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.75,
b=-15.75,
c=-3.5,
z=(0.4931034482758623-0.8724137931034484j),
expected=(-208138312553.07013+58631611809.026955j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=-15.5,
c=-7.5,
z=(0.3413793103448277+0.9482758620689657j),
expected=(-23032.90519856288-18256.94050457296j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.5,
b=1.5,
c=1.0561196186065624,
z=(0.4931034482758623-0.8724137931034484j),
expected=(1.507342459587056+1.2332023580148403j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=2.5,
b=4.5,
c=-3.9316537064827854,
z=(0.4172413793103451+0.9482758620689657j),
expected=(7044.766127108853-40210.365567285575j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.5,
b=-1.5,
c=1.0561196186065624,
z=(0.03793103448275881+1.024137931034483j),
expected=(0.2725347741628333-2.247314875514784j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.5,
b=-1.5,
c=-7.949900487447654,
z=(0.26551724137931054+1.024137931034483j),
expected=(-11.250200011017546+12.597393659160472j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.5,
b=8.5,
c=16.088264119063613,
z=(0.26551724137931054+1.024137931034483j),
expected=(-0.18515160890991517+0.7959014164484782j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.5,
b=16.5,
c=-3.9316537064827854,
z=(0.3413793103448277-1.024137931034483j),
expected=(998246378.8556538+1112032928.103645j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.5,
b=-3.5,
c=2.050308316530781,
z=(0.03793103448275881+1.024137931034483j),
expected=(0.5527670397711952+2.697662715303637j),
rtol=1.2e-15, # rtol bumped from 1e-15 in gh18414
),
),
pytest.param(
Hyp2f1TestCase(
a=-15.5,
b=-1.5,
c=-0.9629749245209605,
z=(0.4931034482758623-0.8724137931034484j),
expected=(55.396931662136886+968.467463806326j),
rtol=5e-14,
),
),
]
)
def test_region5(self, hyp2f1_test_case):
"""1 < |z| < 1.1 and |1 - z| >= 0.9 and real(z) >= 0"""
a, b, c, z, expected, rtol = hyp2f1_test_case
assert 1 < abs(z) < 1.1 and abs(1 - z) >= 0.9 and z.real >= 0
assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
@pytest.mark.parametrize(
"hyp2f1_test_case",
[
pytest.param(
Hyp2f1TestCase(
a=8.095813935368371,
b=4.0013768449590685,
c=4.078873014294075,
z=(-0.9473684210526316+0.5263157894736841j),
expected=(-0.0018093573941378783+0.003481887377423739j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.087593263474208,
b=2.050308316530781,
c=1.0651378143226575,
z=(-0.736842105263158-0.736842105263158j),
expected=(-0.00023401243818780545-1.7983496305603562e-05j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.0272592605282642,
b=8.077282662161238,
c=4.078873014294075,
z=(-0.5263157894736843-0.9473684210526316j),
expected=(0.22359773002226846-0.24092487123993353j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.0272592605282642,
b=2.050308316530781,
c=-15.963511401609862,
z=(-0.9473684210526316-0.5263157894736843j),
expected=(1.191573745740011+0.14347394589721466j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=4.0013768449590685,
c=-15.963511401609862,
z=(-0.9473684210526316-0.5263157894736843j),
expected=(31.822620756901784-66.09094396747611j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=8.077282662161238,
c=-7.93846038215665,
z=(-0.9473684210526316+0.5263157894736841j),
expected=(207.16750179245952+34.80478274924269j),
rtol=5e-12,
),
),
pytest.param(
Hyp2f1TestCase(
a=8.095813935368371,
b=-7.949900487447654,
c=8.031683612216888,
z=(-0.736842105263158+0.7368421052631575j),
expected=(-159.62429364277145+9.154224290644898j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.0272592605282642,
b=-1.92872979730171,
c=16.056809865262608,
z=(-0.9473684210526316+0.5263157894736841j),
expected=(1.121122351247184-0.07170260470126685j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=16.087593263474208,
b=-0.9629749245209605,
c=16.056809865262608,
z=(-0.9473684210526316+0.5263157894736841j),
expected=(1.9040596681316053-0.4951799449960107j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.0272592605282642,
b=-1.92872979730171,
c=-0.906685989801748,
z=(-0.9473684210526316-0.5263157894736843j),
expected=(-14.496623497780739-21.897524523299875j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=4.080187217753502,
b=-3.9316537064827854,
c=-3.9924618758357022,
z=(-0.5263157894736843-0.9473684210526316j),
expected=(36.33473466026878+253.88728442029577j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=1.0272592605282642,
b=-15.964218273004214,
c=-0.906685989801748,
z=(-0.9473684210526316+0.5263157894736841j),
expected=(1505052.5653144997-50820766.81043443j),
rtol=1e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.956227226099288,
b=4.0013768449590685,
c=1.0651378143226575,
z=(-0.5263157894736843+0.9473684210526314j),
expected=(-127.79407519260877-28.69899444941112j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.9214641416286231,
b=8.077282662161238,
c=16.056809865262608,
z=(-0.9473684210526316-0.5263157894736843j),
expected=(2.0623331933754976+0.741234463565458j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.956227226099288,
b=8.077282662161238,
c=2.0397202577726152,
z=(-0.9473684210526316+0.5263157894736841j),
expected=(30.729193458862525-292.5700835046965j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.9214641416286231,
b=1.0561196186065624,
c=-1.9631175993998025,
z=(-0.5263157894736843-0.9473684210526316j),
expected=(1.1285917906203495-0.735264575450189j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=1.0561196186065624,
c=-3.9924618758357022,
z=(-0.736842105263158+0.7368421052631575j),
expected=(0.6356474446678052-0.02429663008952248j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-1.9214641416286231,
b=16.088264119063613,
c=-7.93846038215665,
z=(-0.736842105263158+0.7368421052631575j),
expected=(0.4718880510273174+0.655083067736377j),
rtol=1e-11,
),
),
pytest.param(
Hyp2f1TestCase(
a=-7.937789122896016,
b=-3.9316537064827854,
c=16.056809865262608,
z=(-0.9473684210526316+0.5263157894736841j),
expected=(-0.14681550942352714+0.16092206364265146j),
rtol=5e-11,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=-15.964218273004214,
c=1.0651378143226575,
z=(-0.5263157894736843+0.9473684210526314j),
expected=(-6.436835190526225+22.883156700606182j),
rtol=5e-14,
),
),
pytest.param(
Hyp2f1TestCase(
a=-0.9220024191881196,
b=-7.949900487447654,
c=4.078873014294075,
z=(-0.9473684210526316-0.5263157894736843j),
expected=(-0.7505682955068583-1.1026583264249945j),
rtol=1e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.956227226099288,
b=-3.9316537064827854,
c=-7.93846038215665,
z=(-0.9473684210526316-0.5263157894736843j),
expected=(3.6247814989198166+2.596041360148318j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.956227226099288,
b=-15.964218273004214,
c=-1.9631175993998025,
z=(-0.5263157894736843-0.9473684210526316j),
expected=(-59537.65287927933-669074.4342539902j),
rtol=5e-15,
),
),
pytest.param(
Hyp2f1TestCase(
a=-3.956227226099288,
b=-15.964218273004214,
c=-1.9631175993998025,
z=(-0.9473684210526316-0.5263157894736843j),
expected=(-433084.9970266166+431088.393918521j),
rtol=5e-14,
),
),
]
)
def test_region6(self, hyp2f1_test_case):
"""|z| > 1 but not in region 5."""
a, b, c, z, expected, rtol = hyp2f1_test_case
assert (
abs(z) > 1 and
not (1 < abs(z) < 1.1 and abs(1 - z) >= 0.9 and z.real >= 0)
)
assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
@pytest.mark.slow
@check_version(mpmath, "1.0.0")
def test_test_hyp2f1(self):
"""Test that expected values match what is computed by mpmath.
This gathers the parameters for the test cases out of the pytest marks.
The parameters are a, b, c, z, expected, rtol, where expected should
be the value of hyp2f1(a, b, c, z) computed with mpmath. The test
recomputes hyp2f1(a, b, c, z) using mpmath and verifies that expected
actually is the correct value. This allows the data for the tests to
live within the test code instead of an external datafile, while
avoiding having to compute the results with mpmath during the test,
except for when slow tests are being run.
"""
test_methods = [
test_method for test_method in dir(self)
if test_method.startswith('test') and
# Filter properties and attributes (futureproofing).
callable(getattr(self, test_method)) and
# Filter out this test
test_method != 'test_test_hyp2f1'
]
for test_method in test_methods:
params = self._get_test_parameters(getattr(self, test_method))
for a, b, c, z, expected, _ in params:
assert_allclose(mp_hyp2f1(a, b, c, z), expected, rtol=2.25e-16)
def _get_test_parameters(self, test_method):
"""Get pytest.mark parameters for a test in this class."""
return [
case.values[0] for mark in test_method.pytestmark
if mark.name == 'parametrize'
for case in mark.args[1]
]