test_hyp2f1.py 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180
  1. """Tests for hyp2f1 for complex values.
  2. Author: Albert Steppi, with credit to Adam Kullberg (FormerPhycisist) for
  3. the implementation of mp_hyp2f1 below, which modifies mpmath's hyp2f1 to
  4. return the same branch as scipy's on the standard branch cut.
  5. """
  6. import sys
  7. import pytest
  8. import numpy as np
  9. from typing import NamedTuple
  10. from numpy.testing import assert_allclose
  11. from scipy.special import hyp2f1
  12. from scipy.special._testutils import check_version, MissingModule
  13. try:
  14. import mpmath
  15. except ImportError:
  16. mpmath = MissingModule("mpmath")
  17. def mp_hyp2f1(a, b, c, z):
  18. """Return mpmath hyp2f1 calculated on same branch as scipy hyp2f1.
  19. For most values of a,b,c mpmath returns the x - 0j branch of hyp2f1 on the
  20. branch cut x=(1,inf) whereas scipy's hyp2f1 calculates the x + 0j branch.
  21. Thus, to generate the right comparison values on the branch cut, we
  22. evaluate mpmath.hyp2f1 at x + 1e-15*j.
  23. The exception to this occurs when c-a=-m in which case both mpmath and
  24. scipy calculate the x + 0j branch on the branch cut. When this happens
  25. mpmath.hyp2f1 will be evaluated at the original z point.
  26. """
  27. on_branch_cut = z.real > 1.0 and abs(z.imag) < 1.0e-15
  28. cond1 = abs(c - a - round(c - a)) < 1.0e-15 and round(c - a) <= 0
  29. cond2 = abs(c - b - round(c - b)) < 1.0e-15 and round(c - b) <= 0
  30. # Make sure imaginary part is *exactly* zero
  31. if on_branch_cut:
  32. z = z.real + 0.0j
  33. if on_branch_cut and not (cond1 or cond2):
  34. z_mpmath = z.real + 1.0e-15j
  35. else:
  36. z_mpmath = z
  37. return complex(mpmath.hyp2f1(a, b, c, z_mpmath))
  38. class Hyp2f1TestCase(NamedTuple):
  39. a: float
  40. b: float
  41. c: float
  42. z: complex
  43. expected: complex
  44. rtol: float
  45. class TestHyp2f1:
  46. """Tests for hyp2f1 for complex values.
  47. Expected values for test cases were computed using mpmath. See
  48. `scipy.special._precompute.hyp2f1_data`. The verbose style of specifying
  49. test cases is used for readability and to make it easier to mark individual
  50. cases as expected to fail. Expected failures are used to highlight cases
  51. where improvements are needed. See
  52. `scipy.special._precompute.hyp2f1_data.make_hyp2f1_test_cases` for a
  53. function to generate the boilerplate for the test cases.
  54. Assertions have been added to each test to ensure that the test cases match
  55. the situations that are intended. A final test `test_test_hyp2f1` checks
  56. that the expected values in the test cases actually match what is computed
  57. by mpmath. This test is marked slow even though it isn't particularly slow
  58. so that it won't run by default on continuous integration builds.
  59. """
  60. @pytest.mark.parametrize(
  61. "hyp2f1_test_case",
  62. [
  63. pytest.param(
  64. Hyp2f1TestCase(
  65. a=0.5,
  66. b=0.2,
  67. c=-10,
  68. z=0.2 + 0.2j,
  69. expected=np.inf + 0j,
  70. rtol=0
  71. )
  72. ),
  73. pytest.param(
  74. Hyp2f1TestCase(
  75. a=0.5,
  76. b=0.2,
  77. c=-10,
  78. z=0 + 0j,
  79. expected=1 + 0j,
  80. rtol=0
  81. ),
  82. ),
  83. pytest.param(
  84. Hyp2f1TestCase(
  85. a=0.5,
  86. b=0,
  87. c=-10,
  88. z=0.2 + 0.2j,
  89. expected=1 + 0j,
  90. rtol=0
  91. ),
  92. ),
  93. pytest.param(
  94. Hyp2f1TestCase(
  95. a=0.5,
  96. b=0,
  97. c=0,
  98. z=0.2 + 0.2j,
  99. expected=1 + 0j,
  100. rtol=0,
  101. ),
  102. ),
  103. pytest.param(
  104. Hyp2f1TestCase(
  105. a=0.5,
  106. b=0.2,
  107. c=0,
  108. z=0.2 + 0.2j,
  109. expected=np.inf + 0j,
  110. rtol=0,
  111. ),
  112. ),
  113. pytest.param(
  114. Hyp2f1TestCase(
  115. a=0.5,
  116. b=0.2,
  117. c=0,
  118. z=0 + 0j,
  119. expected=np.nan + 0j,
  120. rtol=0,
  121. ),
  122. ),
  123. pytest.param(
  124. Hyp2f1TestCase(
  125. a=0.5,
  126. b=-5,
  127. c=-10,
  128. z=0.2 + 0.2j,
  129. expected=(1.0495404166666666+0.05708208333333334j),
  130. rtol=1e-15,
  131. ),
  132. ),
  133. pytest.param(
  134. Hyp2f1TestCase(
  135. a=0.5,
  136. b=-10,
  137. c=-10,
  138. z=0.2 + 0.2j,
  139. expected=(1.092966013125+0.13455014673750001j),
  140. rtol=1e-15,
  141. ),
  142. ),
  143. pytest.param(
  144. Hyp2f1TestCase(
  145. a=-10,
  146. b=-20,
  147. c=-10,
  148. z=0.2 + 0.2j,
  149. expected=(-0.07712512000000005+0.12752814080000005j),
  150. rtol=1e-13,
  151. ),
  152. ),
  153. pytest.param(
  154. Hyp2f1TestCase(
  155. a=-1,
  156. b=3.2,
  157. c=-1,
  158. z=0.2 + 0.2j,
  159. expected=(1.6400000000000001+0.6400000000000001j),
  160. rtol=1e-13,
  161. ),
  162. ),
  163. pytest.param(
  164. Hyp2f1TestCase(
  165. a=-2,
  166. b=1.2,
  167. c=-4,
  168. z=1 + 0j,
  169. expected=1.8200000000000001 + 0j,
  170. rtol=1e-15,
  171. ),
  172. ),
  173. ]
  174. )
  175. def test_c_non_positive_int(self, hyp2f1_test_case):
  176. a, b, c, z, expected, rtol = hyp2f1_test_case
  177. assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
  178. @pytest.mark.parametrize(
  179. "hyp2f1_test_case",
  180. [
  181. pytest.param(
  182. Hyp2f1TestCase(
  183. a=0.5,
  184. b=0.2,
  185. c=1.5,
  186. z=1 + 0j,
  187. expected=1.1496439092239847 + 0j,
  188. rtol=1e-15
  189. ),
  190. ),
  191. pytest.param(
  192. Hyp2f1TestCase(
  193. a=12.3,
  194. b=8.0,
  195. c=20.31,
  196. z=1 + 0j,
  197. expected=69280986.75273195 + 0j,
  198. rtol=1e-15
  199. ),
  200. ),
  201. pytest.param(
  202. Hyp2f1TestCase(
  203. a=290.2,
  204. b=321.5,
  205. c=700.1,
  206. z=1 + 0j,
  207. expected=1.3396562400934e117 + 0j,
  208. rtol=1e-12,
  209. ),
  210. ),
  211. # Note that here even mpmath produces different results for
  212. # results that should be equivalent.
  213. pytest.param(
  214. Hyp2f1TestCase(
  215. a=9.2,
  216. b=621.5,
  217. c=700.1,
  218. z=(1+0j),
  219. expected=(952726652.4158565+0j),
  220. rtol=5e-13,
  221. ),
  222. ),
  223. pytest.param(
  224. Hyp2f1TestCase(
  225. a=621.5,
  226. b=9.2,
  227. c=700.1,
  228. z=(1+0j),
  229. expected=(952726652.4160284+0j),
  230. rtol=5e-12,
  231. ),
  232. ),
  233. pytest.param(
  234. Hyp2f1TestCase(
  235. a=-101.2,
  236. b=-400.4,
  237. c=-172.1,
  238. z=(1+0j),
  239. expected=(2.2253618341394838e+37+0j),
  240. rtol=1e-13,
  241. ),
  242. ),
  243. pytest.param(
  244. Hyp2f1TestCase(
  245. a=-400.4,
  246. b=-101.2,
  247. c=-172.1,
  248. z=(1+0j),
  249. expected=(2.2253618341394838e+37+0j),
  250. rtol=5e-13,
  251. ),
  252. ),
  253. pytest.param(
  254. Hyp2f1TestCase(
  255. a=172.5,
  256. b=-201.3,
  257. c=151.2,
  258. z=(1+0j),
  259. expected=(7.072266653650905e-135+0j),
  260. rtol=5e-13,
  261. ),
  262. ),
  263. pytest.param(
  264. Hyp2f1TestCase(
  265. a=-201.3,
  266. b=172.5,
  267. c=151.2,
  268. z=(1+0j),
  269. expected=(7.072266653650905e-135+0j),
  270. rtol=5e-13,
  271. ),
  272. ),
  273. pytest.param(
  274. Hyp2f1TestCase(
  275. a=-102.1,
  276. b=-20.3,
  277. c=1.3,
  278. z=1 + 0j,
  279. expected=2.7899070752746906e22 + 0j,
  280. rtol=3e-14,
  281. ),
  282. ),
  283. pytest.param(
  284. Hyp2f1TestCase(
  285. a=-202.6,
  286. b=60.3,
  287. c=1.5,
  288. z=1 + 0j,
  289. expected=-1.3113641413099326e-56 + 0j,
  290. rtol=1e-12,
  291. ),
  292. ),
  293. ],
  294. )
  295. def test_unital_argument(self, hyp2f1_test_case):
  296. """Tests for case z = 1, c - a - b > 0.
  297. Expected answers computed using mpmath.
  298. """
  299. a, b, c, z, expected, rtol = hyp2f1_test_case
  300. assert z == 1 and c - a - b > 0 # Tests the test
  301. assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
  302. @pytest.mark.parametrize(
  303. "hyp2f1_test_case",
  304. [
  305. pytest.param(
  306. Hyp2f1TestCase(
  307. a=0.5,
  308. b=0.2,
  309. c=1.3,
  310. z=-1 + 0j,
  311. expected=0.9428846409614143 + 0j,
  312. rtol=1e-15),
  313. ),
  314. pytest.param(
  315. Hyp2f1TestCase(
  316. a=12.3,
  317. b=8.0,
  318. c=5.300000000000001,
  319. z=-1 + 0j,
  320. expected=-4.845809986595704e-06 + 0j,
  321. rtol=1e-15
  322. ),
  323. ),
  324. pytest.param(
  325. Hyp2f1TestCase(
  326. a=221.5,
  327. b=90.2,
  328. c=132.3,
  329. z=-1 + 0j,
  330. expected=2.0490488728377282e-42 + 0j,
  331. rtol=1e-7,
  332. ),
  333. ),
  334. pytest.param(
  335. Hyp2f1TestCase(
  336. a=-102.1,
  337. b=-20.3,
  338. c=-80.8,
  339. z=-1 + 0j,
  340. expected=45143784.46783885 + 0j,
  341. rtol=1e-7,
  342. ),
  343. marks=pytest.mark.xfail(
  344. condition=sys.maxsize < 2**32,
  345. reason="Fails on 32 bit.",
  346. )
  347. ),
  348. ],
  349. )
  350. def test_special_case_z_near_minus_1(self, hyp2f1_test_case):
  351. """Tests for case z ~ -1, c ~ 1 + a - b
  352. Expected answers computed using mpmath.
  353. """
  354. a, b, c, z, expected, rtol = hyp2f1_test_case
  355. assert abs(1 + a - b - c) < 1e-15 and abs(z + 1) < 1e-15
  356. assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
  357. @pytest.mark.parametrize(
  358. "hyp2f1_test_case",
  359. [
  360. pytest.param(
  361. Hyp2f1TestCase(
  362. a=-4,
  363. b=2.02764642551431,
  364. c=1.0561196186065624,
  365. z=(0.9473684210526314-0.10526315789473695j),
  366. expected=(0.0031961077109535375-0.0011313924606557173j),
  367. rtol=1e-12,
  368. ),
  369. ),
  370. pytest.param(
  371. Hyp2f1TestCase(
  372. a=-8,
  373. b=-7.937789122896016,
  374. c=-15.964218273004214,
  375. z=(2-0.10526315789473695j),
  376. expected=(0.005543763196412503-0.0025948879065698306j),
  377. rtol=5e-13,
  378. ),
  379. ),
  380. pytest.param(
  381. Hyp2f1TestCase(
  382. a=-8,
  383. b=8.095813935368371,
  384. c=4.0013768449590685,
  385. z=(0.9473684210526314-0.10526315789473695j),
  386. expected=(-0.0003054674127221263-9.261359291755414e-05j),
  387. rtol=1e-10,
  388. ),
  389. ),
  390. pytest.param(
  391. Hyp2f1TestCase(
  392. a=-4,
  393. b=-3.956227226099288,
  394. c=-3.9316537064827854,
  395. z=(1.1578947368421053-0.3157894736842106j),
  396. expected=(-0.0020809502580892937-0.0041877333232365095j),
  397. rtol=5e-12,
  398. ),
  399. ),
  400. pytest.param(
  401. Hyp2f1TestCase(
  402. a=2.02764642551431,
  403. b=-4,
  404. c=2.050308316530781,
  405. z=(0.9473684210526314-0.10526315789473695j),
  406. expected=(0.0011282435590058734+0.0002027062303465851j),
  407. rtol=5e-13,
  408. ),
  409. ),
  410. pytest.param(
  411. Hyp2f1TestCase(
  412. a=-7.937789122896016,
  413. b=-8,
  414. c=-15.964218273004214,
  415. z=(1.3684210526315788+0.10526315789473673j),
  416. expected=(-9.134907719238265e-05-0.00040219233987390723j),
  417. rtol=5e-12,
  418. ),
  419. ),
  420. pytest.param(
  421. Hyp2f1TestCase(
  422. a=4.080187217753502,
  423. b=-4,
  424. c=4.0013768449590685,
  425. z=(0.9473684210526314-0.10526315789473695j),
  426. expected=(-0.000519013062087489-0.0005855883076830948j),
  427. rtol=5e-12,
  428. ),
  429. ),
  430. pytest.param(
  431. Hyp2f1TestCase(
  432. a=-10000,
  433. b=2.2,
  434. c=93459345.3,
  435. z=(2+2j),
  436. expected=(0.9995292071559088-0.00047047067522659253j),
  437. rtol=1e-12,
  438. ),
  439. ),
  440. ]
  441. )
  442. def test_a_b_negative_int(self, hyp2f1_test_case):
  443. a, b, c, z, expected, rtol = hyp2f1_test_case
  444. assert a == int(a) and a < 0 or b == int(b) and b < 0 # Tests the test
  445. assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
  446. @pytest.mark.parametrize(
  447. "hyp2f1_test_case",
  448. [
  449. pytest.param(
  450. Hyp2f1TestCase(
  451. a=-0.5,
  452. b=-0.9629749245209605,
  453. c=-15.5,
  454. z=(1.1578947368421053-1.1578947368421053j),
  455. expected=(0.9778506962676361+0.044083801141231616j),
  456. rtol=1e-12,
  457. ),
  458. ),
  459. pytest.param(
  460. Hyp2f1TestCase(
  461. a=8.5,
  462. b=-3.9316537064827854,
  463. c=1.5,
  464. z=(0.9473684210526314-0.10526315789473695j),
  465. expected=(4.0793167523167675-10.11694246310966j),
  466. rtol=6e-12,
  467. ),
  468. ),
  469. pytest.param(
  470. Hyp2f1TestCase(
  471. a=8.5,
  472. b=-0.9629749245209605,
  473. c=2.5,
  474. z=(1.1578947368421053-0.10526315789473695j),
  475. expected=(-2.9692999501916915+0.6394599899845594j),
  476. rtol=1e-11,
  477. ),
  478. ),
  479. pytest.param(
  480. Hyp2f1TestCase(
  481. a=-0.5,
  482. b=-0.9629749245209605,
  483. c=-15.5,
  484. z=(1.5789473684210522-1.1578947368421053j),
  485. expected=(0.9493076367106102-0.04316852977183447j),
  486. rtol=1e-11,
  487. ),
  488. ),
  489. pytest.param(
  490. Hyp2f1TestCase(
  491. a=-0.9220024191881196,
  492. b=-0.5,
  493. c=-15.5,
  494. z=(0.5263157894736841+0.10526315789473673j),
  495. expected=(0.9844377175631795-0.003120587561483841j),
  496. rtol=1e-10,
  497. ),
  498. ),
  499. ],
  500. )
  501. def test_a_b_neg_int_after_euler_hypergeometric_transformation(
  502. self, hyp2f1_test_case
  503. ):
  504. a, b, c, z, expected, rtol = hyp2f1_test_case
  505. assert ( # Tests the test
  506. (abs(c - a - int(c - a)) < 1e-15 and c - a < 0) or
  507. (abs(c - b - int(c - b)) < 1e-15 and c - b < 0)
  508. )
  509. assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
  510. @pytest.mark.parametrize(
  511. "hyp2f1_test_case",
  512. [
  513. pytest.param(
  514. Hyp2f1TestCase(
  515. a=-0.9220024191881196,
  516. b=-0.9629749245209605,
  517. c=-15.963511401609862,
  518. z=(0.10526315789473673-0.3157894736842106j),
  519. expected=(0.9941449585778349+0.01756335047931358j),
  520. rtol=1e-14,
  521. ),
  522. ),
  523. pytest.param(
  524. Hyp2f1TestCase(
  525. a=1.0272592605282642,
  526. b=-0.9629749245209605,
  527. c=-15.963511401609862,
  528. z=(0.5263157894736841+0.5263157894736841j),
  529. expected=(1.0388722293372104-0.09549450380041416j),
  530. rtol=5e-11,
  531. ),
  532. ),
  533. pytest.param(
  534. Hyp2f1TestCase(
  535. a=2.02764642551431,
  536. b=1.0561196186065624,
  537. c=-7.93846038215665,
  538. z=(0.10526315789473673+0.7368421052631575j),
  539. expected=(2.1948378809826434+24.934157235172222j),
  540. rtol=5e-15,
  541. ),
  542. ),
  543. pytest.param(
  544. Hyp2f1TestCase(
  545. a=2.02764642551431,
  546. b=16.088264119063613,
  547. c=8.031683612216888,
  548. z=(0.3157894736842106-0.736842105263158j),
  549. expected=(-0.4075277891264672-0.06819344579666956j),
  550. rtol=2e-12,
  551. ),
  552. ),
  553. pytest.param(
  554. Hyp2f1TestCase(
  555. a=4.080187217753502,
  556. b=2.050308316530781,
  557. c=8.031683612216888,
  558. z=(0.7368421052631575-0.10526315789473695j),
  559. expected=(2.833535530740603-0.6925373701408158j),
  560. rtol=5e-15,
  561. ),
  562. ),
  563. pytest.param(
  564. Hyp2f1TestCase(
  565. a=2.02764642551431,
  566. b=2.050308316530781,
  567. c=4.078873014294075,
  568. z=(0.10526315789473673-0.3157894736842106j),
  569. expected=(1.005347176329683-0.3580736009337313j),
  570. rtol=5e-16,
  571. ),
  572. ),
  573. pytest.param(
  574. Hyp2f1TestCase(
  575. a=-0.9220024191881196,
  576. b=-0.9629749245209605,
  577. c=-15.963511401609862,
  578. z=(0.3157894736842106-0.5263157894736843j),
  579. expected=(0.9824353641135369+0.029271018868990268j),
  580. rtol=5e-13,
  581. ),
  582. ),
  583. pytest.param(
  584. Hyp2f1TestCase(
  585. a=-0.9220024191881196,
  586. b=-0.9629749245209605,
  587. c=-159.63511401609862,
  588. z=(0.3157894736842106-0.5263157894736843j),
  589. expected=(0.9982436200365834+0.002927268199671111j),
  590. rtol=1e-7,
  591. ),
  592. marks=pytest.mark.xfail(reason="Poor convergence.")
  593. ),
  594. pytest.param(
  595. Hyp2f1TestCase(
  596. a=2.02764642551431,
  597. b=16.088264119063613,
  598. c=8.031683612216888,
  599. z=(0.5263157894736841-0.5263157894736843j),
  600. expected=(-0.6906825165778091+0.8176575137504892j),
  601. rtol=5e-13,
  602. ),
  603. ),
  604. ]
  605. )
  606. def test_region1(self, hyp2f1_test_case):
  607. """|z| < 0.9 and real(z) >= 0."""
  608. a, b, c, z, expected, rtol = hyp2f1_test_case
  609. assert abs(z) < 0.9 and z.real >= 0 # Tests the test
  610. assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
  611. @pytest.mark.parametrize(
  612. "hyp2f1_test_case",
  613. [
  614. pytest.param(
  615. Hyp2f1TestCase(
  616. a=2.02764642551431,
  617. b=1.0561196186065624,
  618. c=4.078873014294075,
  619. z=(-0.3157894736842106+0.7368421052631575j),
  620. expected=(0.7751915029081136+0.24068493258607315j),
  621. rtol=5e-15,
  622. ),
  623. ),
  624. pytest.param(
  625. Hyp2f1TestCase(
  626. a=16.087593263474208,
  627. b=16.088264119063613,
  628. c=2.0397202577726152,
  629. z=(-0.9473684210526316-0.3157894736842106j),
  630. expected=(6.564549348474962e-07+1.6761570598334562e-06j),
  631. rtol=5e-09,
  632. ),
  633. ),
  634. pytest.param(
  635. Hyp2f1TestCase(
  636. a=1.0272592605282642,
  637. b=2.050308316530781,
  638. c=16.056809865262608,
  639. z=(-0.10526315789473695-0.10526315789473695j),
  640. expected=(0.9862043298997204-0.013293151372712681j),
  641. rtol=5e-15,
  642. ),
  643. ),
  644. pytest.param(
  645. Hyp2f1TestCase(
  646. a=4.080187217753502,
  647. b=8.077282662161238,
  648. c=16.056809865262608,
  649. z=(-0.3157894736842106-0.736842105263158j),
  650. expected=(0.16163826638754716-0.41378530376373734j),
  651. rtol=5e-15,
  652. ),
  653. ),
  654. pytest.param(
  655. Hyp2f1TestCase(
  656. a=2.02764642551431,
  657. b=2.050308316530781,
  658. c=-0.906685989801748,
  659. z=(-0.5263157894736843+0.3157894736842106j),
  660. expected=(-6.256871535165936+0.13824973858225484j),
  661. rtol=1e-15,
  662. ),
  663. ),
  664. pytest.param(
  665. Hyp2f1TestCase(
  666. a=2.02764642551431,
  667. b=8.077282662161238,
  668. c=-3.9924618758357022,
  669. z=(-0.9473684210526316-0.3157894736842106j),
  670. expected=(75.54672526086316+50.56157041797548j),
  671. rtol=5e-12,
  672. ),
  673. ),
  674. pytest.param(
  675. Hyp2f1TestCase(
  676. a=16.087593263474208,
  677. b=8.077282662161238,
  678. c=-1.9631175993998025,
  679. z=(-0.5263157894736843+0.5263157894736841j),
  680. expected=(282.0602536306534-82.31597306936214j),
  681. rtol=5e-13,
  682. ),
  683. ),
  684. pytest.param(
  685. Hyp2f1TestCase(
  686. a=8.095813935368371,
  687. b=-3.9316537064827854,
  688. c=8.031683612216888,
  689. z=(-0.5263157894736843-0.10526315789473695j),
  690. expected=(5.179603735575851+1.4445374002099813j),
  691. rtol=5e-14,
  692. ),
  693. ),
  694. pytest.param(
  695. Hyp2f1TestCase(
  696. a=4.080187217753502,
  697. b=-7.949900487447654,
  698. c=1.0651378143226575,
  699. z=(-0.3157894736842106-0.9473684210526316j),
  700. expected=(2317.623517606141-269.51476321010324j),
  701. rtol=5e-13,
  702. ),
  703. ),
  704. pytest.param(
  705. Hyp2f1TestCase(
  706. a=16.087593263474208,
  707. b=-1.92872979730171,
  708. c=2.0397202577726152,
  709. z=(-0.736842105263158-0.3157894736842106j),
  710. expected=(29.179154096175836+22.126690357535043j),
  711. rtol=5e-15,
  712. ),
  713. ),
  714. pytest.param(
  715. Hyp2f1TestCase(
  716. a=8.095813935368371,
  717. b=-3.9316537064827854,
  718. c=-15.963511401609862,
  719. z=(-0.736842105263158-0.10526315789473695j),
  720. expected=(0.20820247892032057-0.04763956711248794j),
  721. rtol=5e-14,
  722. ),
  723. ),
  724. pytest.param(
  725. Hyp2f1TestCase(
  726. a=1.0272592605282642,
  727. b=-15.964218273004214,
  728. c=-1.9631175993998025,
  729. z=(-0.3157894736842106-0.5263157894736843j),
  730. expected=(-157471.63920142158+991294.0587828817j),
  731. rtol=5e-14,
  732. ),
  733. ),
  734. pytest.param(
  735. Hyp2f1TestCase(
  736. a=8.095813935368371,
  737. b=-7.949900487447654,
  738. c=-7.93846038215665,
  739. z=(-0.10526315789473695-0.10526315789473695j),
  740. expected=(0.30765349653210194-0.2979706363594157j),
  741. rtol=1e-15,
  742. ),
  743. ),
  744. pytest.param(
  745. Hyp2f1TestCase(
  746. a=-3.956227226099288,
  747. b=1.0561196186065624,
  748. c=8.031683612216888,
  749. z=(-0.9473684210526316-0.10526315789473695j),
  750. expected=(1.6787607400597109+0.10056620134616838j),
  751. rtol=5e-14,
  752. ),
  753. ),
  754. pytest.param(
  755. Hyp2f1TestCase(
  756. a=-7.937789122896016,
  757. b=16.088264119063613,
  758. c=4.078873014294075,
  759. z=(-0.5263157894736843-0.736842105263158j),
  760. expected=(7062.07842506049-12768.77955655703j),
  761. rtol=5e-15,
  762. ),
  763. ),
  764. pytest.param(
  765. Hyp2f1TestCase(
  766. a=-7.937789122896016,
  767. b=16.088264119063613,
  768. c=2.0397202577726152,
  769. z=(-0.3157894736842106+0.7368421052631575j),
  770. expected=(54749.216391029935-23078.144720887536j),
  771. rtol=1e-15,
  772. ),
  773. ),
  774. pytest.param(
  775. Hyp2f1TestCase(
  776. a=-3.956227226099288,
  777. b=1.0561196186065624,
  778. c=-0.906685989801748,
  779. z=(-0.10526315789473695-0.10526315789473695j),
  780. expected=(1.21521766411428-4.449385173946672j),
  781. rtol=5e-15,
  782. ),
  783. ),
  784. pytest.param(
  785. Hyp2f1TestCase(
  786. a=-15.980848054962111,
  787. b=4.0013768449590685,
  788. c=-1.9631175993998025,
  789. z=(-0.736842105263158+0.5263157894736841j),
  790. expected=(19234693144.196907+1617913967.7294445j),
  791. rtol=5e-14,
  792. ),
  793. ),
  794. pytest.param(
  795. Hyp2f1TestCase(
  796. a=-1.9214641416286231,
  797. b=1.0561196186065624,
  798. c=-15.963511401609862,
  799. z=(-0.5263157894736843+0.3157894736842106j),
  800. expected=(0.9345201094534371+0.03745712558992195j),
  801. rtol=5e-15,
  802. ),
  803. ),
  804. pytest.param(
  805. Hyp2f1TestCase(
  806. a=-7.937789122896016,
  807. b=-0.9629749245209605,
  808. c=2.0397202577726152,
  809. z=(-0.10526315789473695+0.10526315789473673j),
  810. expected=(0.605732446296829+0.398171533680972j),
  811. rtol=5e-15,
  812. ),
  813. ),
  814. pytest.param(
  815. Hyp2f1TestCase(
  816. a=-1.9214641416286231,
  817. b=-15.964218273004214,
  818. c=2.0397202577726152,
  819. z=(-0.10526315789473695-0.5263157894736843j),
  820. expected=(-9.753761888305416-4.590126012666959j),
  821. rtol=5e-15,
  822. ),
  823. ),
  824. pytest.param(
  825. Hyp2f1TestCase(
  826. a=-3.956227226099288,
  827. b=-1.92872979730171,
  828. c=2.0397202577726152,
  829. z=(-0.10526315789473695+0.3157894736842106j),
  830. expected=(0.45587226291120714+1.0694545265819797j),
  831. rtol=5e-15,
  832. ),
  833. ),
  834. pytest.param(
  835. Hyp2f1TestCase(
  836. a=-0.9220024191881196,
  837. b=-7.949900487447654,
  838. c=-0.906685989801748,
  839. z=(-0.736842105263158+0.3157894736842106j),
  840. expected=(12.334808243233418-76.26089051819054j),
  841. rtol=5e-14,
  842. ),
  843. ),
  844. pytest.param(
  845. Hyp2f1TestCase(
  846. a=-0.9220024191881196,
  847. b=-7.949900487447654,
  848. c=-15.963511401609862,
  849. z=(-0.5263157894736843+0.10526315789473673j),
  850. expected=(1.2396019687632678-0.047507973161146286j),
  851. rtol=1e-14,
  852. ),
  853. ),
  854. pytest.param(
  855. Hyp2f1TestCase(
  856. a=-15.980848054962111,
  857. b=-0.9629749245209605,
  858. c=-0.906685989801748,
  859. z=(-0.3157894736842106-0.5263157894736843j),
  860. expected=(97.7889554372208-18.999754543400016j),
  861. rtol=5e-13,
  862. ),
  863. ),
  864. ]
  865. )
  866. def test_region2(self, hyp2f1_test_case):
  867. """|z| < 1 and real(z) < 0."""
  868. a, b, c, z, expected, rtol = hyp2f1_test_case
  869. assert abs(z) < 1 and z.real < 0 # Tests the test
  870. assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
  871. @pytest.mark.parametrize(
  872. "hyp2f1_test_case",
  873. [
  874. pytest.param(
  875. Hyp2f1TestCase(
  876. a=16.25,
  877. b=4.25,
  878. c=2.5,
  879. z=(0.4931034482758623-0.7965517241379311j),
  880. expected=(38.41207903409937-30.510151276075792j),
  881. rtol=5e-14,
  882. ),
  883. ),
  884. pytest.param(
  885. Hyp2f1TestCase(
  886. a=2.0,
  887. b=16.087593263474208,
  888. c=16.088264119063613,
  889. z=(0.5689655172413794-0.7965517241379311j),
  890. expected=(-0.6667857912761286-1.0206224321443573j),
  891. rtol=1e-15,
  892. ),
  893. ),
  894. pytest.param(
  895. Hyp2f1TestCase(
  896. a=8.0,
  897. b=1.0272592605282642,
  898. c=-7.949900487447654,
  899. z=(0.4931034482758623-0.7965517241379311j),
  900. expected=(1679024.1647997478-2748129.775857212j),
  901. rtol=5e-14,
  902. ),
  903. ),
  904. pytest.param(
  905. Hyp2f1TestCase(
  906. a=4.080187217753502,
  907. b=16.0,
  908. c=-7.949900487447654,
  909. z=(0.4931034482758623-0.7965517241379311j),
  910. expected=(424747226301.16986-1245539049327.2856j),
  911. rtol=1e-14,
  912. ),
  913. ),
  914. pytest.param(
  915. Hyp2f1TestCase(
  916. a=2.02764642551431,
  917. b=-15.964218273004214,
  918. c=4.0,
  919. z=(0.4931034482758623-0.7965517241379311j),
  920. expected=(-0.0057826199201757595+0.026359861999025885j),
  921. rtol=5e-06,
  922. ),
  923. ),
  924. pytest.param(
  925. Hyp2f1TestCase(
  926. a=2.02764642551431,
  927. b=-0.9629749245209605,
  928. c=2.0397202577726152,
  929. z=(0.5689655172413794-0.7965517241379311j),
  930. expected=(0.4671901063492606+0.7769632229834897j),
  931. rtol=5e-14,
  932. ),
  933. ),
  934. pytest.param(
  935. Hyp2f1TestCase(
  936. a=2.0,
  937. b=-3.956227226099288,
  938. c=-7.949900487447654,
  939. z=(0.4931034482758623+0.7965517241379312j),
  940. expected=(0.9422283708145973+1.3476905754773343j),
  941. rtol=5e-15,
  942. ),
  943. ),
  944. pytest.param(
  945. Hyp2f1TestCase(
  946. a=1.0,
  947. b=-15.980848054962111,
  948. c=-15.964218273004214,
  949. z=(0.4931034482758623-0.7965517241379311j),
  950. expected=(0.4168719497319604-0.9770953555235625j),
  951. rtol=5e-10,
  952. ),
  953. ),
  954. pytest.param(
  955. Hyp2f1TestCase(
  956. a=-0.5,
  957. b=16.088264119063613,
  958. c=2.5,
  959. z=(0.5689655172413794+0.7965517241379312j),
  960. expected=(1.279096377550619-2.173827694297929j),
  961. rtol=5e-12,
  962. ),
  963. ),
  964. pytest.param(
  965. Hyp2f1TestCase(
  966. a=-1.9214641416286231,
  967. b=4.0013768449590685,
  968. c=2.0397202577726152,
  969. z=(0.4931034482758623+0.7965517241379312j),
  970. expected=(-2.071520656161738-0.7846098268395909j),
  971. rtol=5e-14,
  972. ),
  973. ),
  974. pytest.param(
  975. Hyp2f1TestCase(
  976. a=-0.9220024191881196,
  977. b=8.0,
  978. c=-0.9629749245209605,
  979. z=(0.5689655172413794-0.7965517241379311j),
  980. expected=(-7.740015495862889+3.386766435696699j),
  981. rtol=5e-12,
  982. ),
  983. ),
  984. pytest.param(
  985. Hyp2f1TestCase(
  986. a=-1.9214641416286231,
  987. b=16.088264119063613,
  988. c=-7.93846038215665,
  989. z=(0.4931034482758623+0.7965517241379312j),
  990. expected=(-6318.553685853241-7133.416085202879j),
  991. rtol=1e-10,
  992. ),
  993. ),
  994. pytest.param(
  995. Hyp2f1TestCase(
  996. a=-15.980848054962111,
  997. b=-3.9316537064827854,
  998. c=16.056809865262608,
  999. z=(0.5689655172413794+0.7965517241379312j),
  1000. expected=(-0.8854577905547399+8.135089099967278j),
  1001. rtol=5e-14,
  1002. ),
  1003. ),
  1004. pytest.param(
  1005. Hyp2f1TestCase(
  1006. a=-1.9214641416286231,
  1007. b=-0.9629749245209605,
  1008. c=4.078873014294075,
  1009. z=(0.4931034482758623+0.7965517241379312j),
  1010. expected=(1.224291301521487+0.36014711766402485j),
  1011. rtol=1e-15,
  1012. ),
  1013. ),
  1014. pytest.param(
  1015. Hyp2f1TestCase(
  1016. a=-15.75,
  1017. b=-0.75,
  1018. c=-1.5,
  1019. z=(0.4931034482758623+0.7965517241379312j),
  1020. expected=(-1.5765685855028473-3.9399766961046323j),
  1021. rtol=1e-3,
  1022. ),
  1023. marks=pytest.mark.xfail(
  1024. reason="Unhandled parameters."
  1025. )
  1026. ),
  1027. pytest.param(
  1028. Hyp2f1TestCase(
  1029. a=-15.980848054962111,
  1030. b=-1.92872979730171,
  1031. c=-7.93846038215665,
  1032. z=(0.5689655172413794-0.7965517241379311j),
  1033. expected=(56.794588688231194+4.556286783533971j),
  1034. rtol=5e-14,
  1035. ),
  1036. ),
  1037. pytest.param(
  1038. Hyp2f1TestCase(
  1039. a=4.5,
  1040. b=4.5,
  1041. c=2.050308316530781,
  1042. z=(0.5689655172413794+0.7965517241379312j),
  1043. expected=(-4.251456563455306+6.737837111569671j),
  1044. rtol=5e-14,
  1045. ),
  1046. ),
  1047. pytest.param(
  1048. Hyp2f1TestCase(
  1049. a=4.5,
  1050. b=8.5,
  1051. c=-1.92872979730171,
  1052. z=(0.4931034482758623-0.7965517241379311j),
  1053. expected=(2177143.9156599627-3313617.2748088865j),
  1054. rtol=5e-14,
  1055. ),
  1056. ),
  1057. pytest.param(
  1058. Hyp2f1TestCase(
  1059. a=2.5,
  1060. b=-1.5,
  1061. c=4.0013768449590685,
  1062. z=(0.4931034482758623-0.7965517241379311j),
  1063. expected=(0.45563554481603946+0.6212000158060831j),
  1064. rtol=5e-14,
  1065. ),
  1066. ),
  1067. pytest.param(
  1068. Hyp2f1TestCase(
  1069. a=8.5,
  1070. b=-7.5,
  1071. c=-15.964218273004214,
  1072. z=(0.4931034482758623+0.7965517241379312j),
  1073. expected=(61.03201617828073-37.185626416756214j),
  1074. rtol=5e-14,
  1075. ),
  1076. ),
  1077. pytest.param(
  1078. Hyp2f1TestCase(
  1079. a=-15.5,
  1080. b=16.5,
  1081. c=4.0013768449590685,
  1082. z=(0.4931034482758623+0.7965517241379312j),
  1083. expected=(-33143.425963520735+20790.608514722644j),
  1084. rtol=1e-14,
  1085. ),
  1086. ),
  1087. pytest.param(
  1088. Hyp2f1TestCase(
  1089. a=-0.5,
  1090. b=4.5,
  1091. c=-0.9629749245209605,
  1092. z=(0.5689655172413794+0.7965517241379312j),
  1093. expected=(30.778600270824423-26.65160354466787j),
  1094. rtol=5e-13,
  1095. ),
  1096. ),
  1097. pytest.param(
  1098. Hyp2f1TestCase(
  1099. a=-0.5,
  1100. b=-3.5,
  1101. c=16.088264119063613,
  1102. z=(0.5689655172413794-0.7965517241379311j),
  1103. expected=(1.0629792615560487-0.08308454486044772j),
  1104. rtol=1e-15,
  1105. ),
  1106. ),
  1107. pytest.param(
  1108. Hyp2f1TestCase(
  1109. a=-3.5,
  1110. b=-7.5,
  1111. c=-0.9629749245209605,
  1112. z=(0.4931034482758623-0.7965517241379311j),
  1113. expected=(17431.571802591767+3553.7129767034507j),
  1114. rtol=5e-14,
  1115. ),
  1116. ),
  1117. pytest.param(
  1118. Hyp2f1TestCase(
  1119. a=2.25,
  1120. b=8.25,
  1121. c=16.5,
  1122. z=(0.11379310344827598+0.9482758620689657j),
  1123. expected=(0.4468600750211926+0.7313214934036885j),
  1124. rtol=1e-3,
  1125. ),
  1126. marks=pytest.mark.xfail(
  1127. reason="Unhandled parameters."
  1128. )
  1129. ),
  1130. pytest.param(
  1131. Hyp2f1TestCase(
  1132. a=8.25,
  1133. b=16.25,
  1134. c=4.5,
  1135. z=(0.3413793103448277+0.8724137931034486j),
  1136. expected=(-3.905704438293991+3.693347860329299j),
  1137. rtol=5e-14,
  1138. ),
  1139. ),
  1140. pytest.param(
  1141. Hyp2f1TestCase(
  1142. a=4.25,
  1143. b=4.25,
  1144. c=-0.5,
  1145. z=(0.11379310344827598-0.9482758620689655j),
  1146. expected=(-40.31777941834244-89.89852492432011j),
  1147. rtol=5e-15,
  1148. ),
  1149. ),
  1150. pytest.param(
  1151. Hyp2f1TestCase(
  1152. a=1.0272592605282642,
  1153. b=8.0,
  1154. c=-15.964218273004214,
  1155. z=(0.11379310344827598-0.9482758620689655j),
  1156. expected=(52584.347773055284-109197.86244309516j),
  1157. rtol=5e-14,
  1158. ),
  1159. ),
  1160. pytest.param(
  1161. Hyp2f1TestCase(
  1162. a=8.095813935368371,
  1163. b=-15.964218273004214,
  1164. c=16.056809865262608,
  1165. z=(0.03793103448275881+0.9482758620689657j),
  1166. expected=(-1.187733570412592-1.5147865053584582j),
  1167. rtol=5e-10,
  1168. ),
  1169. ),
  1170. pytest.param(
  1171. Hyp2f1TestCase(
  1172. a=4.080187217753502,
  1173. b=-3.9316537064827854,
  1174. c=1.0651378143226575,
  1175. z=(0.26551724137931054+0.9482758620689657j),
  1176. expected=(13.077494677898947+35.071599628224966j),
  1177. rtol=5e-13,
  1178. ),
  1179. ),
  1180. pytest.param(
  1181. Hyp2f1TestCase(
  1182. a=4.080187217753502,
  1183. b=-3.5,
  1184. c=-3.5,
  1185. z=(0.26551724137931054+0.8724137931034486j),
  1186. expected=(-0.5359656237994614-0.2344483936591811j),
  1187. rtol=5e-15,
  1188. ),
  1189. ),
  1190. pytest.param(
  1191. Hyp2f1TestCase(
  1192. a=4.25,
  1193. b=-3.75,
  1194. c=-1.5,
  1195. z=(0.26551724137931054+0.9482758620689657j),
  1196. expected=(1204.8114871663133+64.41022826840198j),
  1197. rtol=5e-13,
  1198. ),
  1199. ),
  1200. pytest.param(
  1201. Hyp2f1TestCase(
  1202. a=-1.9214641416286231,
  1203. b=16.0,
  1204. c=4.0013768449590685,
  1205. z=(0.03793103448275881-0.9482758620689655j),
  1206. expected=(-9.85268872413994+7.011107558429154j),
  1207. rtol=5e-15,
  1208. ),
  1209. ),
  1210. pytest.param(
  1211. Hyp2f1TestCase(
  1212. a=-7.937789122896016,
  1213. b=16.0,
  1214. c=4.0013768449590685,
  1215. z=(0.3413793103448277-0.8724137931034484j),
  1216. expected=(528.5522951158454-1412.21630264791j),
  1217. rtol=1e-15,
  1218. ),
  1219. ),
  1220. pytest.param(
  1221. Hyp2f1TestCase(
  1222. a=-15.5,
  1223. b=1.0561196186065624,
  1224. c=-7.5,
  1225. z=(0.4172413793103451+0.8724137931034486j),
  1226. expected=(133306.45260685298+256510.7045225382j),
  1227. rtol=5e-15,
  1228. ),
  1229. ),
  1230. pytest.param(
  1231. Hyp2f1TestCase(
  1232. a=-7.937789122896016,
  1233. b=8.077282662161238,
  1234. c=-15.963511401609862,
  1235. z=(0.3413793103448277-0.8724137931034484j),
  1236. expected=(-0.998555715276967+2.774198742229889j),
  1237. rtol=5e-11,
  1238. ),
  1239. ),
  1240. pytest.param(
  1241. Hyp2f1TestCase(
  1242. a=-7.75,
  1243. b=-0.75,
  1244. c=1.5,
  1245. z=(0.11379310344827598-0.9482758620689655j),
  1246. expected=(2.072445019723025-2.9793504811373515j),
  1247. rtol=5e-14,
  1248. ),
  1249. ),
  1250. pytest.param(
  1251. Hyp2f1TestCase(
  1252. a=-15.5,
  1253. b=-1.92872979730171,
  1254. c=1.5,
  1255. z=(0.11379310344827598-0.9482758620689655j),
  1256. expected=(-41.87581944176649-32.52980303527139j),
  1257. rtol=5e-13,
  1258. ),
  1259. ),
  1260. pytest.param(
  1261. Hyp2f1TestCase(
  1262. a=-3.75,
  1263. b=-15.75,
  1264. c=-0.5,
  1265. z=(0.11379310344827598-0.9482758620689655j),
  1266. expected=(-3729.6214864209774-30627.510509112635j),
  1267. rtol=5e-15,
  1268. ),
  1269. ),
  1270. pytest.param(
  1271. Hyp2f1TestCase(
  1272. a=-3.956227226099288,
  1273. b=-15.964218273004214,
  1274. c=-0.906685989801748,
  1275. z=(0.03793103448275881+0.9482758620689657j),
  1276. expected=(-131615.07820609974+145596.13384245415j),
  1277. rtol=5e-15,
  1278. ),
  1279. ),
  1280. pytest.param(
  1281. Hyp2f1TestCase(
  1282. a=1.5,
  1283. b=16.5,
  1284. c=16.088264119063613,
  1285. z=(0.26551724137931054+0.8724137931034486j),
  1286. expected=(0.18981844071070744+0.7855036242583742j),
  1287. rtol=1e-15,
  1288. ),
  1289. ),
  1290. pytest.param(
  1291. Hyp2f1TestCase(
  1292. a=16.5,
  1293. b=8.5,
  1294. c=-3.9316537064827854,
  1295. z=(0.11379310344827598-0.9482758620689655j),
  1296. expected=(110224529.2376068+128287212.04290268j),
  1297. rtol=5e-13,
  1298. ),
  1299. ),
  1300. pytest.param(
  1301. Hyp2f1TestCase(
  1302. a=2.5,
  1303. b=-7.5,
  1304. c=4.0013768449590685,
  1305. z=(0.3413793103448277-0.8724137931034484j),
  1306. expected=(0.2722302180888523-0.21790187837266162j),
  1307. rtol=1e-12,
  1308. ),
  1309. ),
  1310. pytest.param(
  1311. Hyp2f1TestCase(
  1312. a=8.5,
  1313. b=-7.5,
  1314. c=-15.964218273004214,
  1315. z=(0.11379310344827598-0.9482758620689655j),
  1316. expected=(-2.8252338010989035+2.430661949756161j),
  1317. rtol=5e-14,
  1318. ),
  1319. ),
  1320. pytest.param(
  1321. Hyp2f1TestCase(
  1322. a=-3.5,
  1323. b=16.5,
  1324. c=4.0013768449590685,
  1325. z=(0.03793103448275881+0.9482758620689657j),
  1326. expected=(-20.604894257647945+74.5109432558078j),
  1327. rtol=5e-15,
  1328. ),
  1329. ),
  1330. pytest.param(
  1331. Hyp2f1TestCase(
  1332. a=-7.5,
  1333. b=8.5,
  1334. c=-0.9629749245209605,
  1335. z=(0.3413793103448277+0.8724137931034486j),
  1336. expected=(-2764422.521269463-3965966.9965808876j),
  1337. rtol=1e-15,
  1338. ),
  1339. ),
  1340. pytest.param(
  1341. Hyp2f1TestCase(
  1342. a=-1.5,
  1343. b=-0.5,
  1344. c=1.0561196186065624,
  1345. z=(0.26551724137931054+0.9482758620689657j),
  1346. expected=(1.2262338560994905+0.6545051266925549j),
  1347. rtol=1e-15,
  1348. ),
  1349. ),
  1350. pytest.param(
  1351. Hyp2f1TestCase(
  1352. a=-0.5,
  1353. b=-15.5,
  1354. c=-7.949900487447654,
  1355. z=(0.4172413793103451-0.8724137931034484j),
  1356. expected=(-2258.1590330318213+8860.193389158803j),
  1357. rtol=1e-10,
  1358. ),
  1359. ),
  1360. ]
  1361. )
  1362. def test_region4(self, hyp2f1_test_case):
  1363. """0.9 <= |z| <= 1 and |1 - z| >= 1.
  1364. This region is unhandled by of the standard transformations and
  1365. needs special care.
  1366. """
  1367. a, b, c, z, expected, rtol = hyp2f1_test_case
  1368. assert 0.9 <= abs(z) <= 1 and abs(1 - z) >= 0.9 # Tests the test
  1369. assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
  1370. @pytest.mark.parametrize(
  1371. "hyp2f1_test_case",
  1372. [
  1373. pytest.param(
  1374. Hyp2f1TestCase(
  1375. a=4.5,
  1376. b=16.088264119063613,
  1377. c=8.5,
  1378. z=(0.6448275862068968+0.8724137931034486j),
  1379. expected=(0.018601324701770394-0.07618420586062377j),
  1380. rtol=5e-08,
  1381. ),
  1382. ),
  1383. pytest.param(
  1384. Hyp2f1TestCase(
  1385. a=8.25,
  1386. b=4.25,
  1387. c=4.5,
  1388. z=(0.6448275862068968-0.8724137931034484j),
  1389. expected=(-1.391549471425551-0.118036604903893j),
  1390. rtol=5e-15,
  1391. ),
  1392. ),
  1393. pytest.param(
  1394. Hyp2f1TestCase(
  1395. a=2.02764642551431,
  1396. b=2.050308316530781,
  1397. c=-1.9631175993998025,
  1398. z=(0.6448275862068968+0.8724137931034486j),
  1399. expected=(-2309.178768155151-1932.7247727595172j),
  1400. rtol=5e-15,
  1401. ),
  1402. ),
  1403. pytest.param(
  1404. Hyp2f1TestCase(
  1405. a=16.087593263474208,
  1406. b=1.0,
  1407. c=-15.964218273004214,
  1408. z=(0.6448275862068968+0.8724137931034486j),
  1409. expected=(85592537010.05054-8061416766688.324j),
  1410. rtol=1e-14,
  1411. ),
  1412. ),
  1413. pytest.param(
  1414. Hyp2f1TestCase(
  1415. a=8.095813935368371,
  1416. b=-0.5,
  1417. c=1.5,
  1418. z=(0.6448275862068968+0.8724137931034486j),
  1419. expected=(1.2334498208515172-2.1639498536219732j),
  1420. rtol=5e-11,
  1421. ),
  1422. ),
  1423. pytest.param(
  1424. Hyp2f1TestCase(
  1425. a=16.087593263474208,
  1426. b=-15.964218273004214,
  1427. c=4.0,
  1428. z=(0.6448275862068968+0.8724137931034486j),
  1429. expected=(102266.35398605966-44976.97828737755j),
  1430. rtol=1e-3,
  1431. ),
  1432. marks=pytest.mark.xfail(
  1433. reason="Unhandled parameters."
  1434. )
  1435. ),
  1436. pytest.param(
  1437. Hyp2f1TestCase(
  1438. a=4.0,
  1439. b=-3.956227226099288,
  1440. c=-15.964218273004214,
  1441. z=(0.6448275862068968-0.8724137931034484j),
  1442. expected=(-2.9590030930007236-4.190770764773225j),
  1443. rtol=5e-13,
  1444. ),
  1445. ),
  1446. pytest.param(
  1447. Hyp2f1TestCase(
  1448. a=4.080187217753502,
  1449. b=-15.5,
  1450. c=-7.5,
  1451. z=(0.5689655172413794-0.8724137931034484j),
  1452. expected=(-112554838.92074208+174941462.9202412j),
  1453. rtol=5e-05,
  1454. ),
  1455. ),
  1456. pytest.param(
  1457. Hyp2f1TestCase(
  1458. a=-15.980848054962111,
  1459. b=2.050308316530781,
  1460. c=1.0,
  1461. z=(0.6448275862068968-0.8724137931034484j),
  1462. expected=(3.7519882374080145+7.360753798667486j),
  1463. rtol=5e-13,
  1464. ),
  1465. ),
  1466. pytest.param(
  1467. Hyp2f1TestCase(
  1468. a=-7.937789122896016,
  1469. b=2.050308316530781,
  1470. c=4.0,
  1471. z=(0.6448275862068968-0.8724137931034484j),
  1472. expected=(0.000181132943964693+0.07742903103815582j),
  1473. rtol=5e-14,
  1474. ),
  1475. ),
  1476. pytest.param(
  1477. Hyp2f1TestCase(
  1478. a=-7.937789122896016,
  1479. b=4.0013768449590685,
  1480. c=-1.9631175993998025,
  1481. z=(0.5689655172413794+0.8724137931034486j),
  1482. expected=(386338.760913596-386166.51762171905j),
  1483. rtol=5e-15,
  1484. ),
  1485. ),
  1486. pytest.param(
  1487. Hyp2f1TestCase(
  1488. a=-15.980848054962111,
  1489. b=8.0,
  1490. c=-1.92872979730171,
  1491. z=(0.6448275862068968+0.8724137931034486j),
  1492. expected=(1348667126.3444858-2375132427.158893j),
  1493. rtol=5e-14,
  1494. ),
  1495. ),
  1496. pytest.param(
  1497. Hyp2f1TestCase(
  1498. a=-3.5,
  1499. b=-0.9629749245209605,
  1500. c=4.5,
  1501. z=(0.5689655172413794+0.8724137931034486j),
  1502. expected=(1.428353429538678+0.6472718120804372j),
  1503. rtol=5e-15,
  1504. ),
  1505. ),
  1506. pytest.param(
  1507. Hyp2f1TestCase(
  1508. a=-7.937789122896016,
  1509. b=-0.9629749245209605,
  1510. c=2.0397202577726152,
  1511. z=(0.5689655172413794-0.8724137931034484j),
  1512. expected=(3.1439267526119643-3.145305240375117j),
  1513. rtol=5e-14,
  1514. ),
  1515. ),
  1516. pytest.param(
  1517. Hyp2f1TestCase(
  1518. a=-1.9214641416286231,
  1519. b=-15.964218273004214,
  1520. c=-7.93846038215665,
  1521. z=(0.6448275862068968-0.8724137931034484j),
  1522. expected=(75.27467675681773+144.0946946292215j),
  1523. rtol=1e-07,
  1524. ),
  1525. ),
  1526. pytest.param(
  1527. Hyp2f1TestCase(
  1528. a=-3.75,
  1529. b=-7.75,
  1530. c=-7.5,
  1531. z=(0.5689655172413794+0.8724137931034486j),
  1532. expected=(-0.3699450626264222+0.8732812475910993j),
  1533. rtol=1e-15,
  1534. ),
  1535. ),
  1536. pytest.param(
  1537. Hyp2f1TestCase(
  1538. a=1.5,
  1539. b=16.5,
  1540. c=1.0561196186065624,
  1541. z=(0.5689655172413794-0.8724137931034484j),
  1542. expected=(5.5361025821300665-2.4709693474656285j),
  1543. rtol=5e-09,
  1544. ),
  1545. ),
  1546. pytest.param(
  1547. Hyp2f1TestCase(
  1548. a=1.5,
  1549. b=8.5,
  1550. c=-3.9316537064827854,
  1551. z=(0.6448275862068968-0.8724137931034484j),
  1552. expected=(-782805.6699207705-537192.581278909j),
  1553. rtol=5e-14,
  1554. ),
  1555. ),
  1556. pytest.param(
  1557. Hyp2f1TestCase(
  1558. a=2.5,
  1559. b=-15.5,
  1560. c=1.0561196186065624,
  1561. z=(0.6448275862068968+0.8724137931034486j),
  1562. expected=(12.345113400639693-14.993248992902007j),
  1563. rtol=0.0005,
  1564. ),
  1565. ),
  1566. pytest.param(
  1567. Hyp2f1TestCase(
  1568. a=1.5,
  1569. b=-0.5,
  1570. c=-15.964218273004214,
  1571. z=(0.6448275862068968+0.8724137931034486j),
  1572. expected=(23.698109392667842+97.15002033534108j),
  1573. rtol=5e-14,
  1574. ),
  1575. ),
  1576. pytest.param(
  1577. Hyp2f1TestCase(
  1578. a=-7.5,
  1579. b=16.5,
  1580. c=4.0013768449590685,
  1581. z=(0.6448275862068968-0.8724137931034484j),
  1582. expected=(1115.2978631811834+915.9212658718577j),
  1583. rtol=5e-15,
  1584. ),
  1585. ),
  1586. pytest.param(
  1587. Hyp2f1TestCase(
  1588. a=-15.5,
  1589. b=16.5,
  1590. c=-0.9629749245209605,
  1591. z=(0.6448275862068968+0.8724137931034486j),
  1592. expected=(642077722221.6489+535274495398.21027j),
  1593. rtol=5e-15,
  1594. ),
  1595. ),
  1596. pytest.param(
  1597. Hyp2f1TestCase(
  1598. a=-7.5,
  1599. b=-3.5,
  1600. c=4.0013768449590685,
  1601. z=(0.5689655172413794+0.8724137931034486j),
  1602. expected=(-5.689219222945697+16.877463062787143j),
  1603. rtol=5e-15,
  1604. ),
  1605. ),
  1606. pytest.param(
  1607. Hyp2f1TestCase(
  1608. a=-15.5,
  1609. b=-1.5,
  1610. c=-0.9629749245209605,
  1611. z=(0.5689655172413794-0.8724137931034484j),
  1612. expected=(-44.32070290703576+1026.9127058617403j),
  1613. rtol=5e-14,
  1614. ),
  1615. ),
  1616. pytest.param(
  1617. Hyp2f1TestCase(
  1618. a=16.25,
  1619. b=2.25,
  1620. c=4.5,
  1621. z=(0.11379310344827598-1.024137931034483j),
  1622. expected=(-0.021965227124574663+0.009908300237809064j),
  1623. rtol=1e-3,
  1624. ),
  1625. marks=pytest.mark.xfail(
  1626. reason="Unhandled parameters."
  1627. )
  1628. ),
  1629. pytest.param(
  1630. Hyp2f1TestCase(
  1631. a=2.02764642551431,
  1632. b=1.5,
  1633. c=16.5,
  1634. z=(0.26551724137931054+1.024137931034483j),
  1635. expected=(1.0046072901244183+0.19945500134119992j),
  1636. rtol=5e-14,
  1637. ),
  1638. ),
  1639. pytest.param(
  1640. Hyp2f1TestCase(
  1641. a=16.087593263474208,
  1642. b=1.0,
  1643. c=-3.9316537064827854,
  1644. z=(0.3413793103448277+0.9482758620689657j),
  1645. expected=(21022.30133421465+49175.98317370489j),
  1646. rtol=5e-13,
  1647. ),
  1648. ),
  1649. pytest.param(
  1650. Hyp2f1TestCase(
  1651. a=4.080187217753502,
  1652. b=16.088264119063613,
  1653. c=-1.9631175993998025,
  1654. z=(0.4172413793103451-0.9482758620689655j),
  1655. expected=(-7024239.358547302+2481375.02681063j),
  1656. rtol=5e-14,
  1657. ),
  1658. ),
  1659. pytest.param(
  1660. Hyp2f1TestCase(
  1661. a=16.25,
  1662. b=-15.75,
  1663. c=1.5,
  1664. z=(0.18965517241379315+1.024137931034483j),
  1665. expected=(92371704.94848-403546832.548352j),
  1666. rtol=5e-06,
  1667. ),
  1668. ),
  1669. pytest.param(
  1670. Hyp2f1TestCase(
  1671. a=8.5,
  1672. b=-7.949900487447654,
  1673. c=8.5,
  1674. z=(0.26551724137931054-1.024137931034483j),
  1675. expected=(1.9335109845308265+5.986542524829654j),
  1676. rtol=5e-10,
  1677. ),
  1678. ),
  1679. pytest.param(
  1680. Hyp2f1TestCase(
  1681. a=8.095813935368371,
  1682. b=-1.92872979730171,
  1683. c=-7.93846038215665,
  1684. z=(0.4931034482758623+0.8724137931034486j),
  1685. expected=(-122.52639696039328-59.72428067512221j),
  1686. rtol=5e-14,
  1687. ),
  1688. ),
  1689. pytest.param(
  1690. Hyp2f1TestCase(
  1691. a=16.25,
  1692. b=-1.75,
  1693. c=-1.5,
  1694. z=(0.4931034482758623+0.9482758620689657j),
  1695. expected=(-90.40642053579428+50.50649180047921j),
  1696. rtol=5e-08,
  1697. ),
  1698. ),
  1699. pytest.param(
  1700. Hyp2f1TestCase(
  1701. a=-3.5,
  1702. b=8.077282662161238,
  1703. c=16.5,
  1704. z=(0.4931034482758623+0.9482758620689657j),
  1705. expected=(-0.2155745818150323-0.564628986876639j),
  1706. rtol=5e-15,
  1707. ),
  1708. ),
  1709. pytest.param(
  1710. Hyp2f1TestCase(
  1711. a=-0.9220024191881196,
  1712. b=1.0561196186065624,
  1713. c=8.031683612216888,
  1714. z=(0.4172413793103451-0.9482758620689655j),
  1715. expected=(0.9503140488280465+0.11574960074292677j),
  1716. rtol=5e-15,
  1717. ),
  1718. ),
  1719. pytest.param(
  1720. Hyp2f1TestCase(
  1721. a=-0.75,
  1722. b=2.25,
  1723. c=-15.5,
  1724. z=(0.4172413793103451+0.9482758620689657j),
  1725. expected=(0.9285862488442175+0.8203699266719692j),
  1726. rtol=5e-13,
  1727. ),
  1728. ),
  1729. pytest.param(
  1730. Hyp2f1TestCase(
  1731. a=-7.75,
  1732. b=4.25,
  1733. c=-15.5,
  1734. z=(0.3413793103448277-0.9482758620689655j),
  1735. expected=(-1.0509834850116921-1.1145522325486075j),
  1736. rtol=1e-14,
  1737. ),
  1738. ),
  1739. pytest.param(
  1740. Hyp2f1TestCase(
  1741. a=-7.937789122896016,
  1742. b=-0.9629749245209605,
  1743. c=2.0397202577726152,
  1744. z=(0.4931034482758623-0.9482758620689655j),
  1745. expected=(2.88119116536769-3.4249933450696806j),
  1746. rtol=5e-15,
  1747. ),
  1748. ),
  1749. pytest.param(
  1750. Hyp2f1TestCase(
  1751. a=-15.5,
  1752. b=-15.964218273004214,
  1753. c=16.5,
  1754. z=(0.18965517241379315+1.024137931034483j),
  1755. expected=(199.65868451496038+347.79384207302877j),
  1756. rtol=1e-13,
  1757. ),
  1758. ),
  1759. pytest.param(
  1760. Hyp2f1TestCase(
  1761. a=-15.75,
  1762. b=-15.75,
  1763. c=-3.5,
  1764. z=(0.4931034482758623-0.8724137931034484j),
  1765. expected=(-208138312553.07013+58631611809.026955j),
  1766. rtol=5e-14,
  1767. ),
  1768. ),
  1769. pytest.param(
  1770. Hyp2f1TestCase(
  1771. a=-7.937789122896016,
  1772. b=-15.5,
  1773. c=-7.5,
  1774. z=(0.3413793103448277+0.9482758620689657j),
  1775. expected=(-23032.90519856288-18256.94050457296j),
  1776. rtol=5e-15,
  1777. ),
  1778. ),
  1779. pytest.param(
  1780. Hyp2f1TestCase(
  1781. a=4.5,
  1782. b=1.5,
  1783. c=1.0561196186065624,
  1784. z=(0.4931034482758623-0.8724137931034484j),
  1785. expected=(1.507342459587056+1.2332023580148403j),
  1786. rtol=1e-15,
  1787. ),
  1788. ),
  1789. pytest.param(
  1790. Hyp2f1TestCase(
  1791. a=2.5,
  1792. b=4.5,
  1793. c=-3.9316537064827854,
  1794. z=(0.4172413793103451+0.9482758620689657j),
  1795. expected=(7044.766127108853-40210.365567285575j),
  1796. rtol=5e-14,
  1797. ),
  1798. ),
  1799. pytest.param(
  1800. Hyp2f1TestCase(
  1801. a=1.5,
  1802. b=-1.5,
  1803. c=1.0561196186065624,
  1804. z=(0.03793103448275881+1.024137931034483j),
  1805. expected=(0.2725347741628333-2.247314875514784j),
  1806. rtol=1e-15,
  1807. ),
  1808. ),
  1809. pytest.param(
  1810. Hyp2f1TestCase(
  1811. a=4.5,
  1812. b=-1.5,
  1813. c=-7.949900487447654,
  1814. z=(0.26551724137931054+1.024137931034483j),
  1815. expected=(-11.250200011017546+12.597393659160472j),
  1816. rtol=5e-14,
  1817. ),
  1818. ),
  1819. pytest.param(
  1820. Hyp2f1TestCase(
  1821. a=-7.5,
  1822. b=8.5,
  1823. c=16.088264119063613,
  1824. z=(0.26551724137931054+1.024137931034483j),
  1825. expected=(-0.18515160890991517+0.7959014164484782j),
  1826. rtol=1e-15,
  1827. ),
  1828. ),
  1829. pytest.param(
  1830. Hyp2f1TestCase(
  1831. a=-7.5,
  1832. b=16.5,
  1833. c=-3.9316537064827854,
  1834. z=(0.3413793103448277-1.024137931034483j),
  1835. expected=(998246378.8556538+1112032928.103645j),
  1836. rtol=5e-14,
  1837. ),
  1838. ),
  1839. pytest.param(
  1840. Hyp2f1TestCase(
  1841. a=-1.5,
  1842. b=-3.5,
  1843. c=2.050308316530781,
  1844. z=(0.03793103448275881+1.024137931034483j),
  1845. expected=(0.5527670397711952+2.697662715303637j),
  1846. rtol=1e-15,
  1847. ),
  1848. ),
  1849. pytest.param(
  1850. Hyp2f1TestCase(
  1851. a=-15.5,
  1852. b=-1.5,
  1853. c=-0.9629749245209605,
  1854. z=(0.4931034482758623-0.8724137931034484j),
  1855. expected=(55.396931662136886+968.467463806326j),
  1856. rtol=5e-14,
  1857. ),
  1858. ),
  1859. ]
  1860. )
  1861. def test_region5(self, hyp2f1_test_case):
  1862. """1 < |z| < 1.1 and |1 - z| >= 0.9 and real(z) >= 0"""
  1863. a, b, c, z, expected, rtol = hyp2f1_test_case
  1864. assert 1 < abs(z) < 1.1 and abs(1 - z) >= 0.9 and z.real >= 0
  1865. assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
  1866. @pytest.mark.parametrize(
  1867. "hyp2f1_test_case",
  1868. [
  1869. pytest.param(
  1870. Hyp2f1TestCase(
  1871. a=8.095813935368371,
  1872. b=4.0013768449590685,
  1873. c=4.078873014294075,
  1874. z=(-0.9473684210526316+0.5263157894736841j),
  1875. expected=(-0.0018093573941378783+0.003481887377423739j),
  1876. rtol=5e-15,
  1877. ),
  1878. ),
  1879. pytest.param(
  1880. Hyp2f1TestCase(
  1881. a=16.087593263474208,
  1882. b=2.050308316530781,
  1883. c=1.0651378143226575,
  1884. z=(-0.736842105263158-0.736842105263158j),
  1885. expected=(-0.00023401243818780545-1.7983496305603562e-05j),
  1886. rtol=1e-15,
  1887. ),
  1888. ),
  1889. pytest.param(
  1890. Hyp2f1TestCase(
  1891. a=1.0272592605282642,
  1892. b=8.077282662161238,
  1893. c=4.078873014294075,
  1894. z=(-0.5263157894736843-0.9473684210526316j),
  1895. expected=(0.22359773002226846-0.24092487123993353j),
  1896. rtol=1e-15,
  1897. ),
  1898. ),
  1899. pytest.param(
  1900. Hyp2f1TestCase(
  1901. a=1.0272592605282642,
  1902. b=2.050308316530781,
  1903. c=-15.963511401609862,
  1904. z=(-0.9473684210526316-0.5263157894736843j),
  1905. expected=(1.191573745740011+0.14347394589721466j),
  1906. rtol=5e-14,
  1907. ),
  1908. ),
  1909. pytest.param(
  1910. Hyp2f1TestCase(
  1911. a=4.080187217753502,
  1912. b=4.0013768449590685,
  1913. c=-15.963511401609862,
  1914. z=(-0.9473684210526316-0.5263157894736843j),
  1915. expected=(31.822620756901784-66.09094396747611j),
  1916. rtol=5e-14,
  1917. ),
  1918. ),
  1919. pytest.param(
  1920. Hyp2f1TestCase(
  1921. a=4.080187217753502,
  1922. b=8.077282662161238,
  1923. c=-7.93846038215665,
  1924. z=(-0.9473684210526316+0.5263157894736841j),
  1925. expected=(207.16750179245952+34.80478274924269j),
  1926. rtol=5e-12,
  1927. ),
  1928. ),
  1929. pytest.param(
  1930. Hyp2f1TestCase(
  1931. a=8.095813935368371,
  1932. b=-7.949900487447654,
  1933. c=8.031683612216888,
  1934. z=(-0.736842105263158+0.7368421052631575j),
  1935. expected=(-159.62429364277145+9.154224290644898j),
  1936. rtol=5e-14,
  1937. ),
  1938. ),
  1939. pytest.param(
  1940. Hyp2f1TestCase(
  1941. a=1.0272592605282642,
  1942. b=-1.92872979730171,
  1943. c=16.056809865262608,
  1944. z=(-0.9473684210526316+0.5263157894736841j),
  1945. expected=(1.121122351247184-0.07170260470126685j),
  1946. rtol=5e-15,
  1947. ),
  1948. ),
  1949. pytest.param(
  1950. Hyp2f1TestCase(
  1951. a=16.087593263474208,
  1952. b=-0.9629749245209605,
  1953. c=16.056809865262608,
  1954. z=(-0.9473684210526316+0.5263157894736841j),
  1955. expected=(1.9040596681316053-0.4951799449960107j),
  1956. rtol=5e-14,
  1957. ),
  1958. ),
  1959. pytest.param(
  1960. Hyp2f1TestCase(
  1961. a=1.0272592605282642,
  1962. b=-1.92872979730171,
  1963. c=-0.906685989801748,
  1964. z=(-0.9473684210526316-0.5263157894736843j),
  1965. expected=(-14.496623497780739-21.897524523299875j),
  1966. rtol=5e-14,
  1967. ),
  1968. ),
  1969. pytest.param(
  1970. Hyp2f1TestCase(
  1971. a=4.080187217753502,
  1972. b=-3.9316537064827854,
  1973. c=-3.9924618758357022,
  1974. z=(-0.5263157894736843-0.9473684210526316j),
  1975. expected=(36.33473466026878+253.88728442029577j),
  1976. rtol=5e-14,
  1977. ),
  1978. ),
  1979. pytest.param(
  1980. Hyp2f1TestCase(
  1981. a=1.0272592605282642,
  1982. b=-15.964218273004214,
  1983. c=-0.906685989801748,
  1984. z=(-0.9473684210526316+0.5263157894736841j),
  1985. expected=(1505052.5653144997-50820766.81043443j),
  1986. rtol=1e-14,
  1987. ),
  1988. ),
  1989. pytest.param(
  1990. Hyp2f1TestCase(
  1991. a=-3.956227226099288,
  1992. b=4.0013768449590685,
  1993. c=1.0651378143226575,
  1994. z=(-0.5263157894736843+0.9473684210526314j),
  1995. expected=(-127.79407519260877-28.69899444941112j),
  1996. rtol=5e-15,
  1997. ),
  1998. ),
  1999. pytest.param(
  2000. Hyp2f1TestCase(
  2001. a=-1.9214641416286231,
  2002. b=8.077282662161238,
  2003. c=16.056809865262608,
  2004. z=(-0.9473684210526316-0.5263157894736843j),
  2005. expected=(2.0623331933754976+0.741234463565458j),
  2006. rtol=5e-15,
  2007. ),
  2008. ),
  2009. pytest.param(
  2010. Hyp2f1TestCase(
  2011. a=-3.956227226099288,
  2012. b=8.077282662161238,
  2013. c=2.0397202577726152,
  2014. z=(-0.9473684210526316+0.5263157894736841j),
  2015. expected=(30.729193458862525-292.5700835046965j),
  2016. rtol=1e-15,
  2017. ),
  2018. ),
  2019. pytest.param(
  2020. Hyp2f1TestCase(
  2021. a=-1.9214641416286231,
  2022. b=1.0561196186065624,
  2023. c=-1.9631175993998025,
  2024. z=(-0.5263157894736843-0.9473684210526316j),
  2025. expected=(1.1285917906203495-0.735264575450189j),
  2026. rtol=5e-15,
  2027. ),
  2028. ),
  2029. pytest.param(
  2030. Hyp2f1TestCase(
  2031. a=-0.9220024191881196,
  2032. b=1.0561196186065624,
  2033. c=-3.9924618758357022,
  2034. z=(-0.736842105263158+0.7368421052631575j),
  2035. expected=(0.6356474446678052-0.02429663008952248j),
  2036. rtol=5e-14,
  2037. ),
  2038. ),
  2039. pytest.param(
  2040. Hyp2f1TestCase(
  2041. a=-1.9214641416286231,
  2042. b=16.088264119063613,
  2043. c=-7.93846038215665,
  2044. z=(-0.736842105263158+0.7368421052631575j),
  2045. expected=(0.4718880510273174+0.655083067736377j),
  2046. rtol=1e-11,
  2047. ),
  2048. ),
  2049. pytest.param(
  2050. Hyp2f1TestCase(
  2051. a=-7.937789122896016,
  2052. b=-3.9316537064827854,
  2053. c=16.056809865262608,
  2054. z=(-0.9473684210526316+0.5263157894736841j),
  2055. expected=(-0.14681550942352714+0.16092206364265146j),
  2056. rtol=5e-11,
  2057. ),
  2058. ),
  2059. pytest.param(
  2060. Hyp2f1TestCase(
  2061. a=-0.9220024191881196,
  2062. b=-15.964218273004214,
  2063. c=1.0651378143226575,
  2064. z=(-0.5263157894736843+0.9473684210526314j),
  2065. expected=(-6.436835190526225+22.883156700606182j),
  2066. rtol=5e-14,
  2067. ),
  2068. ),
  2069. pytest.param(
  2070. Hyp2f1TestCase(
  2071. a=-0.9220024191881196,
  2072. b=-7.949900487447654,
  2073. c=4.078873014294075,
  2074. z=(-0.9473684210526316-0.5263157894736843j),
  2075. expected=(-0.7505682955068583-1.1026583264249945j),
  2076. rtol=1e-15,
  2077. ),
  2078. ),
  2079. pytest.param(
  2080. Hyp2f1TestCase(
  2081. a=-3.956227226099288,
  2082. b=-3.9316537064827854,
  2083. c=-7.93846038215665,
  2084. z=(-0.9473684210526316-0.5263157894736843j),
  2085. expected=(3.6247814989198166+2.596041360148318j),
  2086. rtol=5e-15,
  2087. ),
  2088. ),
  2089. pytest.param(
  2090. Hyp2f1TestCase(
  2091. a=-3.956227226099288,
  2092. b=-15.964218273004214,
  2093. c=-1.9631175993998025,
  2094. z=(-0.5263157894736843-0.9473684210526316j),
  2095. expected=(-59537.65287927933-669074.4342539902j),
  2096. rtol=5e-15,
  2097. ),
  2098. ),
  2099. pytest.param(
  2100. Hyp2f1TestCase(
  2101. a=-3.956227226099288,
  2102. b=-15.964218273004214,
  2103. c=-1.9631175993998025,
  2104. z=(-0.9473684210526316-0.5263157894736843j),
  2105. expected=(-433084.9970266166+431088.393918521j),
  2106. rtol=5e-14,
  2107. ),
  2108. ),
  2109. ]
  2110. )
  2111. def test_region6(self, hyp2f1_test_case):
  2112. """|z| > 1 but not in region 5."""
  2113. a, b, c, z, expected, rtol = hyp2f1_test_case
  2114. assert (
  2115. abs(z) > 1 and
  2116. not (1 < abs(z) < 1.1 and abs(1 - z) >= 0.9 and z.real >= 0)
  2117. )
  2118. assert_allclose(hyp2f1(a, b, c, z), expected, rtol=rtol)
  2119. @pytest.mark.slow
  2120. @check_version(mpmath, "1.0.0")
  2121. def test_test_hyp2f1(self):
  2122. """Test that expected values match what is computed by mpmath.
  2123. This gathers the parameters for the test cases out of the pytest marks.
  2124. The parameters are a, b, c, z, expected, rtol, where expected should
  2125. be the value of hyp2f1(a, b, c, z) computed with mpmath. The test
  2126. recomputes hyp2f1(a, b, c, z) using mpmath and verifies that expected
  2127. actually is the correct value. This allows the data for the tests to
  2128. live within the test code instead of an external datafile, while
  2129. avoiding having to compute the results with mpmath during the test,
  2130. except for when slow tests are being run.
  2131. """
  2132. test_methods = [
  2133. test_method for test_method in dir(self)
  2134. if test_method.startswith('test') and
  2135. # Filter properties and attributes (futureproofing).
  2136. callable(getattr(self, test_method)) and
  2137. # Filter out this test
  2138. test_method != 'test_test_hyp2f1'
  2139. ]
  2140. for test_method in test_methods:
  2141. params = self._get_test_parameters(getattr(self, test_method))
  2142. for a, b, c, z, expected, _ in params:
  2143. assert_allclose(mp_hyp2f1(a, b, c, z), expected, rtol=2.25e-16)
  2144. def _get_test_parameters(self, test_method):
  2145. """Get pytest.mark parameters for a test in this class."""
  2146. return [
  2147. case.values[0] for mark in test_method.pytestmark
  2148. if mark.name == 'parametrize'
  2149. for case in mark.args[1]
  2150. ]