12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180 |
- """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]
- ]
|