2181 lines
77 KiB
Python
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=1e-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=1e-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=1e-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=1e-15,
|
||
|
),
|
||
|
),
|
||
|
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]
|
||
|
]
|