test_distributions.py 136 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640
  1. """ Test functions for stats module
  2. """
  3. from __future__ import division, print_function, absolute_import
  4. import warnings
  5. import re
  6. import sys
  7. import pickle
  8. import os
  9. from numpy.testing import (assert_equal, assert_array_equal,
  10. assert_almost_equal, assert_array_almost_equal,
  11. assert_allclose, assert_, assert_warns)
  12. import pytest
  13. from pytest import raises as assert_raises
  14. from scipy._lib._numpy_compat import suppress_warnings
  15. import numpy
  16. import numpy as np
  17. from numpy import typecodes, array
  18. from numpy.lib.recfunctions import rec_append_fields
  19. from scipy import special
  20. from scipy.integrate import IntegrationWarning
  21. import scipy.stats as stats
  22. from scipy.stats._distn_infrastructure import argsreduce
  23. import scipy.stats.distributions
  24. from scipy.special import xlogy
  25. from .test_continuous_basic import distcont
  26. # python -OO strips docstrings
  27. DOCSTRINGS_STRIPPED = sys.flags.optimize > 1
  28. # Generate test cases to test cdf and distribution consistency.
  29. # Note that this list does not include all distributions.
  30. dists = ['uniform', 'norm', 'lognorm', 'expon', 'beta',
  31. 'powerlaw', 'bradford', 'burr', 'fisk', 'cauchy', 'halfcauchy',
  32. 'foldcauchy', 'gamma', 'gengamma', 'loggamma',
  33. 'alpha', 'anglit', 'arcsine', 'betaprime', 'dgamma', 'moyal',
  34. 'exponnorm', 'exponweib', 'exponpow', 'frechet_l', 'frechet_r',
  35. 'gilbrat', 'f', 'ncf', 'chi2', 'chi', 'nakagami', 'genpareto',
  36. 'genextreme', 'genhalflogistic', 'pareto', 'lomax', 'halfnorm',
  37. 'halflogistic', 'fatiguelife', 'foldnorm', 'ncx2', 't', 'nct',
  38. 'weibull_min', 'weibull_max', 'dweibull', 'maxwell', 'rayleigh',
  39. 'genlogistic', 'logistic', 'gumbel_l', 'gumbel_r', 'gompertz',
  40. 'hypsecant', 'laplace', 'reciprocal', 'trapz', 'triang',
  41. 'tukeylambda', 'vonmises', 'vonmises_line', 'pearson3', 'gennorm',
  42. 'halfgennorm', 'rice', 'kappa4', 'kappa3', 'truncnorm', 'argus',
  43. 'crystalball']
  44. def _assert_hasattr(a, b, msg=None):
  45. if msg is None:
  46. msg = '%s does not have attribute %s' % (a, b)
  47. assert_(hasattr(a, b), msg=msg)
  48. def test_api_regression():
  49. # https://github.com/scipy/scipy/issues/3802
  50. _assert_hasattr(scipy.stats.distributions, 'f_gen')
  51. # check function for test generator
  52. def check_distribution(dist, args, alpha):
  53. with suppress_warnings() as sup:
  54. # frechet_l and frechet_r are deprecated, so all their
  55. # methods generate DeprecationWarnings.
  56. sup.filter(category=DeprecationWarning, message=".*frechet_")
  57. D, pval = stats.kstest(dist, '', args=args, N=1000)
  58. if (pval < alpha):
  59. D, pval = stats.kstest(dist, '', args=args, N=1000)
  60. assert_(pval > alpha,
  61. msg="D = {}; pval = {}; alpha = {}; args = {}".format(
  62. D, pval, alpha, args))
  63. def cases_test_all_distributions():
  64. np.random.seed(1234)
  65. for dist in dists:
  66. distfunc = getattr(stats, dist)
  67. nargs = distfunc.numargs
  68. alpha = 0.01
  69. if dist == 'fatiguelife':
  70. alpha = 0.001
  71. if dist == 'trapz':
  72. args = tuple(np.sort(np.random.random(nargs)))
  73. elif dist == 'triang':
  74. args = tuple(np.random.random(nargs))
  75. elif dist == 'reciprocal' or dist == 'truncnorm':
  76. vals = np.random.random(nargs)
  77. vals[1] = vals[0] + 1.0
  78. args = tuple(vals)
  79. elif dist == 'vonmises':
  80. yield dist, (10,), alpha
  81. yield dist, (101,), alpha
  82. args = tuple(1.0 + np.random.random(nargs))
  83. else:
  84. args = tuple(1.0 + np.random.random(nargs))
  85. yield dist, args, alpha
  86. @pytest.mark.parametrize('dist,args,alpha', cases_test_all_distributions())
  87. def test_all_distributions(dist, args, alpha):
  88. check_distribution(dist, args, alpha)
  89. def check_vonmises_pdf_periodic(k, l, s, x):
  90. vm = stats.vonmises(k, loc=l, scale=s)
  91. assert_almost_equal(vm.pdf(x), vm.pdf(x % (2*numpy.pi*s)))
  92. def check_vonmises_cdf_periodic(k, l, s, x):
  93. vm = stats.vonmises(k, loc=l, scale=s)
  94. assert_almost_equal(vm.cdf(x) % 1, vm.cdf(x % (2*numpy.pi*s)) % 1)
  95. def test_vonmises_pdf_periodic():
  96. for k in [0.1, 1, 101]:
  97. for x in [0, 1, numpy.pi, 10, 100]:
  98. check_vonmises_pdf_periodic(k, 0, 1, x)
  99. check_vonmises_pdf_periodic(k, 1, 1, x)
  100. check_vonmises_pdf_periodic(k, 0, 10, x)
  101. check_vonmises_cdf_periodic(k, 0, 1, x)
  102. check_vonmises_cdf_periodic(k, 1, 1, x)
  103. check_vonmises_cdf_periodic(k, 0, 10, x)
  104. def test_vonmises_line_support():
  105. assert_equal(stats.vonmises_line.a, -np.pi)
  106. assert_equal(stats.vonmises_line.b, np.pi)
  107. def test_vonmises_numerical():
  108. vm = stats.vonmises(800)
  109. assert_almost_equal(vm.cdf(0), 0.5)
  110. @pytest.mark.parametrize('dist',
  111. ['alpha', 'betaprime', 'burr', 'burr12',
  112. 'fatiguelife', 'invgamma', 'invgauss', 'invweibull',
  113. 'johnsonsb', 'levy', 'levy_l', 'lognorm', 'gilbrat',
  114. 'powerlognorm', 'rayleigh', 'wald'])
  115. def test_support(dist):
  116. """gh-6235"""
  117. dct = dict(distcont)
  118. args = dct[dist]
  119. dist = getattr(stats, dist)
  120. assert_almost_equal(dist.pdf(dist.a, *args), 0)
  121. assert_equal(dist.logpdf(dist.a, *args), -np.inf)
  122. assert_almost_equal(dist.pdf(dist.b, *args), 0)
  123. assert_equal(dist.logpdf(dist.b, *args), -np.inf)
  124. class TestRandInt(object):
  125. def setup_method(self):
  126. np.random.seed(1234)
  127. def test_rvs(self):
  128. vals = stats.randint.rvs(5, 30, size=100)
  129. assert_(numpy.all(vals < 30) & numpy.all(vals >= 5))
  130. assert_(len(vals) == 100)
  131. vals = stats.randint.rvs(5, 30, size=(2, 50))
  132. assert_(numpy.shape(vals) == (2, 50))
  133. assert_(vals.dtype.char in typecodes['AllInteger'])
  134. val = stats.randint.rvs(15, 46)
  135. assert_((val >= 15) & (val < 46))
  136. assert_(isinstance(val, numpy.ScalarType), msg=repr(type(val)))
  137. val = stats.randint(15, 46).rvs(3)
  138. assert_(val.dtype.char in typecodes['AllInteger'])
  139. def test_pdf(self):
  140. k = numpy.r_[0:36]
  141. out = numpy.where((k >= 5) & (k < 30), 1.0/(30-5), 0)
  142. vals = stats.randint.pmf(k, 5, 30)
  143. assert_array_almost_equal(vals, out)
  144. def test_cdf(self):
  145. x = np.linspace(0,36,100)
  146. k = numpy.floor(x)
  147. out = numpy.select([k >= 30, k >= 5], [1.0, (k-5.0+1)/(30-5.0)], 0)
  148. vals = stats.randint.cdf(x, 5, 30)
  149. assert_array_almost_equal(vals, out, decimal=12)
  150. class TestBinom(object):
  151. def setup_method(self):
  152. np.random.seed(1234)
  153. def test_rvs(self):
  154. vals = stats.binom.rvs(10, 0.75, size=(2, 50))
  155. assert_(numpy.all(vals >= 0) & numpy.all(vals <= 10))
  156. assert_(numpy.shape(vals) == (2, 50))
  157. assert_(vals.dtype.char in typecodes['AllInteger'])
  158. val = stats.binom.rvs(10, 0.75)
  159. assert_(isinstance(val, int))
  160. val = stats.binom(10, 0.75).rvs(3)
  161. assert_(isinstance(val, numpy.ndarray))
  162. assert_(val.dtype.char in typecodes['AllInteger'])
  163. def test_pmf(self):
  164. # regression test for Ticket #1842
  165. vals1 = stats.binom.pmf(100, 100, 1)
  166. vals2 = stats.binom.pmf(0, 100, 0)
  167. assert_allclose(vals1, 1.0, rtol=1e-15, atol=0)
  168. assert_allclose(vals2, 1.0, rtol=1e-15, atol=0)
  169. def test_entropy(self):
  170. # Basic entropy tests.
  171. b = stats.binom(2, 0.5)
  172. expected_p = np.array([0.25, 0.5, 0.25])
  173. expected_h = -sum(xlogy(expected_p, expected_p))
  174. h = b.entropy()
  175. assert_allclose(h, expected_h)
  176. b = stats.binom(2, 0.0)
  177. h = b.entropy()
  178. assert_equal(h, 0.0)
  179. b = stats.binom(2, 1.0)
  180. h = b.entropy()
  181. assert_equal(h, 0.0)
  182. def test_warns_p0(self):
  183. # no spurious warnigns are generated for p=0; gh-3817
  184. with warnings.catch_warnings():
  185. warnings.simplefilter("error", RuntimeWarning)
  186. assert_equal(stats.binom(n=2, p=0).mean(), 0)
  187. assert_equal(stats.binom(n=2, p=0).std(), 0)
  188. class TestBernoulli(object):
  189. def setup_method(self):
  190. np.random.seed(1234)
  191. def test_rvs(self):
  192. vals = stats.bernoulli.rvs(0.75, size=(2, 50))
  193. assert_(numpy.all(vals >= 0) & numpy.all(vals <= 1))
  194. assert_(numpy.shape(vals) == (2, 50))
  195. assert_(vals.dtype.char in typecodes['AllInteger'])
  196. val = stats.bernoulli.rvs(0.75)
  197. assert_(isinstance(val, int))
  198. val = stats.bernoulli(0.75).rvs(3)
  199. assert_(isinstance(val, numpy.ndarray))
  200. assert_(val.dtype.char in typecodes['AllInteger'])
  201. def test_entropy(self):
  202. # Simple tests of entropy.
  203. b = stats.bernoulli(0.25)
  204. expected_h = -0.25*np.log(0.25) - 0.75*np.log(0.75)
  205. h = b.entropy()
  206. assert_allclose(h, expected_h)
  207. b = stats.bernoulli(0.0)
  208. h = b.entropy()
  209. assert_equal(h, 0.0)
  210. b = stats.bernoulli(1.0)
  211. h = b.entropy()
  212. assert_equal(h, 0.0)
  213. class TestBradford(object):
  214. # gh-6216
  215. def test_cdf_ppf(self):
  216. c = 0.1
  217. x = np.logspace(-20, -4)
  218. q = stats.bradford.cdf(x, c)
  219. xx = stats.bradford.ppf(q, c)
  220. assert_allclose(x, xx)
  221. class TestNBinom(object):
  222. def setup_method(self):
  223. np.random.seed(1234)
  224. def test_rvs(self):
  225. vals = stats.nbinom.rvs(10, 0.75, size=(2, 50))
  226. assert_(numpy.all(vals >= 0))
  227. assert_(numpy.shape(vals) == (2, 50))
  228. assert_(vals.dtype.char in typecodes['AllInteger'])
  229. val = stats.nbinom.rvs(10, 0.75)
  230. assert_(isinstance(val, int))
  231. val = stats.nbinom(10, 0.75).rvs(3)
  232. assert_(isinstance(val, numpy.ndarray))
  233. assert_(val.dtype.char in typecodes['AllInteger'])
  234. def test_pmf(self):
  235. # regression test for ticket 1779
  236. assert_allclose(np.exp(stats.nbinom.logpmf(700, 721, 0.52)),
  237. stats.nbinom.pmf(700, 721, 0.52))
  238. # logpmf(0,1,1) shouldn't return nan (regression test for gh-4029)
  239. val = scipy.stats.nbinom.logpmf(0, 1, 1)
  240. assert_equal(val, 0)
  241. class TestNormInvGauss(object):
  242. def setup_method(self):
  243. np.random.seed(1234)
  244. def test_cdf_R(self):
  245. # test pdf and cdf vals against R
  246. # require("GeneralizedHyperbolic")
  247. # x_test <- c(-7, -5, 0, 8, 15)
  248. # r_cdf <- GeneralizedHyperbolic::pnig(x_test, mu = 0, a = 1, b = 0.5)
  249. # r_pdf <- GeneralizedHyperbolic::dnig(x_test, mu = 0, a = 1, b = 0.5)
  250. r_cdf = np.array([8.034920282e-07, 2.512671945e-05, 3.186661051e-01,
  251. 9.988650664e-01, 9.999848769e-01])
  252. x_test = np.array([-7, -5, 0, 8, 15])
  253. vals_cdf = stats.norminvgauss.cdf(x_test, a=1, b=0.5)
  254. assert_allclose(vals_cdf, r_cdf, atol=1e-9)
  255. def test_pdf_R(self):
  256. # values from R as defined in test_cdf_R
  257. r_pdf = np.array([1.359600783e-06, 4.413878805e-05, 4.555014266e-01,
  258. 7.450485342e-04, 8.917889931e-06])
  259. x_test = np.array([-7, -5, 0, 8, 15])
  260. vals_pdf = stats.norminvgauss.pdf(x_test, a=1, b=0.5)
  261. assert_allclose(vals_pdf, r_pdf, atol=1e-9)
  262. def test_stats(self):
  263. a, b = 1, 0.5
  264. gamma = np.sqrt(a**2 - b**2)
  265. v_stats = (b / gamma, a**2 / gamma**3, 3.0 * b / (a * np.sqrt(gamma)),
  266. 3.0 * (1 + 4 * b**2 / a**2) / gamma)
  267. assert_equal(v_stats, stats.norminvgauss.stats(a, b, moments='mvsk'))
  268. def test_ppf(self):
  269. a, b = 1, 0.5
  270. x_test = np.array([0.001, 0.5, 0.999])
  271. vals = stats.norminvgauss.ppf(x_test, a, b)
  272. assert_allclose(x_test, stats.norminvgauss.cdf(vals, a, b))
  273. class TestGeom(object):
  274. def setup_method(self):
  275. np.random.seed(1234)
  276. def test_rvs(self):
  277. vals = stats.geom.rvs(0.75, size=(2, 50))
  278. assert_(numpy.all(vals >= 0))
  279. assert_(numpy.shape(vals) == (2, 50))
  280. assert_(vals.dtype.char in typecodes['AllInteger'])
  281. val = stats.geom.rvs(0.75)
  282. assert_(isinstance(val, int))
  283. val = stats.geom(0.75).rvs(3)
  284. assert_(isinstance(val, numpy.ndarray))
  285. assert_(val.dtype.char in typecodes['AllInteger'])
  286. def test_pmf(self):
  287. vals = stats.geom.pmf([1, 2, 3], 0.5)
  288. assert_array_almost_equal(vals, [0.5, 0.25, 0.125])
  289. def test_logpmf(self):
  290. # regression test for ticket 1793
  291. vals1 = np.log(stats.geom.pmf([1, 2, 3], 0.5))
  292. vals2 = stats.geom.logpmf([1, 2, 3], 0.5)
  293. assert_allclose(vals1, vals2, rtol=1e-15, atol=0)
  294. # regression test for gh-4028
  295. val = stats.geom.logpmf(1, 1)
  296. assert_equal(val, 0.0)
  297. def test_cdf_sf(self):
  298. vals = stats.geom.cdf([1, 2, 3], 0.5)
  299. vals_sf = stats.geom.sf([1, 2, 3], 0.5)
  300. expected = array([0.5, 0.75, 0.875])
  301. assert_array_almost_equal(vals, expected)
  302. assert_array_almost_equal(vals_sf, 1-expected)
  303. def test_logcdf_logsf(self):
  304. vals = stats.geom.logcdf([1, 2, 3], 0.5)
  305. vals_sf = stats.geom.logsf([1, 2, 3], 0.5)
  306. expected = array([0.5, 0.75, 0.875])
  307. assert_array_almost_equal(vals, np.log(expected))
  308. assert_array_almost_equal(vals_sf, np.log1p(-expected))
  309. def test_ppf(self):
  310. vals = stats.geom.ppf([0.5, 0.75, 0.875], 0.5)
  311. expected = array([1.0, 2.0, 3.0])
  312. assert_array_almost_equal(vals, expected)
  313. def test_ppf_underflow(self):
  314. # this should not underflow
  315. assert_allclose(stats.geom.ppf(1e-20, 1e-20), 1.0, atol=1e-14)
  316. class TestPlanck(object):
  317. def setup_method(self):
  318. np.random.seed(1234)
  319. def test_sf(self):
  320. vals = stats.planck.sf([1, 2, 3], 5.)
  321. expected = array([4.5399929762484854e-05,
  322. 3.0590232050182579e-07,
  323. 2.0611536224385579e-09])
  324. assert_array_almost_equal(vals, expected)
  325. def test_logsf(self):
  326. vals = stats.planck.logsf([1000., 2000., 3000.], 1000.)
  327. expected = array([-1001000., -2001000., -3001000.])
  328. assert_array_almost_equal(vals, expected)
  329. class TestGennorm(object):
  330. def test_laplace(self):
  331. # test against Laplace (special case for beta=1)
  332. points = [1, 2, 3]
  333. pdf1 = stats.gennorm.pdf(points, 1)
  334. pdf2 = stats.laplace.pdf(points)
  335. assert_almost_equal(pdf1, pdf2)
  336. def test_norm(self):
  337. # test against normal (special case for beta=2)
  338. points = [1, 2, 3]
  339. pdf1 = stats.gennorm.pdf(points, 2)
  340. pdf2 = stats.norm.pdf(points, scale=2**-.5)
  341. assert_almost_equal(pdf1, pdf2)
  342. class TestHalfgennorm(object):
  343. def test_expon(self):
  344. # test against exponential (special case for beta=1)
  345. points = [1, 2, 3]
  346. pdf1 = stats.halfgennorm.pdf(points, 1)
  347. pdf2 = stats.expon.pdf(points)
  348. assert_almost_equal(pdf1, pdf2)
  349. def test_halfnorm(self):
  350. # test against half normal (special case for beta=2)
  351. points = [1, 2, 3]
  352. pdf1 = stats.halfgennorm.pdf(points, 2)
  353. pdf2 = stats.halfnorm.pdf(points, scale=2**-.5)
  354. assert_almost_equal(pdf1, pdf2)
  355. def test_gennorm(self):
  356. # test against generalized normal
  357. points = [1, 2, 3]
  358. pdf1 = stats.halfgennorm.pdf(points, .497324)
  359. pdf2 = stats.gennorm.pdf(points, .497324)
  360. assert_almost_equal(pdf1, 2*pdf2)
  361. class TestTruncnorm(object):
  362. def setup_method(self):
  363. np.random.seed(1234)
  364. def test_ppf_ticket1131(self):
  365. vals = stats.truncnorm.ppf([-0.5, 0, 1e-4, 0.5, 1-1e-4, 1, 2], -1., 1.,
  366. loc=[3]*7, scale=2)
  367. expected = np.array([np.nan, 1, 1.00056419, 3, 4.99943581, 5, np.nan])
  368. assert_array_almost_equal(vals, expected)
  369. def test_isf_ticket1131(self):
  370. vals = stats.truncnorm.isf([-0.5, 0, 1e-4, 0.5, 1-1e-4, 1, 2], -1., 1.,
  371. loc=[3]*7, scale=2)
  372. expected = np.array([np.nan, 5, 4.99943581, 3, 1.00056419, 1, np.nan])
  373. assert_array_almost_equal(vals, expected)
  374. def test_gh_2477_small_values(self):
  375. # Check a case that worked in the original issue.
  376. low, high = -11, -10
  377. x = stats.truncnorm.rvs(low, high, 0, 1, size=10)
  378. assert_(low < x.min() < x.max() < high)
  379. # Check a case that failed in the original issue.
  380. low, high = 10, 11
  381. x = stats.truncnorm.rvs(low, high, 0, 1, size=10)
  382. assert_(low < x.min() < x.max() < high)
  383. @pytest.mark.xfail(reason="truncnorm rvs is know to fail at extreme tails")
  384. def test_gh_2477_large_values(self):
  385. # Check a case that fails because of extreme tailness.
  386. low, high = 100, 101
  387. with np.errstate(divide='ignore'):
  388. x = stats.truncnorm.rvs(low, high, 0, 1, size=10)
  389. assert_(low < x.min() < x.max() < high)
  390. def test_gh_1489_trac_962_rvs(self):
  391. # Check the original example.
  392. low, high = 10, 15
  393. x = stats.truncnorm.rvs(low, high, 0, 1, size=10)
  394. assert_(low < x.min() < x.max() < high)
  395. class TestHypergeom(object):
  396. def setup_method(self):
  397. np.random.seed(1234)
  398. def test_rvs(self):
  399. vals = stats.hypergeom.rvs(20, 10, 3, size=(2, 50))
  400. assert_(numpy.all(vals >= 0) &
  401. numpy.all(vals <= 3))
  402. assert_(numpy.shape(vals) == (2, 50))
  403. assert_(vals.dtype.char in typecodes['AllInteger'])
  404. val = stats.hypergeom.rvs(20, 3, 10)
  405. assert_(isinstance(val, int))
  406. val = stats.hypergeom(20, 3, 10).rvs(3)
  407. assert_(isinstance(val, numpy.ndarray))
  408. assert_(val.dtype.char in typecodes['AllInteger'])
  409. def test_precision(self):
  410. # comparison number from mpmath
  411. M = 2500
  412. n = 50
  413. N = 500
  414. tot = M
  415. good = n
  416. hgpmf = stats.hypergeom.pmf(2, tot, good, N)
  417. assert_almost_equal(hgpmf, 0.0010114963068932233, 11)
  418. def test_args(self):
  419. # test correct output for corner cases of arguments
  420. # see gh-2325
  421. assert_almost_equal(stats.hypergeom.pmf(0, 2, 1, 0), 1.0, 11)
  422. assert_almost_equal(stats.hypergeom.pmf(1, 2, 1, 0), 0.0, 11)
  423. assert_almost_equal(stats.hypergeom.pmf(0, 2, 0, 2), 1.0, 11)
  424. assert_almost_equal(stats.hypergeom.pmf(1, 2, 1, 0), 0.0, 11)
  425. def test_cdf_above_one(self):
  426. # for some values of parameters, hypergeom cdf was >1, see gh-2238
  427. assert_(0 <= stats.hypergeom.cdf(30, 13397950, 4363, 12390) <= 1.0)
  428. def test_precision2(self):
  429. # Test hypergeom precision for large numbers. See #1218.
  430. # Results compared with those from R.
  431. oranges = 9.9e4
  432. pears = 1.1e5
  433. fruits_eaten = np.array([3, 3.8, 3.9, 4, 4.1, 4.2, 5]) * 1e4
  434. quantile = 2e4
  435. res = []
  436. for eaten in fruits_eaten:
  437. res.append(stats.hypergeom.sf(quantile, oranges + pears, oranges,
  438. eaten))
  439. expected = np.array([0, 1.904153e-114, 2.752693e-66, 4.931217e-32,
  440. 8.265601e-11, 0.1237904, 1])
  441. assert_allclose(res, expected, atol=0, rtol=5e-7)
  442. # Test with array_like first argument
  443. quantiles = [1.9e4, 2e4, 2.1e4, 2.15e4]
  444. res2 = stats.hypergeom.sf(quantiles, oranges + pears, oranges, 4.2e4)
  445. expected2 = [1, 0.1237904, 6.511452e-34, 3.277667e-69]
  446. assert_allclose(res2, expected2, atol=0, rtol=5e-7)
  447. def test_entropy(self):
  448. # Simple tests of entropy.
  449. hg = stats.hypergeom(4, 1, 1)
  450. h = hg.entropy()
  451. expected_p = np.array([0.75, 0.25])
  452. expected_h = -np.sum(xlogy(expected_p, expected_p))
  453. assert_allclose(h, expected_h)
  454. hg = stats.hypergeom(1, 1, 1)
  455. h = hg.entropy()
  456. assert_equal(h, 0.0)
  457. def test_logsf(self):
  458. # Test logsf for very large numbers. See issue #4982
  459. # Results compare with those from R (v3.2.0):
  460. # phyper(k, n, M-n, N, lower.tail=FALSE, log.p=TRUE)
  461. # -2239.771
  462. k = 1e4
  463. M = 1e7
  464. n = 1e6
  465. N = 5e4
  466. result = stats.hypergeom.logsf(k, M, n, N)
  467. exspected = -2239.771 # From R
  468. assert_almost_equal(result, exspected, decimal=3)
  469. class TestLoggamma(object):
  470. def test_stats(self):
  471. # The following precomputed values are from the table in section 2.2
  472. # of "A Statistical Study of Log-Gamma Distribution", by Ping Shing
  473. # Chan (thesis, McMaster University, 1993).
  474. table = np.array([
  475. # c, mean, var, skew, exc. kurt.
  476. 0.5, -1.9635, 4.9348, -1.5351, 4.0000,
  477. 1.0, -0.5772, 1.6449, -1.1395, 2.4000,
  478. 12.0, 2.4427, 0.0869, -0.2946, 0.1735,
  479. ]).reshape(-1, 5)
  480. for c, mean, var, skew, kurt in table:
  481. computed = stats.loggamma.stats(c, moments='msvk')
  482. assert_array_almost_equal(computed, [mean, var, skew, kurt],
  483. decimal=4)
  484. class TestLogistic(object):
  485. # gh-6226
  486. def test_cdf_ppf(self):
  487. x = np.linspace(-20, 20)
  488. y = stats.logistic.cdf(x)
  489. xx = stats.logistic.ppf(y)
  490. assert_allclose(x, xx)
  491. def test_sf_isf(self):
  492. x = np.linspace(-20, 20)
  493. y = stats.logistic.sf(x)
  494. xx = stats.logistic.isf(y)
  495. assert_allclose(x, xx)
  496. def test_extreme_values(self):
  497. # p is chosen so that 1 - (1 - p) == p in double precision
  498. p = 9.992007221626409e-16
  499. desired = 34.53957599234088
  500. assert_allclose(stats.logistic.ppf(1 - p), desired)
  501. assert_allclose(stats.logistic.isf(p), desired)
  502. class TestLogser(object):
  503. def setup_method(self):
  504. np.random.seed(1234)
  505. def test_rvs(self):
  506. vals = stats.logser.rvs(0.75, size=(2, 50))
  507. assert_(numpy.all(vals >= 1))
  508. assert_(numpy.shape(vals) == (2, 50))
  509. assert_(vals.dtype.char in typecodes['AllInteger'])
  510. val = stats.logser.rvs(0.75)
  511. assert_(isinstance(val, int))
  512. val = stats.logser(0.75).rvs(3)
  513. assert_(isinstance(val, numpy.ndarray))
  514. assert_(val.dtype.char in typecodes['AllInteger'])
  515. def test_pmf_small_p(self):
  516. m = stats.logser.pmf(4, 1e-20)
  517. # The expected value was computed using mpmath:
  518. # >>> import mpmath
  519. # >>> mpmath.mp.dps = 64
  520. # >>> k = 4
  521. # >>> p = mpmath.mpf('1e-20')
  522. # >>> float(-(p**k)/k/mpmath.log(1-p))
  523. # 2.5e-61
  524. # It is also clear from noticing that for very small p,
  525. # log(1-p) is approximately -p, and the formula becomes
  526. # p**(k-1) / k
  527. assert_allclose(m, 2.5e-61)
  528. def test_mean_small_p(self):
  529. m = stats.logser.mean(1e-8)
  530. # The expected mean was computed using mpmath:
  531. # >>> import mpmath
  532. # >>> mpmath.dps = 60
  533. # >>> p = mpmath.mpf('1e-8')
  534. # >>> float(-p / ((1 - p)*mpmath.log(1 - p)))
  535. # 1.000000005
  536. assert_allclose(m, 1.000000005)
  537. class TestPareto(object):
  538. def test_stats(self):
  539. # Check the stats() method with some simple values. Also check
  540. # that the calculations do not trigger RuntimeWarnings.
  541. with warnings.catch_warnings():
  542. warnings.simplefilter("error", RuntimeWarning)
  543. m, v, s, k = stats.pareto.stats(0.5, moments='mvsk')
  544. assert_equal(m, np.inf)
  545. assert_equal(v, np.inf)
  546. assert_equal(s, np.nan)
  547. assert_equal(k, np.nan)
  548. m, v, s, k = stats.pareto.stats(1.0, moments='mvsk')
  549. assert_equal(m, np.inf)
  550. assert_equal(v, np.inf)
  551. assert_equal(s, np.nan)
  552. assert_equal(k, np.nan)
  553. m, v, s, k = stats.pareto.stats(1.5, moments='mvsk')
  554. assert_equal(m, 3.0)
  555. assert_equal(v, np.inf)
  556. assert_equal(s, np.nan)
  557. assert_equal(k, np.nan)
  558. m, v, s, k = stats.pareto.stats(2.0, moments='mvsk')
  559. assert_equal(m, 2.0)
  560. assert_equal(v, np.inf)
  561. assert_equal(s, np.nan)
  562. assert_equal(k, np.nan)
  563. m, v, s, k = stats.pareto.stats(2.5, moments='mvsk')
  564. assert_allclose(m, 2.5 / 1.5)
  565. assert_allclose(v, 2.5 / (1.5*1.5*0.5))
  566. assert_equal(s, np.nan)
  567. assert_equal(k, np.nan)
  568. m, v, s, k = stats.pareto.stats(3.0, moments='mvsk')
  569. assert_allclose(m, 1.5)
  570. assert_allclose(v, 0.75)
  571. assert_equal(s, np.nan)
  572. assert_equal(k, np.nan)
  573. m, v, s, k = stats.pareto.stats(3.5, moments='mvsk')
  574. assert_allclose(m, 3.5 / 2.5)
  575. assert_allclose(v, 3.5 / (2.5*2.5*1.5))
  576. assert_allclose(s, (2*4.5/0.5)*np.sqrt(1.5/3.5))
  577. assert_equal(k, np.nan)
  578. m, v, s, k = stats.pareto.stats(4.0, moments='mvsk')
  579. assert_allclose(m, 4.0 / 3.0)
  580. assert_allclose(v, 4.0 / 18.0)
  581. assert_allclose(s, 2*(1+4.0)/(4.0-3) * np.sqrt((4.0-2)/4.0))
  582. assert_equal(k, np.nan)
  583. m, v, s, k = stats.pareto.stats(4.5, moments='mvsk')
  584. assert_allclose(m, 4.5 / 3.5)
  585. assert_allclose(v, 4.5 / (3.5*3.5*2.5))
  586. assert_allclose(s, (2*5.5/1.5) * np.sqrt(2.5/4.5))
  587. assert_allclose(k, 6*(4.5**3 + 4.5**2 - 6*4.5 - 2)/(4.5*1.5*0.5))
  588. def test_sf(self):
  589. x = 1e9
  590. b = 2
  591. scale = 1.5
  592. p = stats.pareto.sf(x, b, loc=0, scale=scale)
  593. expected = (scale/x)**b # 2.25e-18
  594. assert_allclose(p, expected)
  595. class TestGenpareto(object):
  596. def test_ab(self):
  597. # c >= 0: a, b = [0, inf]
  598. for c in [1., 0.]:
  599. c = np.asarray(c)
  600. stats.genpareto._argcheck(c) # ugh
  601. assert_equal(stats.genpareto.a, 0.)
  602. assert_(np.isposinf(stats.genpareto.b))
  603. # c < 0: a=0, b=1/|c|
  604. c = np.asarray(-2.)
  605. stats.genpareto._argcheck(c)
  606. assert_allclose([stats.genpareto.a, stats.genpareto.b], [0., 0.5])
  607. def test_c0(self):
  608. # with c=0, genpareto reduces to the exponential distribution
  609. rv = stats.genpareto(c=0.)
  610. x = np.linspace(0, 10., 30)
  611. assert_allclose(rv.pdf(x), stats.expon.pdf(x))
  612. assert_allclose(rv.cdf(x), stats.expon.cdf(x))
  613. assert_allclose(rv.sf(x), stats.expon.sf(x))
  614. q = np.linspace(0., 1., 10)
  615. assert_allclose(rv.ppf(q), stats.expon.ppf(q))
  616. def test_cm1(self):
  617. # with c=-1, genpareto reduces to the uniform distr on [0, 1]
  618. rv = stats.genpareto(c=-1.)
  619. x = np.linspace(0, 10., 30)
  620. assert_allclose(rv.pdf(x), stats.uniform.pdf(x))
  621. assert_allclose(rv.cdf(x), stats.uniform.cdf(x))
  622. assert_allclose(rv.sf(x), stats.uniform.sf(x))
  623. q = np.linspace(0., 1., 10)
  624. assert_allclose(rv.ppf(q), stats.uniform.ppf(q))
  625. # logpdf(1., c=-1) should be zero
  626. assert_allclose(rv.logpdf(1), 0)
  627. def test_x_inf(self):
  628. # make sure x=inf is handled gracefully
  629. rv = stats.genpareto(c=0.1)
  630. assert_allclose([rv.pdf(np.inf), rv.cdf(np.inf)], [0., 1.])
  631. assert_(np.isneginf(rv.logpdf(np.inf)))
  632. rv = stats.genpareto(c=0.)
  633. assert_allclose([rv.pdf(np.inf), rv.cdf(np.inf)], [0., 1.])
  634. assert_(np.isneginf(rv.logpdf(np.inf)))
  635. rv = stats.genpareto(c=-1.)
  636. assert_allclose([rv.pdf(np.inf), rv.cdf(np.inf)], [0., 1.])
  637. assert_(np.isneginf(rv.logpdf(np.inf)))
  638. def test_c_continuity(self):
  639. # pdf is continuous at c=0, -1
  640. x = np.linspace(0, 10, 30)
  641. for c in [0, -1]:
  642. pdf0 = stats.genpareto.pdf(x, c)
  643. for dc in [1e-14, -1e-14]:
  644. pdfc = stats.genpareto.pdf(x, c + dc)
  645. assert_allclose(pdf0, pdfc, atol=1e-12)
  646. cdf0 = stats.genpareto.cdf(x, c)
  647. for dc in [1e-14, 1e-14]:
  648. cdfc = stats.genpareto.cdf(x, c + dc)
  649. assert_allclose(cdf0, cdfc, atol=1e-12)
  650. def test_c_continuity_ppf(self):
  651. q = np.r_[np.logspace(1e-12, 0.01, base=0.1),
  652. np.linspace(0.01, 1, 30, endpoint=False),
  653. 1. - np.logspace(1e-12, 0.01, base=0.1)]
  654. for c in [0., -1.]:
  655. ppf0 = stats.genpareto.ppf(q, c)
  656. for dc in [1e-14, -1e-14]:
  657. ppfc = stats.genpareto.ppf(q, c + dc)
  658. assert_allclose(ppf0, ppfc, atol=1e-12)
  659. def test_c_continuity_isf(self):
  660. q = np.r_[np.logspace(1e-12, 0.01, base=0.1),
  661. np.linspace(0.01, 1, 30, endpoint=False),
  662. 1. - np.logspace(1e-12, 0.01, base=0.1)]
  663. for c in [0., -1.]:
  664. isf0 = stats.genpareto.isf(q, c)
  665. for dc in [1e-14, -1e-14]:
  666. isfc = stats.genpareto.isf(q, c + dc)
  667. assert_allclose(isf0, isfc, atol=1e-12)
  668. def test_cdf_ppf_roundtrip(self):
  669. # this should pass with machine precision. hat tip @pbrod
  670. q = np.r_[np.logspace(1e-12, 0.01, base=0.1),
  671. np.linspace(0.01, 1, 30, endpoint=False),
  672. 1. - np.logspace(1e-12, 0.01, base=0.1)]
  673. for c in [1e-8, -1e-18, 1e-15, -1e-15]:
  674. assert_allclose(stats.genpareto.cdf(stats.genpareto.ppf(q, c), c),
  675. q, atol=1e-15)
  676. def test_logsf(self):
  677. logp = stats.genpareto.logsf(1e10, .01, 0, 1)
  678. assert_allclose(logp, -1842.0680753952365)
  679. class TestPearson3(object):
  680. def setup_method(self):
  681. np.random.seed(1234)
  682. def test_rvs(self):
  683. vals = stats.pearson3.rvs(0.1, size=(2, 50))
  684. assert_(numpy.shape(vals) == (2, 50))
  685. assert_(vals.dtype.char in typecodes['AllFloat'])
  686. val = stats.pearson3.rvs(0.5)
  687. assert_(isinstance(val, float))
  688. val = stats.pearson3(0.5).rvs(3)
  689. assert_(isinstance(val, numpy.ndarray))
  690. assert_(val.dtype.char in typecodes['AllFloat'])
  691. assert_(len(val) == 3)
  692. def test_pdf(self):
  693. vals = stats.pearson3.pdf(2, [0.0, 0.1, 0.2])
  694. assert_allclose(vals, np.array([0.05399097, 0.05555481, 0.05670246]),
  695. atol=1e-6)
  696. vals = stats.pearson3.pdf(-3, 0.1)
  697. assert_allclose(vals, np.array([0.00313791]), atol=1e-6)
  698. vals = stats.pearson3.pdf([-3, -2, -1, 0, 1], 0.1)
  699. assert_allclose(vals, np.array([0.00313791, 0.05192304, 0.25028092,
  700. 0.39885918, 0.23413173]), atol=1e-6)
  701. def test_cdf(self):
  702. vals = stats.pearson3.cdf(2, [0.0, 0.1, 0.2])
  703. assert_allclose(vals, np.array([0.97724987, 0.97462004, 0.97213626]),
  704. atol=1e-6)
  705. vals = stats.pearson3.cdf(-3, 0.1)
  706. assert_allclose(vals, [0.00082256], atol=1e-6)
  707. vals = stats.pearson3.cdf([-3, -2, -1, 0, 1], 0.1)
  708. assert_allclose(vals, [8.22563821e-04, 1.99860448e-02, 1.58550710e-01,
  709. 5.06649130e-01, 8.41442111e-01], atol=1e-6)
  710. class TestKappa4(object):
  711. def test_cdf_genpareto(self):
  712. # h = 1 and k != 0 is generalized Pareto
  713. x = [0.0, 0.1, 0.2, 0.5]
  714. h = 1.0
  715. for k in [-1.9, -1.0, -0.5, -0.2, -0.1, 0.1, 0.2, 0.5, 1.0,
  716. 1.9]:
  717. vals = stats.kappa4.cdf(x, h, k)
  718. # shape parameter is opposite what is expected
  719. vals_comp = stats.genpareto.cdf(x, -k)
  720. assert_allclose(vals, vals_comp)
  721. def test_cdf_genextreme(self):
  722. # h = 0 and k != 0 is generalized extreme value
  723. x = np.linspace(-5, 5, 10)
  724. h = 0.0
  725. k = np.linspace(-3, 3, 10)
  726. vals = stats.kappa4.cdf(x, h, k)
  727. vals_comp = stats.genextreme.cdf(x, k)
  728. assert_allclose(vals, vals_comp)
  729. def test_cdf_expon(self):
  730. # h = 1 and k = 0 is exponential
  731. x = np.linspace(0, 10, 10)
  732. h = 1.0
  733. k = 0.0
  734. vals = stats.kappa4.cdf(x, h, k)
  735. vals_comp = stats.expon.cdf(x)
  736. assert_allclose(vals, vals_comp)
  737. def test_cdf_gumbel_r(self):
  738. # h = 0 and k = 0 is gumbel_r
  739. x = np.linspace(-5, 5, 10)
  740. h = 0.0
  741. k = 0.0
  742. vals = stats.kappa4.cdf(x, h, k)
  743. vals_comp = stats.gumbel_r.cdf(x)
  744. assert_allclose(vals, vals_comp)
  745. def test_cdf_logistic(self):
  746. # h = -1 and k = 0 is logistic
  747. x = np.linspace(-5, 5, 10)
  748. h = -1.0
  749. k = 0.0
  750. vals = stats.kappa4.cdf(x, h, k)
  751. vals_comp = stats.logistic.cdf(x)
  752. assert_allclose(vals, vals_comp)
  753. def test_cdf_uniform(self):
  754. # h = 1 and k = 1 is uniform
  755. x = np.linspace(-5, 5, 10)
  756. h = 1.0
  757. k = 1.0
  758. vals = stats.kappa4.cdf(x, h, k)
  759. vals_comp = stats.uniform.cdf(x)
  760. assert_allclose(vals, vals_comp)
  761. def test_integers_ctor(self):
  762. # regression test for gh-7416: _argcheck fails for integer h and k
  763. # in numpy 1.12
  764. stats.kappa4(1, 2)
  765. class TestPoisson(object):
  766. def setup_method(self):
  767. np.random.seed(1234)
  768. def test_pmf_basic(self):
  769. # Basic case
  770. ln2 = np.log(2)
  771. vals = stats.poisson.pmf([0, 1, 2], ln2)
  772. expected = [0.5, ln2/2, ln2**2/4]
  773. assert_allclose(vals, expected)
  774. def test_mu0(self):
  775. # Edge case: mu=0
  776. vals = stats.poisson.pmf([0, 1, 2], 0)
  777. expected = [1, 0, 0]
  778. assert_array_equal(vals, expected)
  779. interval = stats.poisson.interval(0.95, 0)
  780. assert_equal(interval, (0, 0))
  781. def test_rvs(self):
  782. vals = stats.poisson.rvs(0.5, size=(2, 50))
  783. assert_(numpy.all(vals >= 0))
  784. assert_(numpy.shape(vals) == (2, 50))
  785. assert_(vals.dtype.char in typecodes['AllInteger'])
  786. val = stats.poisson.rvs(0.5)
  787. assert_(isinstance(val, int))
  788. val = stats.poisson(0.5).rvs(3)
  789. assert_(isinstance(val, numpy.ndarray))
  790. assert_(val.dtype.char in typecodes['AllInteger'])
  791. def test_stats(self):
  792. mu = 16.0
  793. result = stats.poisson.stats(mu, moments='mvsk')
  794. assert_allclose(result, [mu, mu, np.sqrt(1.0/mu), 1.0/mu])
  795. mu = np.array([0.0, 1.0, 2.0])
  796. result = stats.poisson.stats(mu, moments='mvsk')
  797. expected = (mu, mu, [np.inf, 1, 1/np.sqrt(2)], [np.inf, 1, 0.5])
  798. assert_allclose(result, expected)
  799. class TestZipf(object):
  800. def setup_method(self):
  801. np.random.seed(1234)
  802. def test_rvs(self):
  803. vals = stats.zipf.rvs(1.5, size=(2, 50))
  804. assert_(numpy.all(vals >= 1))
  805. assert_(numpy.shape(vals) == (2, 50))
  806. assert_(vals.dtype.char in typecodes['AllInteger'])
  807. val = stats.zipf.rvs(1.5)
  808. assert_(isinstance(val, int))
  809. val = stats.zipf(1.5).rvs(3)
  810. assert_(isinstance(val, numpy.ndarray))
  811. assert_(val.dtype.char in typecodes['AllInteger'])
  812. def test_moments(self):
  813. # n-th moment is finite iff a > n + 1
  814. m, v = stats.zipf.stats(a=2.8)
  815. assert_(np.isfinite(m))
  816. assert_equal(v, np.inf)
  817. s, k = stats.zipf.stats(a=4.8, moments='sk')
  818. assert_(not np.isfinite([s, k]).all())
  819. class TestDLaplace(object):
  820. def setup_method(self):
  821. np.random.seed(1234)
  822. def test_rvs(self):
  823. vals = stats.dlaplace.rvs(1.5, size=(2, 50))
  824. assert_(numpy.shape(vals) == (2, 50))
  825. assert_(vals.dtype.char in typecodes['AllInteger'])
  826. val = stats.dlaplace.rvs(1.5)
  827. assert_(isinstance(val, int))
  828. val = stats.dlaplace(1.5).rvs(3)
  829. assert_(isinstance(val, numpy.ndarray))
  830. assert_(val.dtype.char in typecodes['AllInteger'])
  831. assert_(stats.dlaplace.rvs(0.8) is not None)
  832. def test_stats(self):
  833. # compare the explicit formulas w/ direct summation using pmf
  834. a = 1.
  835. dl = stats.dlaplace(a)
  836. m, v, s, k = dl.stats('mvsk')
  837. N = 37
  838. xx = np.arange(-N, N+1)
  839. pp = dl.pmf(xx)
  840. m2, m4 = np.sum(pp*xx**2), np.sum(pp*xx**4)
  841. assert_equal((m, s), (0, 0))
  842. assert_allclose((v, k), (m2, m4/m2**2 - 3.), atol=1e-14, rtol=1e-8)
  843. def test_stats2(self):
  844. a = np.log(2.)
  845. dl = stats.dlaplace(a)
  846. m, v, s, k = dl.stats('mvsk')
  847. assert_equal((m, s), (0., 0.))
  848. assert_allclose((v, k), (4., 3.25))
  849. class TestInvGamma(object):
  850. def test_invgamma_inf_gh_1866(self):
  851. # invgamma's moments are only finite for a>n
  852. # specific numbers checked w/ boost 1.54
  853. with warnings.catch_warnings():
  854. warnings.simplefilter('error', RuntimeWarning)
  855. mvsk = stats.invgamma.stats(a=19.31, moments='mvsk')
  856. expected = [0.05461496450, 0.0001723162534, 1.020362676,
  857. 2.055616582]
  858. assert_allclose(mvsk, expected)
  859. a = [1.1, 3.1, 5.6]
  860. mvsk = stats.invgamma.stats(a=a, moments='mvsk')
  861. expected = ([10., 0.476190476, 0.2173913043], # mmm
  862. [np.inf, 0.2061430632, 0.01312749422], # vvv
  863. [np.nan, 41.95235392, 2.919025532], # sss
  864. [np.nan, np.nan, 24.51923076]) # kkk
  865. for x, y in zip(mvsk, expected):
  866. assert_almost_equal(x, y)
  867. def test_cdf_ppf(self):
  868. # gh-6245
  869. x = np.logspace(-2.6, 0)
  870. y = stats.invgamma.cdf(x, 1)
  871. xx = stats.invgamma.ppf(y, 1)
  872. assert_allclose(x, xx)
  873. def test_sf_isf(self):
  874. # gh-6245
  875. if sys.maxsize > 2**32:
  876. x = np.logspace(2, 100)
  877. else:
  878. # Invgamme roundtrip on 32-bit systems has relative accuracy
  879. # ~1e-15 until x=1e+15, and becomes inf above x=1e+18
  880. x = np.logspace(2, 18)
  881. y = stats.invgamma.sf(x, 1)
  882. xx = stats.invgamma.isf(y, 1)
  883. assert_allclose(x, xx, rtol=1.0)
  884. class TestF(object):
  885. def test_f_moments(self):
  886. # n-th moment of F distributions is only finite for n < dfd / 2
  887. m, v, s, k = stats.f.stats(11, 6.5, moments='mvsk')
  888. assert_(np.isfinite(m))
  889. assert_(np.isfinite(v))
  890. assert_(np.isfinite(s))
  891. assert_(not np.isfinite(k))
  892. def test_moments_warnings(self):
  893. # no warnings should be generated for dfd = 2, 4, 6, 8 (div by zero)
  894. with warnings.catch_warnings():
  895. warnings.simplefilter('error', RuntimeWarning)
  896. stats.f.stats(dfn=[11]*4, dfd=[2, 4, 6, 8], moments='mvsk')
  897. @pytest.mark.xfail(reason='f stats does not properly broadcast')
  898. def test_stats_broadcast(self):
  899. # stats do not fully broadcast just yet
  900. mv = stats.f.stats(dfn=11, dfd=[11, 12])
  901. def test_rvgeneric_std():
  902. # Regression test for #1191
  903. assert_array_almost_equal(stats.t.std([5, 6]), [1.29099445, 1.22474487])
  904. def test_moments_t():
  905. # regression test for #8786
  906. assert_equal(stats.t.stats(df=1, moments='mvsk'),
  907. (np.inf, np.nan, np.nan, np.nan))
  908. assert_equal(stats.t.stats(df=1.01, moments='mvsk'),
  909. (0.0, np.inf, np.nan, np.nan))
  910. assert_equal(stats.t.stats(df=2, moments='mvsk'),
  911. (0.0, np.inf, np.nan, np.nan))
  912. assert_equal(stats.t.stats(df=2.01, moments='mvsk'),
  913. (0.0, 2.01/(2.01-2.0), np.nan, np.inf))
  914. assert_equal(stats.t.stats(df=3, moments='sk'), (np.nan, np.inf))
  915. assert_equal(stats.t.stats(df=3.01, moments='sk'), (0.0, np.inf))
  916. assert_equal(stats.t.stats(df=4, moments='sk'), (0.0, np.inf))
  917. assert_equal(stats.t.stats(df=4.01, moments='sk'), (0.0, 6.0/(4.01 - 4.0)))
  918. class TestRvDiscrete(object):
  919. def setup_method(self):
  920. np.random.seed(1234)
  921. def test_rvs(self):
  922. states = [-1, 0, 1, 2, 3, 4]
  923. probability = [0.0, 0.3, 0.4, 0.0, 0.3, 0.0]
  924. samples = 1000
  925. r = stats.rv_discrete(name='sample', values=(states, probability))
  926. x = r.rvs(size=samples)
  927. assert_(isinstance(x, numpy.ndarray))
  928. for s, p in zip(states, probability):
  929. assert_(abs(sum(x == s)/float(samples) - p) < 0.05)
  930. x = r.rvs()
  931. assert_(isinstance(x, int))
  932. def test_entropy(self):
  933. # Basic tests of entropy.
  934. pvals = np.array([0.25, 0.45, 0.3])
  935. p = stats.rv_discrete(values=([0, 1, 2], pvals))
  936. expected_h = -sum(xlogy(pvals, pvals))
  937. h = p.entropy()
  938. assert_allclose(h, expected_h)
  939. p = stats.rv_discrete(values=([0, 1, 2], [1.0, 0, 0]))
  940. h = p.entropy()
  941. assert_equal(h, 0.0)
  942. def test_pmf(self):
  943. xk = [1, 2, 4]
  944. pk = [0.5, 0.3, 0.2]
  945. rv = stats.rv_discrete(values=(xk, pk))
  946. x = [[1., 4.],
  947. [3., 2]]
  948. assert_allclose(rv.pmf(x),
  949. [[0.5, 0.2],
  950. [0., 0.3]], atol=1e-14)
  951. def test_cdf(self):
  952. xk = [1, 2, 4]
  953. pk = [0.5, 0.3, 0.2]
  954. rv = stats.rv_discrete(values=(xk, pk))
  955. x_values = [-2, 1., 1.1, 1.5, 2.0, 3.0, 4, 5]
  956. expected = [0, 0.5, 0.5, 0.5, 0.8, 0.8, 1, 1]
  957. assert_allclose(rv.cdf(x_values), expected, atol=1e-14)
  958. # also check scalar arguments
  959. assert_allclose([rv.cdf(xx) for xx in x_values],
  960. expected, atol=1e-14)
  961. def test_ppf(self):
  962. xk = [1, 2, 4]
  963. pk = [0.5, 0.3, 0.2]
  964. rv = stats.rv_discrete(values=(xk, pk))
  965. q_values = [0.1, 0.5, 0.6, 0.8, 0.9, 1.]
  966. expected = [1, 1, 2, 2, 4, 4]
  967. assert_allclose(rv.ppf(q_values), expected, atol=1e-14)
  968. # also check scalar arguments
  969. assert_allclose([rv.ppf(q) for q in q_values],
  970. expected, atol=1e-14)
  971. def test_cdf_ppf_next(self):
  972. # copied and special cased from test_discrete_basic
  973. vals = ([1, 2, 4, 7, 8], [0.1, 0.2, 0.3, 0.3, 0.1])
  974. rv = stats.rv_discrete(values=vals)
  975. assert_array_equal(rv.ppf(rv.cdf(rv.xk[:-1]) + 1e-8),
  976. rv.xk[1:])
  977. def test_expect(self):
  978. xk = [1, 2, 4, 6, 7, 11]
  979. pk = [0.1, 0.2, 0.2, 0.2, 0.2, 0.1]
  980. rv = stats.rv_discrete(values=(xk, pk))
  981. assert_allclose(rv.expect(), np.sum(rv.xk * rv.pk), atol=1e-14)
  982. def test_bad_input(self):
  983. xk = [1, 2, 3]
  984. pk = [0.5, 0.5]
  985. assert_raises(ValueError, stats.rv_discrete, **dict(values=(xk, pk)))
  986. pk = [1, 2, 3]
  987. assert_raises(ValueError, stats.rv_discrete, **dict(values=(xk, pk)))
  988. class TestSkewNorm(object):
  989. def setup_method(self):
  990. np.random.seed(1234)
  991. def test_normal(self):
  992. # When the skewness is 0 the distribution is normal
  993. x = np.linspace(-5, 5, 100)
  994. assert_array_almost_equal(stats.skewnorm.pdf(x, a=0),
  995. stats.norm.pdf(x))
  996. def test_rvs(self):
  997. shape = (3, 4, 5)
  998. x = stats.skewnorm.rvs(a=0.75, size=shape)
  999. assert_equal(shape, x.shape)
  1000. x = stats.skewnorm.rvs(a=-3, size=shape)
  1001. assert_equal(shape, x.shape)
  1002. def test_moments(self):
  1003. X = stats.skewnorm.rvs(a=4, size=int(1e6), loc=5, scale=2)
  1004. expected = [np.mean(X), np.var(X), stats.skew(X), stats.kurtosis(X)]
  1005. computed = stats.skewnorm.stats(a=4, loc=5, scale=2, moments='mvsk')
  1006. assert_array_almost_equal(computed, expected, decimal=2)
  1007. X = stats.skewnorm.rvs(a=-4, size=int(1e6), loc=5, scale=2)
  1008. expected = [np.mean(X), np.var(X), stats.skew(X), stats.kurtosis(X)]
  1009. computed = stats.skewnorm.stats(a=-4, loc=5, scale=2, moments='mvsk')
  1010. assert_array_almost_equal(computed, expected, decimal=2)
  1011. def test_cdf_large_x(self):
  1012. # Regression test for gh-7746.
  1013. # The x values are large enough that the closest 64 bit floating
  1014. # point representation of the exact CDF is 1.0.
  1015. p = stats.skewnorm.cdf([10, 20, 30], -1)
  1016. assert_allclose(p, np.ones(3), rtol=1e-14)
  1017. p = stats.skewnorm.cdf(25, 2.5)
  1018. assert_allclose(p, 1.0, rtol=1e-14)
  1019. def test_cdf_sf_small_values(self):
  1020. # Triples are [x, a, cdf(x, a)]. These values were computed
  1021. # using CDF[SkewNormDistribution[0, 1, a], x] in Wolfram Alpha.
  1022. cdfvals = [
  1023. [-8, 1, 3.870035046664392611e-31],
  1024. [-4, 2, 8.1298399188811398e-21],
  1025. [-2, 5, 1.55326826787106273e-26],
  1026. [-9, -1, 2.257176811907681295e-19],
  1027. [-10, -4, 1.523970604832105213e-23],
  1028. ]
  1029. for x, a, cdfval in cdfvals:
  1030. p = stats.skewnorm.cdf(x, a)
  1031. assert_allclose(p, cdfval, rtol=1e-8)
  1032. # For the skew normal distribution, sf(-x, -a) = cdf(x, a).
  1033. p = stats.skewnorm.sf(-x, -a)
  1034. assert_allclose(p, cdfval, rtol=1e-8)
  1035. class TestExpon(object):
  1036. def test_zero(self):
  1037. assert_equal(stats.expon.pdf(0), 1)
  1038. def test_tail(self): # Regression test for ticket 807
  1039. assert_equal(stats.expon.cdf(1e-18), 1e-18)
  1040. assert_equal(stats.expon.isf(stats.expon.sf(40)), 40)
  1041. class TestExponNorm(object):
  1042. def test_moments(self):
  1043. # Some moment test cases based on non-loc/scaled formula
  1044. def get_moms(lam, sig, mu):
  1045. # See wikipedia for these formulae
  1046. # where it is listed as an exponentially modified gaussian
  1047. opK2 = 1.0 + 1 / (lam*sig)**2
  1048. exp_skew = 2 / (lam * sig)**3 * opK2**(-1.5)
  1049. exp_kurt = 6.0 * (1 + (lam * sig)**2)**(-2)
  1050. return [mu + 1/lam, sig*sig + 1.0/(lam*lam), exp_skew, exp_kurt]
  1051. mu, sig, lam = 0, 1, 1
  1052. K = 1.0 / (lam * sig)
  1053. sts = stats.exponnorm.stats(K, loc=mu, scale=sig, moments='mvsk')
  1054. assert_almost_equal(sts, get_moms(lam, sig, mu))
  1055. mu, sig, lam = -3, 2, 0.1
  1056. K = 1.0 / (lam * sig)
  1057. sts = stats.exponnorm.stats(K, loc=mu, scale=sig, moments='mvsk')
  1058. assert_almost_equal(sts, get_moms(lam, sig, mu))
  1059. mu, sig, lam = 0, 3, 1
  1060. K = 1.0 / (lam * sig)
  1061. sts = stats.exponnorm.stats(K, loc=mu, scale=sig, moments='mvsk')
  1062. assert_almost_equal(sts, get_moms(lam, sig, mu))
  1063. mu, sig, lam = -5, 11, 3.5
  1064. K = 1.0 / (lam * sig)
  1065. sts = stats.exponnorm.stats(K, loc=mu, scale=sig, moments='mvsk')
  1066. assert_almost_equal(sts, get_moms(lam, sig, mu))
  1067. def test_extremes_x(self):
  1068. # Test for extreme values against overflows
  1069. assert_almost_equal(stats.exponnorm.pdf(-900, 1), 0.0)
  1070. assert_almost_equal(stats.exponnorm.pdf(+900, 1), 0.0)
  1071. class TestGenExpon(object):
  1072. def test_pdf_unity_area(self):
  1073. from scipy.integrate import simps
  1074. # PDF should integrate to one
  1075. p = stats.genexpon.pdf(numpy.arange(0, 10, 0.01), 0.5, 0.5, 2.0)
  1076. assert_almost_equal(simps(p, dx=0.01), 1, 1)
  1077. def test_cdf_bounds(self):
  1078. # CDF should always be positive
  1079. cdf = stats.genexpon.cdf(numpy.arange(0, 10, 0.01), 0.5, 0.5, 2.0)
  1080. assert_(numpy.all((0 <= cdf) & (cdf <= 1)))
  1081. class TestExponpow(object):
  1082. def test_tail(self):
  1083. assert_almost_equal(stats.exponpow.cdf(1e-10, 2.), 1e-20)
  1084. assert_almost_equal(stats.exponpow.isf(stats.exponpow.sf(5, .8), .8),
  1085. 5)
  1086. class TestSkellam(object):
  1087. def test_pmf(self):
  1088. # comparison to R
  1089. k = numpy.arange(-10, 15)
  1090. mu1, mu2 = 10, 5
  1091. skpmfR = numpy.array(
  1092. [4.2254582961926893e-005, 1.1404838449648488e-004,
  1093. 2.8979625801752660e-004, 6.9177078182101231e-004,
  1094. 1.5480716105844708e-003, 3.2412274963433889e-003,
  1095. 6.3373707175123292e-003, 1.1552351566696643e-002,
  1096. 1.9606152375042644e-002, 3.0947164083410337e-002,
  1097. 4.5401737566767360e-002, 6.1894328166820688e-002,
  1098. 7.8424609500170578e-002, 9.2418812533573133e-002,
  1099. 1.0139793148019728e-001, 1.0371927988298846e-001,
  1100. 9.9076583077406091e-002, 8.8546660073089561e-002,
  1101. 7.4187842052486810e-002, 5.8392772862200251e-002,
  1102. 4.3268692953013159e-002, 3.0248159818374226e-002,
  1103. 1.9991434305603021e-002, 1.2516877303301180e-002,
  1104. 7.4389876226229707e-003])
  1105. assert_almost_equal(stats.skellam.pmf(k, mu1, mu2), skpmfR, decimal=15)
  1106. def test_cdf(self):
  1107. # comparison to R, only 5 decimals
  1108. k = numpy.arange(-10, 15)
  1109. mu1, mu2 = 10, 5
  1110. skcdfR = numpy.array(
  1111. [6.4061475386192104e-005, 1.7810985988267694e-004,
  1112. 4.6790611790020336e-004, 1.1596768997212152e-003,
  1113. 2.7077485103056847e-003, 5.9489760066490718e-003,
  1114. 1.2286346724161398e-002, 2.3838698290858034e-002,
  1115. 4.3444850665900668e-002, 7.4392014749310995e-002,
  1116. 1.1979375231607835e-001, 1.8168808048289900e-001,
  1117. 2.6011268998306952e-001, 3.5253150251664261e-001,
  1118. 4.5392943399683988e-001, 5.5764871387982828e-001,
  1119. 6.5672529695723436e-001, 7.4527195703032389e-001,
  1120. 8.1945979908281064e-001, 8.7785257194501087e-001,
  1121. 9.2112126489802404e-001, 9.5136942471639818e-001,
  1122. 9.7136085902200120e-001, 9.8387773632530240e-001,
  1123. 9.9131672394792536e-001])
  1124. assert_almost_equal(stats.skellam.cdf(k, mu1, mu2), skcdfR, decimal=5)
  1125. class TestLognorm(object):
  1126. def test_pdf(self):
  1127. # Regression test for Ticket #1471: avoid nan with 0/0 situation
  1128. # Also make sure there are no warnings at x=0, cf gh-5202
  1129. with warnings.catch_warnings():
  1130. warnings.simplefilter('error', RuntimeWarning)
  1131. pdf = stats.lognorm.pdf([0, 0.5, 1], 1)
  1132. assert_array_almost_equal(pdf, [0.0, 0.62749608, 0.39894228])
  1133. def test_logcdf(self):
  1134. # Regression test for gh-5940: sf et al would underflow too early
  1135. x2, mu, sigma = 201.68, 195, 0.149
  1136. assert_allclose(stats.lognorm.sf(x2-mu, s=sigma),
  1137. stats.norm.sf(np.log(x2-mu)/sigma))
  1138. assert_allclose(stats.lognorm.logsf(x2-mu, s=sigma),
  1139. stats.norm.logsf(np.log(x2-mu)/sigma))
  1140. class TestBeta(object):
  1141. def test_logpdf(self):
  1142. # Regression test for Ticket #1326: avoid nan with 0*log(0) situation
  1143. logpdf = stats.beta.logpdf(0, 1, 0.5)
  1144. assert_almost_equal(logpdf, -0.69314718056)
  1145. logpdf = stats.beta.logpdf(0, 0.5, 1)
  1146. assert_almost_equal(logpdf, np.inf)
  1147. def test_logpdf_ticket_1866(self):
  1148. alpha, beta = 267, 1472
  1149. x = np.array([0.2, 0.5, 0.6])
  1150. b = stats.beta(alpha, beta)
  1151. assert_allclose(b.logpdf(x).sum(), -1201.699061824062)
  1152. assert_allclose(b.pdf(x), np.exp(b.logpdf(x)))
  1153. class TestBetaPrime(object):
  1154. def test_logpdf(self):
  1155. alpha, beta = 267, 1472
  1156. x = np.array([0.2, 0.5, 0.6])
  1157. b = stats.betaprime(alpha, beta)
  1158. assert_(np.isfinite(b.logpdf(x)).all())
  1159. assert_allclose(b.pdf(x), np.exp(b.logpdf(x)))
  1160. def test_cdf(self):
  1161. # regression test for gh-4030: Implementation of
  1162. # scipy.stats.betaprime.cdf()
  1163. x = stats.betaprime.cdf(0, 0.2, 0.3)
  1164. assert_equal(x, 0.0)
  1165. alpha, beta = 267, 1472
  1166. x = np.array([0.2, 0.5, 0.6])
  1167. cdfs = stats.betaprime.cdf(x, alpha, beta)
  1168. assert_(np.isfinite(cdfs).all())
  1169. # check the new cdf implementation vs generic one:
  1170. gen_cdf = stats.rv_continuous._cdf_single
  1171. cdfs_g = [gen_cdf(stats.betaprime, val, alpha, beta) for val in x]
  1172. assert_allclose(cdfs, cdfs_g, atol=0, rtol=2e-12)
  1173. class TestGamma(object):
  1174. def test_pdf(self):
  1175. # a few test cases to compare with R
  1176. pdf = stats.gamma.pdf(90, 394, scale=1./5)
  1177. assert_almost_equal(pdf, 0.002312341)
  1178. pdf = stats.gamma.pdf(3, 10, scale=1./5)
  1179. assert_almost_equal(pdf, 0.1620358)
  1180. def test_logpdf(self):
  1181. # Regression test for Ticket #1326: cornercase avoid nan with 0*log(0)
  1182. # situation
  1183. logpdf = stats.gamma.logpdf(0, 1)
  1184. assert_almost_equal(logpdf, 0)
  1185. class TestChi2(object):
  1186. # regression tests after precision improvements, ticket:1041, not verified
  1187. def test_precision(self):
  1188. assert_almost_equal(stats.chi2.pdf(1000, 1000), 8.919133934753128e-003,
  1189. decimal=14)
  1190. assert_almost_equal(stats.chi2.pdf(100, 100), 0.028162503162596778,
  1191. decimal=14)
  1192. class TestGumbelL(object):
  1193. # gh-6228
  1194. def test_cdf_ppf(self):
  1195. x = np.linspace(-100, -4)
  1196. y = stats.gumbel_l.cdf(x)
  1197. xx = stats.gumbel_l.ppf(y)
  1198. assert_allclose(x, xx)
  1199. def test_logcdf_logsf(self):
  1200. x = np.linspace(-100, -4)
  1201. y = stats.gumbel_l.logcdf(x)
  1202. z = stats.gumbel_l.logsf(x)
  1203. u = np.exp(y)
  1204. v = -special.expm1(z)
  1205. assert_allclose(u, v)
  1206. def test_sf_isf(self):
  1207. x = np.linspace(-20, 5)
  1208. y = stats.gumbel_l.sf(x)
  1209. xx = stats.gumbel_l.isf(y)
  1210. assert_allclose(x, xx)
  1211. class TestLevyStable(object):
  1212. def test_fit(self):
  1213. # construct data to have percentiles that match
  1214. # example in McCulloch 1986.
  1215. x = [-.05413,-.05413,
  1216. 0.,0.,0.,0.,
  1217. .00533,.00533,.00533,.00533,.00533,
  1218. .03354,.03354,.03354,.03354,.03354,
  1219. .05309,.05309,.05309,.05309,.05309]
  1220. alpha1, beta1, loc1, scale1 = stats.levy_stable._fitstart(x)
  1221. assert_allclose(alpha1, 1.48, rtol=0, atol=0.01)
  1222. assert_almost_equal(beta1, -.22, 2)
  1223. assert_almost_equal(scale1, 0.01717, 4)
  1224. assert_almost_equal(loc1, 0.00233, 2) # to 2 dps due to rounding error in McCulloch86
  1225. # cover alpha=2 scenario
  1226. x2 = x + [.05309,.05309,.05309,.05309,.05309]
  1227. alpha2, beta2, loc2, scale2 = stats.levy_stable._fitstart(x2)
  1228. assert_equal(alpha2, 2)
  1229. assert_equal(beta2, -1)
  1230. assert_almost_equal(scale2, .02503, 4)
  1231. assert_almost_equal(loc2, .03354, 4)
  1232. @pytest.mark.slow
  1233. def test_pdf_nolan_samples(self):
  1234. """ Test pdf values against Nolan's stablec.exe output
  1235. see - http://fs2.american.edu/jpnolan/www/stable/stable.html
  1236. There's a known limitation of Nolan's executable for alpha < 0.2.
  1237. Repeat following with beta = -1, -.5, 0, .5 and 1
  1238. stablec.exe <<
  1239. 1 # pdf
  1240. 1 # Nolan S equivalent to S0 in scipy
  1241. .25,2,.25 # alpha
  1242. -1,-1,0 # beta
  1243. -10,10,1 # x
  1244. 1,0 # gamma, delta
  1245. 2 # output file
  1246. """
  1247. data = np.load(os.path.abspath(os.path.join(os.path.dirname(__file__),
  1248. 'data/stable-pdf-sample-data.npy')))
  1249. data = np.core.records.fromarrays(data.T, names='x,p,alpha,beta')
  1250. # support numpy 1.8.2 for travis
  1251. npisin = np.isin if hasattr(np, "isin") else np.in1d
  1252. tests = [
  1253. # best selects
  1254. ['best', None, 8, None],
  1255. # quadrature is accurate for most alpha except 0.25; perhaps limitation of Nolan stablec?
  1256. # we reduce size of x to speed up computation as numerical integration slow.
  1257. ['quadrature', None, 8, lambda r: (r['alpha'] > 0.25) & (npisin(r['x'], [-10,-5,0,5,10]))],
  1258. # zolatarev is accurate except at alpha==1, beta != 0
  1259. ['zolotarev', None, 8, lambda r: r['alpha'] != 1],
  1260. ['zolotarev', None, 8, lambda r: (r['alpha'] == 1) & (r['beta'] == 0)],
  1261. ['zolotarev', None, 1, lambda r: (r['alpha'] == 1) & (r['beta'] != 0)],
  1262. # fft accuracy reduces as alpha decreases, fails at low values of alpha and x=0
  1263. ['fft', 0, 4, lambda r: r['alpha'] > 1],
  1264. ['fft', 0, 3, lambda r: (r['alpha'] < 1) & (r['alpha'] > 0.25)],
  1265. ['fft', 0, 1, lambda r: (r['alpha'] == 0.25) & (r['x'] != 0)], # not useful here
  1266. ]
  1267. for ix, (default_method, fft_min_points, decimal_places, filter_func) in enumerate(tests):
  1268. stats.levy_stable.pdf_default_method = default_method
  1269. stats.levy_stable.pdf_fft_min_points_threshold = fft_min_points
  1270. subdata = data[filter_func(data)] if filter_func is not None else data
  1271. with suppress_warnings() as sup:
  1272. sup.record(RuntimeWarning, "Density calculation unstable for alpha=1 and beta!=0.*")
  1273. sup.record(RuntimeWarning, "Density calculations experimental for FFT method.*")
  1274. p = stats.levy_stable.pdf(subdata['x'], subdata['alpha'], subdata['beta'], scale=1, loc=0)
  1275. subdata2 = rec_append_fields(subdata, 'calc', p)
  1276. failures = subdata2[(np.abs(p-subdata['p']) >= 1.5*10.**(-decimal_places)) | np.isnan(p)]
  1277. assert_almost_equal(p, subdata['p'], decimal_places, "pdf test %s failed with method '%s'\n%s" % (ix, default_method, failures), verbose=False)
  1278. @pytest.mark.slow
  1279. def test_cdf_nolan_samples(self):
  1280. """ Test cdf values against Nolan's stablec.exe output
  1281. see - http://fs2.american.edu/jpnolan/www/stable/stable.html
  1282. There's a known limitation of Nolan's executable for alpha < 0.2.
  1283. Repeat following with beta = -1, -.5, 0, .5 and 1
  1284. stablec.exe <<
  1285. 2 # cdf
  1286. 1 # Nolan S equivalent to S0 in scipy
  1287. .25,2,.25 # alpha
  1288. -1,-1,0 # beta
  1289. -10,10,1 # x
  1290. 1,0 # gamma, delta
  1291. 2 # output file
  1292. """
  1293. data = np.load(os.path.abspath(os.path.join(os.path.dirname(__file__),
  1294. 'data/stable-cdf-sample-data.npy')))
  1295. data = np.core.records.fromarrays(data.T, names='x,p,alpha,beta')
  1296. tests = [
  1297. # zolatarev is accurate for all values
  1298. ['zolotarev', None, 8, None],
  1299. # fft accuracy poor, very poor alpha < 1
  1300. ['fft', 0, 2, lambda r: r['alpha'] > 1],
  1301. ]
  1302. for ix, (default_method, fft_min_points, decimal_places, filter_func) in enumerate(tests):
  1303. stats.levy_stable.pdf_default_method = default_method
  1304. stats.levy_stable.pdf_fft_min_points_threshold = fft_min_points
  1305. subdata = data[filter_func(data)] if filter_func is not None else data
  1306. with suppress_warnings() as sup:
  1307. sup.record(RuntimeWarning, 'FFT method is considered ' +
  1308. 'experimental for cumulative distribution ' +
  1309. 'function evaluations.*')
  1310. p = stats.levy_stable.cdf(subdata['x'], subdata['alpha'], subdata['beta'], scale=1, loc=0)
  1311. subdata2 = rec_append_fields(subdata, 'calc', p)
  1312. failures = subdata2[(np.abs(p-subdata['p']) >= 1.5*10.**(-decimal_places)) | np.isnan(p)]
  1313. assert_almost_equal(p, subdata['p'], decimal_places, "cdf test %s failed with method '%s'\n%s" % (ix, default_method, failures), verbose=False)
  1314. def test_pdf_alpha_equals_one_beta_non_zero(self):
  1315. """ sample points extracted from Tables and Graphs of Stable Probability
  1316. Density Functions - Donald R Holt - 1973 - p 187.
  1317. """
  1318. xs = np.array([0, 0, 0, 0,
  1319. 1, 1, 1, 1,
  1320. 2, 2, 2, 2,
  1321. 3, 3, 3, 3,
  1322. 4, 4, 4, 4])
  1323. density = np.array([.3183, .3096, .2925, .2622,
  1324. .1591, .1587, .1599, .1635,
  1325. .0637, .0729, .0812, .0955,
  1326. .0318, .0390, .0458, .0586,
  1327. .0187, .0236, .0285, .0384])
  1328. betas = np.array([0, .25, .5, 1,
  1329. 0, .25, .5, 1,
  1330. 0, .25, .5, 1,
  1331. 0, .25, .5, 1,
  1332. 0, .25, .5, 1])
  1333. tests = [
  1334. ['quadrature', None, 4],
  1335. #['fft', 0, 4],
  1336. ['zolotarev', None, 1],
  1337. ]
  1338. with np.errstate(all='ignore'), suppress_warnings() as sup:
  1339. sup.filter(category=RuntimeWarning, message="Density calculation unstable.*")
  1340. for default_method, fft_min_points, decimal_places in tests:
  1341. stats.levy_stable.pdf_default_method = default_method
  1342. stats.levy_stable.pdf_fft_min_points_threshold = fft_min_points
  1343. #stats.levy_stable.fft_grid_spacing = 0.0001
  1344. pdf = stats.levy_stable.pdf(xs, 1, betas, scale=1, loc=0)
  1345. assert_almost_equal(pdf, density, decimal_places, default_method)
  1346. def test_stats(self):
  1347. param_sets = [
  1348. [(1.48,-.22, 0, 1), (0,np.inf,np.NaN,np.NaN)],
  1349. [(2,.9, 10, 1.5), (10,4.5,0,0)]
  1350. ]
  1351. for args, exp_stats in param_sets:
  1352. calc_stats = stats.levy_stable.stats(args[0], args[1], loc=args[2], scale=args[3], moments='mvsk')
  1353. assert_almost_equal(calc_stats, exp_stats)
  1354. class TestArrayArgument(object): # test for ticket:992
  1355. def setup_method(self):
  1356. np.random.seed(1234)
  1357. def test_noexception(self):
  1358. rvs = stats.norm.rvs(loc=(np.arange(5)), scale=np.ones(5),
  1359. size=(10, 5))
  1360. assert_equal(rvs.shape, (10, 5))
  1361. class TestDocstring(object):
  1362. def test_docstrings(self):
  1363. # See ticket #761
  1364. if stats.rayleigh.__doc__ is not None:
  1365. assert_("rayleigh" in stats.rayleigh.__doc__.lower())
  1366. if stats.bernoulli.__doc__ is not None:
  1367. assert_("bernoulli" in stats.bernoulli.__doc__.lower())
  1368. def test_no_name_arg(self):
  1369. # If name is not given, construction shouldn't fail. See #1508.
  1370. stats.rv_continuous()
  1371. stats.rv_discrete()
  1372. class TestEntropy(object):
  1373. def test_entropy_positive(self):
  1374. # See ticket #497
  1375. pk = [0.5, 0.2, 0.3]
  1376. qk = [0.1, 0.25, 0.65]
  1377. eself = stats.entropy(pk, pk)
  1378. edouble = stats.entropy(pk, qk)
  1379. assert_(0.0 == eself)
  1380. assert_(edouble >= 0.0)
  1381. def test_entropy_base(self):
  1382. pk = np.ones(16, float)
  1383. S = stats.entropy(pk, base=2.)
  1384. assert_(abs(S - 4.) < 1.e-5)
  1385. qk = np.ones(16, float)
  1386. qk[:8] = 2.
  1387. S = stats.entropy(pk, qk)
  1388. S2 = stats.entropy(pk, qk, base=2.)
  1389. assert_(abs(S/S2 - np.log(2.)) < 1.e-5)
  1390. def test_entropy_zero(self):
  1391. # Test for PR-479
  1392. assert_almost_equal(stats.entropy([0, 1, 2]), 0.63651416829481278,
  1393. decimal=12)
  1394. def test_entropy_2d(self):
  1395. pk = [[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]]
  1396. qk = [[0.2, 0.1], [0.3, 0.6], [0.5, 0.3]]
  1397. assert_array_almost_equal(stats.entropy(pk, qk),
  1398. [0.1933259, 0.18609809])
  1399. def test_entropy_2d_zero(self):
  1400. pk = [[0.1, 0.2], [0.6, 0.3], [0.3, 0.5]]
  1401. qk = [[0.0, 0.1], [0.3, 0.6], [0.5, 0.3]]
  1402. assert_array_almost_equal(stats.entropy(pk, qk),
  1403. [np.inf, 0.18609809])
  1404. pk[0][0] = 0.0
  1405. assert_array_almost_equal(stats.entropy(pk, qk),
  1406. [0.17403988, 0.18609809])
  1407. def TestArgsreduce():
  1408. a = array([1, 3, 2, 1, 2, 3, 3])
  1409. b, c = argsreduce(a > 1, a, 2)
  1410. assert_array_equal(b, [3, 2, 2, 3, 3])
  1411. assert_array_equal(c, [2, 2, 2, 2, 2])
  1412. b, c = argsreduce(2 > 1, a, 2)
  1413. assert_array_equal(b, a[0])
  1414. assert_array_equal(c, [2])
  1415. b, c = argsreduce(a > 0, a, 2)
  1416. assert_array_equal(b, a)
  1417. assert_array_equal(c, [2] * numpy.size(a))
  1418. class TestFitMethod(object):
  1419. skip = ['ncf']
  1420. def setup_method(self):
  1421. np.random.seed(1234)
  1422. @pytest.mark.slow
  1423. @pytest.mark.parametrize('dist,args,alpha', cases_test_all_distributions())
  1424. def test_fit(self, dist, args, alpha):
  1425. if dist in self.skip:
  1426. pytest.skip("%s fit known to fail" % dist)
  1427. distfunc = getattr(stats, dist)
  1428. with np.errstate(all='ignore'), suppress_warnings() as sup:
  1429. sup.filter(category=DeprecationWarning, message=".*frechet_")
  1430. res = distfunc.rvs(*args, **{'size': 200})
  1431. vals = distfunc.fit(res)
  1432. vals2 = distfunc.fit(res, optimizer='powell')
  1433. # Only check the length of the return
  1434. # FIXME: should check the actual results to see if we are 'close'
  1435. # to what was created --- but what is 'close' enough
  1436. assert_(len(vals) == 2+len(args))
  1437. assert_(len(vals2) == 2+len(args))
  1438. @pytest.mark.slow
  1439. @pytest.mark.parametrize('dist,args,alpha', cases_test_all_distributions())
  1440. def test_fix_fit(self, dist, args, alpha):
  1441. # Not sure why 'ncf', and 'beta' are failing
  1442. # frechet has different len(args) than distfunc.numargs
  1443. if dist in self.skip + ['frechet']:
  1444. pytest.skip("%s fit known to fail" % dist)
  1445. distfunc = getattr(stats, dist)
  1446. with np.errstate(all='ignore'), suppress_warnings() as sup:
  1447. sup.filter(category=DeprecationWarning, message=".*frechet_")
  1448. res = distfunc.rvs(*args, **{'size': 200})
  1449. vals = distfunc.fit(res, floc=0)
  1450. vals2 = distfunc.fit(res, fscale=1)
  1451. assert_(len(vals) == 2+len(args))
  1452. assert_(vals[-2] == 0)
  1453. assert_(vals2[-1] == 1)
  1454. assert_(len(vals2) == 2+len(args))
  1455. if len(args) > 0:
  1456. vals3 = distfunc.fit(res, f0=args[0])
  1457. assert_(len(vals3) == 2+len(args))
  1458. assert_(vals3[0] == args[0])
  1459. if len(args) > 1:
  1460. vals4 = distfunc.fit(res, f1=args[1])
  1461. assert_(len(vals4) == 2+len(args))
  1462. assert_(vals4[1] == args[1])
  1463. if len(args) > 2:
  1464. vals5 = distfunc.fit(res, f2=args[2])
  1465. assert_(len(vals5) == 2+len(args))
  1466. assert_(vals5[2] == args[2])
  1467. def test_fix_fit_2args_lognorm(self):
  1468. # Regression test for #1551.
  1469. np.random.seed(12345)
  1470. with np.errstate(all='ignore'):
  1471. x = stats.lognorm.rvs(0.25, 0., 20.0, size=20)
  1472. expected_shape = np.sqrt(((np.log(x) - np.log(20))**2).mean())
  1473. assert_allclose(np.array(stats.lognorm.fit(x, floc=0, fscale=20)),
  1474. [expected_shape, 0, 20], atol=1e-8)
  1475. def test_fix_fit_norm(self):
  1476. x = np.arange(1, 6)
  1477. loc, scale = stats.norm.fit(x)
  1478. assert_almost_equal(loc, 3)
  1479. assert_almost_equal(scale, np.sqrt(2))
  1480. loc, scale = stats.norm.fit(x, floc=2)
  1481. assert_equal(loc, 2)
  1482. assert_equal(scale, np.sqrt(3))
  1483. loc, scale = stats.norm.fit(x, fscale=2)
  1484. assert_almost_equal(loc, 3)
  1485. assert_equal(scale, 2)
  1486. def test_fix_fit_gamma(self):
  1487. x = np.arange(1, 6)
  1488. meanlog = np.log(x).mean()
  1489. # A basic test of gamma.fit with floc=0.
  1490. floc = 0
  1491. a, loc, scale = stats.gamma.fit(x, floc=floc)
  1492. s = np.log(x.mean()) - meanlog
  1493. assert_almost_equal(np.log(a) - special.digamma(a), s, decimal=5)
  1494. assert_equal(loc, floc)
  1495. assert_almost_equal(scale, x.mean()/a, decimal=8)
  1496. # Regression tests for gh-2514.
  1497. # The problem was that if `floc=0` was given, any other fixed
  1498. # parameters were ignored.
  1499. f0 = 1
  1500. floc = 0
  1501. a, loc, scale = stats.gamma.fit(x, f0=f0, floc=floc)
  1502. assert_equal(a, f0)
  1503. assert_equal(loc, floc)
  1504. assert_almost_equal(scale, x.mean()/a, decimal=8)
  1505. f0 = 2
  1506. floc = 0
  1507. a, loc, scale = stats.gamma.fit(x, f0=f0, floc=floc)
  1508. assert_equal(a, f0)
  1509. assert_equal(loc, floc)
  1510. assert_almost_equal(scale, x.mean()/a, decimal=8)
  1511. # loc and scale fixed.
  1512. floc = 0
  1513. fscale = 2
  1514. a, loc, scale = stats.gamma.fit(x, floc=floc, fscale=fscale)
  1515. assert_equal(loc, floc)
  1516. assert_equal(scale, fscale)
  1517. c = meanlog - np.log(fscale)
  1518. assert_almost_equal(special.digamma(a), c)
  1519. def test_fix_fit_beta(self):
  1520. # Test beta.fit when both floc and fscale are given.
  1521. def mlefunc(a, b, x):
  1522. # Zeros of this function are critical points of
  1523. # the maximum likelihood function.
  1524. n = len(x)
  1525. s1 = np.log(x).sum()
  1526. s2 = np.log(1-x).sum()
  1527. psiab = special.psi(a + b)
  1528. func = [s1 - n * (-psiab + special.psi(a)),
  1529. s2 - n * (-psiab + special.psi(b))]
  1530. return func
  1531. # Basic test with floc and fscale given.
  1532. x = np.array([0.125, 0.25, 0.5])
  1533. a, b, loc, scale = stats.beta.fit(x, floc=0, fscale=1)
  1534. assert_equal(loc, 0)
  1535. assert_equal(scale, 1)
  1536. assert_allclose(mlefunc(a, b, x), [0, 0], atol=1e-6)
  1537. # Basic test with f0, floc and fscale given.
  1538. # This is also a regression test for gh-2514.
  1539. x = np.array([0.125, 0.25, 0.5])
  1540. a, b, loc, scale = stats.beta.fit(x, f0=2, floc=0, fscale=1)
  1541. assert_equal(a, 2)
  1542. assert_equal(loc, 0)
  1543. assert_equal(scale, 1)
  1544. da, db = mlefunc(a, b, x)
  1545. assert_allclose(db, 0, atol=1e-5)
  1546. # Same floc and fscale values as above, but reverse the data
  1547. # and fix b (f1).
  1548. x2 = 1 - x
  1549. a2, b2, loc2, scale2 = stats.beta.fit(x2, f1=2, floc=0, fscale=1)
  1550. assert_equal(b2, 2)
  1551. assert_equal(loc2, 0)
  1552. assert_equal(scale2, 1)
  1553. da, db = mlefunc(a2, b2, x2)
  1554. assert_allclose(da, 0, atol=1e-5)
  1555. # a2 of this test should equal b from above.
  1556. assert_almost_equal(a2, b)
  1557. # Check for detection of data out of bounds when floc and fscale
  1558. # are given.
  1559. assert_raises(ValueError, stats.beta.fit, x, floc=0.5, fscale=1)
  1560. y = np.array([0, .5, 1])
  1561. assert_raises(ValueError, stats.beta.fit, y, floc=0, fscale=1)
  1562. assert_raises(ValueError, stats.beta.fit, y, floc=0, fscale=1, f0=2)
  1563. assert_raises(ValueError, stats.beta.fit, y, floc=0, fscale=1, f1=2)
  1564. # Check that attempting to fix all the parameters raises a ValueError.
  1565. assert_raises(ValueError, stats.beta.fit, y, f0=0, f1=1,
  1566. floc=2, fscale=3)
  1567. def test_expon_fit(self):
  1568. x = np.array([2, 2, 4, 4, 4, 4, 4, 8])
  1569. loc, scale = stats.expon.fit(x)
  1570. assert_equal(loc, 2) # x.min()
  1571. assert_equal(scale, 2) # x.mean() - x.min()
  1572. loc, scale = stats.expon.fit(x, fscale=3)
  1573. assert_equal(loc, 2) # x.min()
  1574. assert_equal(scale, 3) # fscale
  1575. loc, scale = stats.expon.fit(x, floc=0)
  1576. assert_equal(loc, 0) # floc
  1577. assert_equal(scale, 4) # x.mean() - loc
  1578. def test_lognorm_fit(self):
  1579. x = np.array([1.5, 3, 10, 15, 23, 59])
  1580. lnxm1 = np.log(x - 1)
  1581. shape, loc, scale = stats.lognorm.fit(x, floc=1)
  1582. assert_allclose(shape, lnxm1.std(), rtol=1e-12)
  1583. assert_equal(loc, 1)
  1584. assert_allclose(scale, np.exp(lnxm1.mean()), rtol=1e-12)
  1585. shape, loc, scale = stats.lognorm.fit(x, floc=1, fscale=6)
  1586. assert_allclose(shape, np.sqrt(((lnxm1 - np.log(6))**2).mean()),
  1587. rtol=1e-12)
  1588. assert_equal(loc, 1)
  1589. assert_equal(scale, 6)
  1590. shape, loc, scale = stats.lognorm.fit(x, floc=1, fix_s=0.75)
  1591. assert_equal(shape, 0.75)
  1592. assert_equal(loc, 1)
  1593. assert_allclose(scale, np.exp(lnxm1.mean()), rtol=1e-12)
  1594. def test_uniform_fit(self):
  1595. x = np.array([1.0, 1.1, 1.2, 9.0])
  1596. loc, scale = stats.uniform.fit(x)
  1597. assert_equal(loc, x.min())
  1598. assert_equal(scale, x.ptp())
  1599. loc, scale = stats.uniform.fit(x, floc=0)
  1600. assert_equal(loc, 0)
  1601. assert_equal(scale, x.max())
  1602. loc, scale = stats.uniform.fit(x, fscale=10)
  1603. assert_equal(loc, 0)
  1604. assert_equal(scale, 10)
  1605. assert_raises(ValueError, stats.uniform.fit, x, floc=2.0)
  1606. assert_raises(ValueError, stats.uniform.fit, x, fscale=5.0)
  1607. def test_fshapes(self):
  1608. # take a beta distribution, with shapes='a, b', and make sure that
  1609. # fa is equivalent to f0, and fb is equivalent to f1
  1610. a, b = 3., 4.
  1611. x = stats.beta.rvs(a, b, size=100, random_state=1234)
  1612. res_1 = stats.beta.fit(x, f0=3.)
  1613. res_2 = stats.beta.fit(x, fa=3.)
  1614. assert_allclose(res_1, res_2, atol=1e-12, rtol=1e-12)
  1615. res_2 = stats.beta.fit(x, fix_a=3.)
  1616. assert_allclose(res_1, res_2, atol=1e-12, rtol=1e-12)
  1617. res_3 = stats.beta.fit(x, f1=4.)
  1618. res_4 = stats.beta.fit(x, fb=4.)
  1619. assert_allclose(res_3, res_4, atol=1e-12, rtol=1e-12)
  1620. res_4 = stats.beta.fit(x, fix_b=4.)
  1621. assert_allclose(res_3, res_4, atol=1e-12, rtol=1e-12)
  1622. # cannot specify both positional and named args at the same time
  1623. assert_raises(ValueError, stats.beta.fit, x, fa=1, f0=2)
  1624. # check that attempting to fix all parameters raises a ValueError
  1625. assert_raises(ValueError, stats.beta.fit, x, fa=0, f1=1,
  1626. floc=2, fscale=3)
  1627. # check that specifying floc, fscale and fshapes works for
  1628. # beta and gamma which override the generic fit method
  1629. res_5 = stats.beta.fit(x, fa=3., floc=0, fscale=1)
  1630. aa, bb, ll, ss = res_5
  1631. assert_equal([aa, ll, ss], [3., 0, 1])
  1632. # gamma distribution
  1633. a = 3.
  1634. data = stats.gamma.rvs(a, size=100)
  1635. aa, ll, ss = stats.gamma.fit(data, fa=a)
  1636. assert_equal(aa, a)
  1637. def test_extra_params(self):
  1638. # unknown parameters should raise rather than be silently ignored
  1639. dist = stats.exponnorm
  1640. data = dist.rvs(K=2, size=100)
  1641. dct = dict(enikibeniki=-101)
  1642. assert_raises(TypeError, dist.fit, data, **dct)
  1643. class TestFrozen(object):
  1644. def setup_method(self):
  1645. np.random.seed(1234)
  1646. # Test that a frozen distribution gives the same results as the original
  1647. # object.
  1648. #
  1649. # Only tested for the normal distribution (with loc and scale specified)
  1650. # and for the gamma distribution (with a shape parameter specified).
  1651. def test_norm(self):
  1652. dist = stats.norm
  1653. frozen = stats.norm(loc=10.0, scale=3.0)
  1654. result_f = frozen.pdf(20.0)
  1655. result = dist.pdf(20.0, loc=10.0, scale=3.0)
  1656. assert_equal(result_f, result)
  1657. result_f = frozen.cdf(20.0)
  1658. result = dist.cdf(20.0, loc=10.0, scale=3.0)
  1659. assert_equal(result_f, result)
  1660. result_f = frozen.ppf(0.25)
  1661. result = dist.ppf(0.25, loc=10.0, scale=3.0)
  1662. assert_equal(result_f, result)
  1663. result_f = frozen.isf(0.25)
  1664. result = dist.isf(0.25, loc=10.0, scale=3.0)
  1665. assert_equal(result_f, result)
  1666. result_f = frozen.sf(10.0)
  1667. result = dist.sf(10.0, loc=10.0, scale=3.0)
  1668. assert_equal(result_f, result)
  1669. result_f = frozen.median()
  1670. result = dist.median(loc=10.0, scale=3.0)
  1671. assert_equal(result_f, result)
  1672. result_f = frozen.mean()
  1673. result = dist.mean(loc=10.0, scale=3.0)
  1674. assert_equal(result_f, result)
  1675. result_f = frozen.var()
  1676. result = dist.var(loc=10.0, scale=3.0)
  1677. assert_equal(result_f, result)
  1678. result_f = frozen.std()
  1679. result = dist.std(loc=10.0, scale=3.0)
  1680. assert_equal(result_f, result)
  1681. result_f = frozen.entropy()
  1682. result = dist.entropy(loc=10.0, scale=3.0)
  1683. assert_equal(result_f, result)
  1684. result_f = frozen.moment(2)
  1685. result = dist.moment(2, loc=10.0, scale=3.0)
  1686. assert_equal(result_f, result)
  1687. assert_equal(frozen.a, dist.a)
  1688. assert_equal(frozen.b, dist.b)
  1689. def test_gamma(self):
  1690. a = 2.0
  1691. dist = stats.gamma
  1692. frozen = stats.gamma(a)
  1693. result_f = frozen.pdf(20.0)
  1694. result = dist.pdf(20.0, a)
  1695. assert_equal(result_f, result)
  1696. result_f = frozen.cdf(20.0)
  1697. result = dist.cdf(20.0, a)
  1698. assert_equal(result_f, result)
  1699. result_f = frozen.ppf(0.25)
  1700. result = dist.ppf(0.25, a)
  1701. assert_equal(result_f, result)
  1702. result_f = frozen.isf(0.25)
  1703. result = dist.isf(0.25, a)
  1704. assert_equal(result_f, result)
  1705. result_f = frozen.sf(10.0)
  1706. result = dist.sf(10.0, a)
  1707. assert_equal(result_f, result)
  1708. result_f = frozen.median()
  1709. result = dist.median(a)
  1710. assert_equal(result_f, result)
  1711. result_f = frozen.mean()
  1712. result = dist.mean(a)
  1713. assert_equal(result_f, result)
  1714. result_f = frozen.var()
  1715. result = dist.var(a)
  1716. assert_equal(result_f, result)
  1717. result_f = frozen.std()
  1718. result = dist.std(a)
  1719. assert_equal(result_f, result)
  1720. result_f = frozen.entropy()
  1721. result = dist.entropy(a)
  1722. assert_equal(result_f, result)
  1723. result_f = frozen.moment(2)
  1724. result = dist.moment(2, a)
  1725. assert_equal(result_f, result)
  1726. assert_equal(frozen.a, frozen.dist.a)
  1727. assert_equal(frozen.b, frozen.dist.b)
  1728. def test_regression_ticket_1293(self):
  1729. # Create a frozen distribution.
  1730. frozen = stats.lognorm(1)
  1731. # Call one of its methods that does not take any keyword arguments.
  1732. m1 = frozen.moment(2)
  1733. # Now call a method that takes a keyword argument.
  1734. frozen.stats(moments='mvsk')
  1735. # Call moment(2) again.
  1736. # After calling stats(), the following was raising an exception.
  1737. # So this test passes if the following does not raise an exception.
  1738. m2 = frozen.moment(2)
  1739. # The following should also be true, of course. But it is not
  1740. # the focus of this test.
  1741. assert_equal(m1, m2)
  1742. def test_ab(self):
  1743. # test that the support of a frozen distribution
  1744. # (i) remains frozen even if it changes for the original one
  1745. # (ii) is actually correct if the shape parameters are such that
  1746. # the values of [a, b] are not the default [0, inf]
  1747. # take a genpareto as an example where the support
  1748. # depends on the value of the shape parameter:
  1749. # for c > 0: a, b = 0, inf
  1750. # for c < 0: a, b = 0, -1/c
  1751. rv = stats.genpareto(c=-0.1)
  1752. a, b = rv.dist.a, rv.dist.b
  1753. assert_equal([a, b], [0., 10.])
  1754. assert_equal([rv.a, rv.b], [0., 10.])
  1755. stats.genpareto.pdf(0, c=0.1) # this changes genpareto.b
  1756. assert_equal([rv.dist.a, rv.dist.b], [a, b])
  1757. assert_equal([rv.a, rv.b], [a, b])
  1758. rv1 = stats.genpareto(c=0.1)
  1759. assert_(rv1.dist is not rv.dist)
  1760. def test_rv_frozen_in_namespace(self):
  1761. # Regression test for gh-3522
  1762. assert_(hasattr(stats.distributions, 'rv_frozen'))
  1763. def test_random_state(self):
  1764. # only check that the random_state attribute exists,
  1765. frozen = stats.norm()
  1766. assert_(hasattr(frozen, 'random_state'))
  1767. # ... that it can be set,
  1768. frozen.random_state = 42
  1769. assert_equal(frozen.random_state.get_state(),
  1770. np.random.RandomState(42).get_state())
  1771. # ... and that .rvs method accepts it as an argument
  1772. rndm = np.random.RandomState(1234)
  1773. frozen.rvs(size=8, random_state=rndm)
  1774. def test_pickling(self):
  1775. # test that a frozen instance pickles and unpickles
  1776. # (this method is a clone of common_tests.check_pickling)
  1777. beta = stats.beta(2.3098496451481823, 0.62687954300963677)
  1778. poiss = stats.poisson(3.)
  1779. sample = stats.rv_discrete(values=([0, 1, 2, 3],
  1780. [0.1, 0.2, 0.3, 0.4]))
  1781. for distfn in [beta, poiss, sample]:
  1782. distfn.random_state = 1234
  1783. distfn.rvs(size=8)
  1784. s = pickle.dumps(distfn)
  1785. r0 = distfn.rvs(size=8)
  1786. unpickled = pickle.loads(s)
  1787. r1 = unpickled.rvs(size=8)
  1788. assert_equal(r0, r1)
  1789. # also smoke test some methods
  1790. medians = [distfn.ppf(0.5), unpickled.ppf(0.5)]
  1791. assert_equal(medians[0], medians[1])
  1792. assert_equal(distfn.cdf(medians[0]),
  1793. unpickled.cdf(medians[1]))
  1794. def test_expect(self):
  1795. # smoke test the expect method of the frozen distribution
  1796. # only take a gamma w/loc and scale and poisson with loc specified
  1797. def func(x):
  1798. return x
  1799. gm = stats.gamma(a=2, loc=3, scale=4)
  1800. gm_val = gm.expect(func, lb=1, ub=2, conditional=True)
  1801. gamma_val = stats.gamma.expect(func, args=(2,), loc=3, scale=4,
  1802. lb=1, ub=2, conditional=True)
  1803. assert_allclose(gm_val, gamma_val)
  1804. p = stats.poisson(3, loc=4)
  1805. p_val = p.expect(func)
  1806. poisson_val = stats.poisson.expect(func, args=(3,), loc=4)
  1807. assert_allclose(p_val, poisson_val)
  1808. class TestExpect(object):
  1809. # Test for expect method.
  1810. #
  1811. # Uses normal distribution and beta distribution for finite bounds, and
  1812. # hypergeom for discrete distribution with finite support
  1813. def test_norm(self):
  1814. v = stats.norm.expect(lambda x: (x-5)*(x-5), loc=5, scale=2)
  1815. assert_almost_equal(v, 4, decimal=14)
  1816. m = stats.norm.expect(lambda x: (x), loc=5, scale=2)
  1817. assert_almost_equal(m, 5, decimal=14)
  1818. lb = stats.norm.ppf(0.05, loc=5, scale=2)
  1819. ub = stats.norm.ppf(0.95, loc=5, scale=2)
  1820. prob90 = stats.norm.expect(lambda x: 1, loc=5, scale=2, lb=lb, ub=ub)
  1821. assert_almost_equal(prob90, 0.9, decimal=14)
  1822. prob90c = stats.norm.expect(lambda x: 1, loc=5, scale=2, lb=lb, ub=ub,
  1823. conditional=True)
  1824. assert_almost_equal(prob90c, 1., decimal=14)
  1825. def test_beta(self):
  1826. # case with finite support interval
  1827. v = stats.beta.expect(lambda x: (x-19/3.)*(x-19/3.), args=(10, 5),
  1828. loc=5, scale=2)
  1829. assert_almost_equal(v, 1./18., decimal=13)
  1830. m = stats.beta.expect(lambda x: x, args=(10, 5), loc=5., scale=2.)
  1831. assert_almost_equal(m, 19/3., decimal=13)
  1832. ub = stats.beta.ppf(0.95, 10, 10, loc=5, scale=2)
  1833. lb = stats.beta.ppf(0.05, 10, 10, loc=5, scale=2)
  1834. prob90 = stats.beta.expect(lambda x: 1., args=(10, 10), loc=5.,
  1835. scale=2., lb=lb, ub=ub, conditional=False)
  1836. assert_almost_equal(prob90, 0.9, decimal=13)
  1837. prob90c = stats.beta.expect(lambda x: 1, args=(10, 10), loc=5,
  1838. scale=2, lb=lb, ub=ub, conditional=True)
  1839. assert_almost_equal(prob90c, 1., decimal=13)
  1840. def test_hypergeom(self):
  1841. # test case with finite bounds
  1842. # without specifying bounds
  1843. m_true, v_true = stats.hypergeom.stats(20, 10, 8, loc=5.)
  1844. m = stats.hypergeom.expect(lambda x: x, args=(20, 10, 8), loc=5.)
  1845. assert_almost_equal(m, m_true, decimal=13)
  1846. v = stats.hypergeom.expect(lambda x: (x-9.)**2, args=(20, 10, 8),
  1847. loc=5.)
  1848. assert_almost_equal(v, v_true, decimal=14)
  1849. # with bounds, bounds equal to shifted support
  1850. v_bounds = stats.hypergeom.expect(lambda x: (x-9.)**2,
  1851. args=(20, 10, 8),
  1852. loc=5., lb=5, ub=13)
  1853. assert_almost_equal(v_bounds, v_true, decimal=14)
  1854. # drop boundary points
  1855. prob_true = 1-stats.hypergeom.pmf([5, 13], 20, 10, 8, loc=5).sum()
  1856. prob_bounds = stats.hypergeom.expect(lambda x: 1, args=(20, 10, 8),
  1857. loc=5., lb=6, ub=12)
  1858. assert_almost_equal(prob_bounds, prob_true, decimal=13)
  1859. # conditional
  1860. prob_bc = stats.hypergeom.expect(lambda x: 1, args=(20, 10, 8), loc=5.,
  1861. lb=6, ub=12, conditional=True)
  1862. assert_almost_equal(prob_bc, 1, decimal=14)
  1863. # check simple integral
  1864. prob_b = stats.hypergeom.expect(lambda x: 1, args=(20, 10, 8),
  1865. lb=0, ub=8)
  1866. assert_almost_equal(prob_b, 1, decimal=13)
  1867. def test_poisson(self):
  1868. # poisson, use lower bound only
  1869. prob_bounds = stats.poisson.expect(lambda x: 1, args=(2,), lb=3,
  1870. conditional=False)
  1871. prob_b_true = 1-stats.poisson.cdf(2, 2)
  1872. assert_almost_equal(prob_bounds, prob_b_true, decimal=14)
  1873. prob_lb = stats.poisson.expect(lambda x: 1, args=(2,), lb=2,
  1874. conditional=True)
  1875. assert_almost_equal(prob_lb, 1, decimal=14)
  1876. def test_genhalflogistic(self):
  1877. # genhalflogistic, changes upper bound of support in _argcheck
  1878. # regression test for gh-2622
  1879. halflog = stats.genhalflogistic
  1880. # check consistency when calling expect twice with the same input
  1881. res1 = halflog.expect(args=(1.5,))
  1882. halflog.expect(args=(0.5,))
  1883. res2 = halflog.expect(args=(1.5,))
  1884. assert_almost_equal(res1, res2, decimal=14)
  1885. def test_rice_overflow(self):
  1886. # rice.pdf(999, 0.74) was inf since special.i0 silentyly overflows
  1887. # check that using i0e fixes it
  1888. assert_(np.isfinite(stats.rice.pdf(999, 0.74)))
  1889. assert_(np.isfinite(stats.rice.expect(lambda x: 1, args=(0.74,))))
  1890. assert_(np.isfinite(stats.rice.expect(lambda x: 2, args=(0.74,))))
  1891. assert_(np.isfinite(stats.rice.expect(lambda x: 3, args=(0.74,))))
  1892. def test_logser(self):
  1893. # test a discrete distribution with infinite support and loc
  1894. p, loc = 0.3, 3
  1895. res_0 = stats.logser.expect(lambda k: k, args=(p,))
  1896. # check against the correct answer (sum of a geom series)
  1897. assert_allclose(res_0,
  1898. p / (p - 1.) / np.log(1. - p), atol=1e-15)
  1899. # now check it with `loc`
  1900. res_l = stats.logser.expect(lambda k: k, args=(p,), loc=loc)
  1901. assert_allclose(res_l, res_0 + loc, atol=1e-15)
  1902. def test_skellam(self):
  1903. # Use a discrete distribution w/ bi-infinite support. Compute two first
  1904. # moments and compare to known values (cf skellam.stats)
  1905. p1, p2 = 18, 22
  1906. m1 = stats.skellam.expect(lambda x: x, args=(p1, p2))
  1907. m2 = stats.skellam.expect(lambda x: x**2, args=(p1, p2))
  1908. assert_allclose(m1, p1 - p2, atol=1e-12)
  1909. assert_allclose(m2 - m1**2, p1 + p2, atol=1e-12)
  1910. def test_randint(self):
  1911. # Use a discrete distribution w/ parameter-dependent support, which
  1912. # is larger than the default chunksize
  1913. lo, hi = 0, 113
  1914. res = stats.randint.expect(lambda x: x, (lo, hi))
  1915. assert_allclose(res,
  1916. sum(_ for _ in range(lo, hi)) / (hi - lo), atol=1e-15)
  1917. def test_zipf(self):
  1918. # Test that there is no infinite loop even if the sum diverges
  1919. assert_warns(RuntimeWarning, stats.zipf.expect,
  1920. lambda x: x**2, (2,))
  1921. def test_discrete_kwds(self):
  1922. # check that discrete expect accepts keywords to control the summation
  1923. n0 = stats.poisson.expect(lambda x: 1, args=(2,))
  1924. n1 = stats.poisson.expect(lambda x: 1, args=(2,),
  1925. maxcount=1001, chunksize=32, tolerance=1e-8)
  1926. assert_almost_equal(n0, n1, decimal=14)
  1927. def test_moment(self):
  1928. # test the .moment() method: compute a higher moment and compare to
  1929. # a known value
  1930. def poiss_moment5(mu):
  1931. return mu**5 + 10*mu**4 + 25*mu**3 + 15*mu**2 + mu
  1932. for mu in [5, 7]:
  1933. m5 = stats.poisson.moment(5, mu)
  1934. assert_allclose(m5, poiss_moment5(mu), rtol=1e-10)
  1935. class TestNct(object):
  1936. def test_nc_parameter(self):
  1937. # Parameter values c<=0 were not enabled (gh-2402).
  1938. # For negative values c and for c=0 results of rv.cdf(0) below were nan
  1939. rv = stats.nct(5, 0)
  1940. assert_equal(rv.cdf(0), 0.5)
  1941. rv = stats.nct(5, -1)
  1942. assert_almost_equal(rv.cdf(0), 0.841344746069, decimal=10)
  1943. def test_broadcasting(self):
  1944. res = stats.nct.pdf(5, np.arange(4, 7)[:, None],
  1945. np.linspace(0.1, 1, 4))
  1946. expected = array([[0.00321886, 0.00557466, 0.00918418, 0.01442997],
  1947. [0.00217142, 0.00395366, 0.00683888, 0.01126276],
  1948. [0.00153078, 0.00291093, 0.00525206, 0.00900815]])
  1949. assert_allclose(res, expected, rtol=1e-5)
  1950. def test_variance_gh_issue_2401(self):
  1951. # Computation of the variance of a non-central t-distribution resulted
  1952. # in a TypeError: ufunc 'isinf' not supported for the input types,
  1953. # and the inputs could not be safely coerced to any supported types
  1954. # according to the casting rule 'safe'
  1955. rv = stats.nct(4, 0)
  1956. assert_equal(rv.var(), 2.0)
  1957. def test_nct_inf_moments(self):
  1958. # n-th moment of nct only exists for df > n
  1959. m, v, s, k = stats.nct.stats(df=1.9, nc=0.3, moments='mvsk')
  1960. assert_(np.isfinite(m))
  1961. assert_equal([v, s, k], [np.inf, np.nan, np.nan])
  1962. m, v, s, k = stats.nct.stats(df=3.1, nc=0.3, moments='mvsk')
  1963. assert_(np.isfinite([m, v, s]).all())
  1964. assert_equal(k, np.nan)
  1965. class TestRice(object):
  1966. def test_rice_zero_b(self):
  1967. # rice distribution should work with b=0, cf gh-2164
  1968. x = [0.2, 1., 5.]
  1969. assert_(np.isfinite(stats.rice.pdf(x, b=0.)).all())
  1970. assert_(np.isfinite(stats.rice.logpdf(x, b=0.)).all())
  1971. assert_(np.isfinite(stats.rice.cdf(x, b=0.)).all())
  1972. assert_(np.isfinite(stats.rice.logcdf(x, b=0.)).all())
  1973. q = [0.1, 0.1, 0.5, 0.9]
  1974. assert_(np.isfinite(stats.rice.ppf(q, b=0.)).all())
  1975. mvsk = stats.rice.stats(0, moments='mvsk')
  1976. assert_(np.isfinite(mvsk).all())
  1977. # furthermore, pdf is continuous as b\to 0
  1978. # rice.pdf(x, b\to 0) = x exp(-x^2/2) + O(b^2)
  1979. # see e.g. Abramovich & Stegun 9.6.7 & 9.6.10
  1980. b = 1e-8
  1981. assert_allclose(stats.rice.pdf(x, 0), stats.rice.pdf(x, b),
  1982. atol=b, rtol=0)
  1983. def test_rice_rvs(self):
  1984. rvs = stats.rice.rvs
  1985. assert_equal(rvs(b=3.).size, 1)
  1986. assert_equal(rvs(b=3., size=(3, 5)).shape, (3, 5))
  1987. class TestErlang(object):
  1988. def setup_method(self):
  1989. np.random.seed(1234)
  1990. def test_erlang_runtimewarning(self):
  1991. # erlang should generate a RuntimeWarning if a non-integer
  1992. # shape parameter is used.
  1993. with warnings.catch_warnings():
  1994. warnings.simplefilter("error", RuntimeWarning)
  1995. # The non-integer shape parameter 1.3 should trigger a
  1996. # RuntimeWarning
  1997. assert_raises(RuntimeWarning,
  1998. stats.erlang.rvs, 1.3, loc=0, scale=1, size=4)
  1999. # Calling the fit method with `f0` set to an integer should
  2000. # *not* trigger a RuntimeWarning. It should return the same
  2001. # values as gamma.fit(...).
  2002. data = [0.5, 1.0, 2.0, 4.0]
  2003. result_erlang = stats.erlang.fit(data, f0=1)
  2004. result_gamma = stats.gamma.fit(data, f0=1)
  2005. assert_allclose(result_erlang, result_gamma, rtol=1e-3)
  2006. class TestRayleigh(object):
  2007. # gh-6227
  2008. def test_logpdf(self):
  2009. y = stats.rayleigh.logpdf(50)
  2010. assert_allclose(y, -1246.0879769945718)
  2011. def test_logsf(self):
  2012. y = stats.rayleigh.logsf(50)
  2013. assert_allclose(y, -1250)
  2014. class TestExponWeib(object):
  2015. def test_pdf_logpdf(self):
  2016. # Regression test for gh-3508.
  2017. x = 0.1
  2018. a = 1.0
  2019. c = 100.0
  2020. p = stats.exponweib.pdf(x, a, c)
  2021. logp = stats.exponweib.logpdf(x, a, c)
  2022. # Expected values were computed with mpmath.
  2023. assert_allclose([p, logp],
  2024. [1.0000000000000054e-97, -223.35075402042244])
  2025. def test_a_is_1(self):
  2026. # For issue gh-3508.
  2027. # Check that when a=1, the pdf and logpdf methods of exponweib are the
  2028. # same as those of weibull_min.
  2029. x = np.logspace(-4, -1, 4)
  2030. a = 1
  2031. c = 100
  2032. p = stats.exponweib.pdf(x, a, c)
  2033. expected = stats.weibull_min.pdf(x, c)
  2034. assert_allclose(p, expected)
  2035. logp = stats.exponweib.logpdf(x, a, c)
  2036. expected = stats.weibull_min.logpdf(x, c)
  2037. assert_allclose(logp, expected)
  2038. def test_a_is_1_c_is_1(self):
  2039. # When a = 1 and c = 1, the distribution is exponential.
  2040. x = np.logspace(-8, 1, 10)
  2041. a = 1
  2042. c = 1
  2043. p = stats.exponweib.pdf(x, a, c)
  2044. expected = stats.expon.pdf(x)
  2045. assert_allclose(p, expected)
  2046. logp = stats.exponweib.logpdf(x, a, c)
  2047. expected = stats.expon.logpdf(x)
  2048. assert_allclose(logp, expected)
  2049. class TestWeibull(object):
  2050. def test_logpdf(self):
  2051. # gh-6217
  2052. y = stats.weibull_min.logpdf(0, 1)
  2053. assert_equal(y, 0)
  2054. def test_with_maxima_distrib(self):
  2055. # Tests for weibull_min and weibull_max.
  2056. # The expected values were computed using the symbolic algebra
  2057. # program 'maxima' with the package 'distrib', which has
  2058. # 'pdf_weibull' and 'cdf_weibull'. The mapping between the
  2059. # scipy and maxima functions is as follows:
  2060. # -----------------------------------------------------------------
  2061. # scipy maxima
  2062. # --------------------------------- ------------------------------
  2063. # weibull_min.pdf(x, a, scale=b) pdf_weibull(x, a, b)
  2064. # weibull_min.logpdf(x, a, scale=b) log(pdf_weibull(x, a, b))
  2065. # weibull_min.cdf(x, a, scale=b) cdf_weibull(x, a, b)
  2066. # weibull_min.logcdf(x, a, scale=b) log(cdf_weibull(x, a, b))
  2067. # weibull_min.sf(x, a, scale=b) 1 - cdf_weibull(x, a, b)
  2068. # weibull_min.logsf(x, a, scale=b) log(1 - cdf_weibull(x, a, b))
  2069. #
  2070. # weibull_max.pdf(x, a, scale=b) pdf_weibull(-x, a, b)
  2071. # weibull_max.logpdf(x, a, scale=b) log(pdf_weibull(-x, a, b))
  2072. # weibull_max.cdf(x, a, scale=b) 1 - cdf_weibull(-x, a, b)
  2073. # weibull_max.logcdf(x, a, scale=b) log(1 - cdf_weibull(-x, a, b))
  2074. # weibull_max.sf(x, a, scale=b) cdf_weibull(-x, a, b)
  2075. # weibull_max.logsf(x, a, scale=b) log(cdf_weibull(-x, a, b))
  2076. # -----------------------------------------------------------------
  2077. x = 1.5
  2078. a = 2.0
  2079. b = 3.0
  2080. # weibull_min
  2081. p = stats.weibull_min.pdf(x, a, scale=b)
  2082. assert_allclose(p, np.exp(-0.25)/3)
  2083. lp = stats.weibull_min.logpdf(x, a, scale=b)
  2084. assert_allclose(lp, -0.25 - np.log(3))
  2085. c = stats.weibull_min.cdf(x, a, scale=b)
  2086. assert_allclose(c, -special.expm1(-0.25))
  2087. lc = stats.weibull_min.logcdf(x, a, scale=b)
  2088. assert_allclose(lc, np.log(-special.expm1(-0.25)))
  2089. s = stats.weibull_min.sf(x, a, scale=b)
  2090. assert_allclose(s, np.exp(-0.25))
  2091. ls = stats.weibull_min.logsf(x, a, scale=b)
  2092. assert_allclose(ls, -0.25)
  2093. # Also test using a large value x, for which computing the survival
  2094. # function using the CDF would result in 0.
  2095. s = stats.weibull_min.sf(30, 2, scale=3)
  2096. assert_allclose(s, np.exp(-100))
  2097. ls = stats.weibull_min.logsf(30, 2, scale=3)
  2098. assert_allclose(ls, -100)
  2099. # weibull_max
  2100. x = -1.5
  2101. p = stats.weibull_max.pdf(x, a, scale=b)
  2102. assert_allclose(p, np.exp(-0.25)/3)
  2103. lp = stats.weibull_max.logpdf(x, a, scale=b)
  2104. assert_allclose(lp, -0.25 - np.log(3))
  2105. c = stats.weibull_max.cdf(x, a, scale=b)
  2106. assert_allclose(c, np.exp(-0.25))
  2107. lc = stats.weibull_max.logcdf(x, a, scale=b)
  2108. assert_allclose(lc, -0.25)
  2109. s = stats.weibull_max.sf(x, a, scale=b)
  2110. assert_allclose(s, -special.expm1(-0.25))
  2111. ls = stats.weibull_max.logsf(x, a, scale=b)
  2112. assert_allclose(ls, np.log(-special.expm1(-0.25)))
  2113. # Also test using a value of x close to 0, for which computing the
  2114. # survival function using the CDF would result in 0.
  2115. s = stats.weibull_max.sf(-1e-9, 2, scale=3)
  2116. assert_allclose(s, -special.expm1(-1/9000000000000000000))
  2117. ls = stats.weibull_max.logsf(-1e-9, 2, scale=3)
  2118. assert_allclose(ls, np.log(-special.expm1(-1/9000000000000000000)))
  2119. class TestRdist(object):
  2120. @pytest.mark.slow
  2121. def test_rdist_cdf_gh1285(self):
  2122. # check workaround in rdist._cdf for issue gh-1285.
  2123. distfn = stats.rdist
  2124. values = [0.001, 0.5, 0.999]
  2125. assert_almost_equal(distfn.cdf(distfn.ppf(values, 541.0), 541.0),
  2126. values, decimal=5)
  2127. class TestTrapz(object):
  2128. def test_reduces_to_triang(self):
  2129. modes = [0, 0.3, 0.5, 1]
  2130. for mode in modes:
  2131. x = [0, mode, 1]
  2132. assert_almost_equal(stats.trapz.pdf(x, mode, mode),
  2133. stats.triang.pdf(x, mode))
  2134. assert_almost_equal(stats.trapz.cdf(x, mode, mode),
  2135. stats.triang.cdf(x, mode))
  2136. def test_reduces_to_uniform(self):
  2137. x = np.linspace(0, 1, 10)
  2138. assert_almost_equal(stats.trapz.pdf(x, 0, 1), stats.uniform.pdf(x))
  2139. assert_almost_equal(stats.trapz.cdf(x, 0, 1), stats.uniform.cdf(x))
  2140. def test_cases(self):
  2141. # edge cases
  2142. assert_almost_equal(stats.trapz.pdf(0, 0, 0), 2)
  2143. assert_almost_equal(stats.trapz.pdf(1, 1, 1), 2)
  2144. assert_almost_equal(stats.trapz.pdf(0.5, 0, 0.8),
  2145. 1.11111111111111111)
  2146. assert_almost_equal(stats.trapz.pdf(0.5, 0.2, 1.0),
  2147. 1.11111111111111111)
  2148. # straightforward case
  2149. assert_almost_equal(stats.trapz.pdf(0.1, 0.2, 0.8), 0.625)
  2150. assert_almost_equal(stats.trapz.pdf(0.5, 0.2, 0.8), 1.25)
  2151. assert_almost_equal(stats.trapz.pdf(0.9, 0.2, 0.8), 0.625)
  2152. assert_almost_equal(stats.trapz.cdf(0.1, 0.2, 0.8), 0.03125)
  2153. assert_almost_equal(stats.trapz.cdf(0.2, 0.2, 0.8), 0.125)
  2154. assert_almost_equal(stats.trapz.cdf(0.5, 0.2, 0.8), 0.5)
  2155. assert_almost_equal(stats.trapz.cdf(0.9, 0.2, 0.8), 0.96875)
  2156. assert_almost_equal(stats.trapz.cdf(1.0, 0.2, 0.8), 1.0)
  2157. def test_trapz_vect(self):
  2158. # test that array-valued shapes and arguments are handled
  2159. c = np.array([0.1, 0.2, 0.3])
  2160. d = np.array([0.5, 0.6])[:, None]
  2161. x = np.array([0.15, 0.25, 0.9])
  2162. v = stats.trapz.pdf(x, c, d)
  2163. cc, dd, xx = np.broadcast_arrays(c, d, x)
  2164. res = np.empty(xx.size, dtype=xx.dtype)
  2165. ind = np.arange(xx.size)
  2166. for i, x1, c1, d1 in zip(ind, xx.ravel(), cc.ravel(), dd.ravel()):
  2167. res[i] = stats.trapz.pdf(x1, c1, d1)
  2168. assert_allclose(v, res.reshape(v.shape), atol=1e-15)
  2169. class TestTriang(object):
  2170. def test_edge_cases(self):
  2171. with np.errstate(all='raise'):
  2172. assert_equal(stats.triang.pdf(0, 0), 2.)
  2173. assert_equal(stats.triang.pdf(0.5, 0), 1.)
  2174. assert_equal(stats.triang.pdf(1, 0), 0.)
  2175. assert_equal(stats.triang.pdf(0, 1), 0)
  2176. assert_equal(stats.triang.pdf(0.5, 1), 1.)
  2177. assert_equal(stats.triang.pdf(1, 1), 2)
  2178. assert_equal(stats.triang.cdf(0., 0.), 0.)
  2179. assert_equal(stats.triang.cdf(0.5, 0.), 0.75)
  2180. assert_equal(stats.triang.cdf(1.0, 0.), 1.0)
  2181. assert_equal(stats.triang.cdf(0., 1.), 0.)
  2182. assert_equal(stats.triang.cdf(0.5, 1.), 0.25)
  2183. assert_equal(stats.triang.cdf(1., 1.), 1)
  2184. def test_540_567():
  2185. # test for nan returned in tickets 540, 567
  2186. assert_almost_equal(stats.norm.cdf(-1.7624320982), 0.03899815971089126,
  2187. decimal=10, err_msg='test_540_567')
  2188. assert_almost_equal(stats.norm.cdf(-1.7624320983), 0.038998159702449846,
  2189. decimal=10, err_msg='test_540_567')
  2190. assert_almost_equal(stats.norm.cdf(1.38629436112, loc=0.950273420309,
  2191. scale=0.204423758009),
  2192. 0.98353464004309321,
  2193. decimal=10, err_msg='test_540_567')
  2194. def test_regression_ticket_1316():
  2195. # The following was raising an exception, because _construct_default_doc()
  2196. # did not handle the default keyword extradoc=None. See ticket #1316.
  2197. g = stats._continuous_distns.gamma_gen(name='gamma')
  2198. def test_regression_ticket_1326():
  2199. # adjust to avoid nan with 0*log(0)
  2200. assert_almost_equal(stats.chi2.pdf(0.0, 2), 0.5, 14)
  2201. def test_regression_tukey_lambda():
  2202. # Make sure that Tukey-Lambda distribution correctly handles
  2203. # non-positive lambdas.
  2204. x = np.linspace(-5.0, 5.0, 101)
  2205. olderr = np.seterr(divide='ignore')
  2206. try:
  2207. for lam in [0.0, -1.0, -2.0, np.array([[-1.0], [0.0], [-2.0]])]:
  2208. p = stats.tukeylambda.pdf(x, lam)
  2209. assert_((p != 0.0).all())
  2210. assert_(~np.isnan(p).all())
  2211. lam = np.array([[-1.0], [0.0], [2.0]])
  2212. p = stats.tukeylambda.pdf(x, lam)
  2213. finally:
  2214. np.seterr(**olderr)
  2215. assert_(~np.isnan(p).all())
  2216. assert_((p[0] != 0.0).all())
  2217. assert_((p[1] != 0.0).all())
  2218. assert_((p[2] != 0.0).any())
  2219. assert_((p[2] == 0.0).any())
  2220. @pytest.mark.skipif(DOCSTRINGS_STRIPPED, reason="docstrings stripped")
  2221. def test_regression_ticket_1421():
  2222. assert_('pdf(x, mu, loc=0, scale=1)' not in stats.poisson.__doc__)
  2223. assert_('pmf(x,' in stats.poisson.__doc__)
  2224. def test_nan_arguments_gh_issue_1362():
  2225. with np.errstate(invalid='ignore'):
  2226. assert_(np.isnan(stats.t.logcdf(1, np.nan)))
  2227. assert_(np.isnan(stats.t.cdf(1, np.nan)))
  2228. assert_(np.isnan(stats.t.logsf(1, np.nan)))
  2229. assert_(np.isnan(stats.t.sf(1, np.nan)))
  2230. assert_(np.isnan(stats.t.pdf(1, np.nan)))
  2231. assert_(np.isnan(stats.t.logpdf(1, np.nan)))
  2232. assert_(np.isnan(stats.t.ppf(1, np.nan)))
  2233. assert_(np.isnan(stats.t.isf(1, np.nan)))
  2234. assert_(np.isnan(stats.bernoulli.logcdf(np.nan, 0.5)))
  2235. assert_(np.isnan(stats.bernoulli.cdf(np.nan, 0.5)))
  2236. assert_(np.isnan(stats.bernoulli.logsf(np.nan, 0.5)))
  2237. assert_(np.isnan(stats.bernoulli.sf(np.nan, 0.5)))
  2238. assert_(np.isnan(stats.bernoulli.pmf(np.nan, 0.5)))
  2239. assert_(np.isnan(stats.bernoulli.logpmf(np.nan, 0.5)))
  2240. assert_(np.isnan(stats.bernoulli.ppf(np.nan, 0.5)))
  2241. assert_(np.isnan(stats.bernoulli.isf(np.nan, 0.5)))
  2242. def test_frozen_fit_ticket_1536():
  2243. np.random.seed(5678)
  2244. true = np.array([0.25, 0., 0.5])
  2245. x = stats.lognorm.rvs(true[0], true[1], true[2], size=100)
  2246. olderr = np.seterr(divide='ignore')
  2247. try:
  2248. params = np.array(stats.lognorm.fit(x, floc=0.))
  2249. finally:
  2250. np.seterr(**olderr)
  2251. assert_almost_equal(params, true, decimal=2)
  2252. params = np.array(stats.lognorm.fit(x, fscale=0.5, loc=0))
  2253. assert_almost_equal(params, true, decimal=2)
  2254. params = np.array(stats.lognorm.fit(x, f0=0.25, loc=0))
  2255. assert_almost_equal(params, true, decimal=2)
  2256. params = np.array(stats.lognorm.fit(x, f0=0.25, floc=0))
  2257. assert_almost_equal(params, true, decimal=2)
  2258. np.random.seed(5678)
  2259. loc = 1
  2260. floc = 0.9
  2261. x = stats.norm.rvs(loc, 2., size=100)
  2262. params = np.array(stats.norm.fit(x, floc=floc))
  2263. expected = np.array([floc, np.sqrt(((x-floc)**2).mean())])
  2264. assert_almost_equal(params, expected, decimal=4)
  2265. def test_regression_ticket_1530():
  2266. # Check the starting value works for Cauchy distribution fit.
  2267. np.random.seed(654321)
  2268. rvs = stats.cauchy.rvs(size=100)
  2269. params = stats.cauchy.fit(rvs)
  2270. expected = (0.045, 1.142)
  2271. assert_almost_equal(params, expected, decimal=1)
  2272. def test_gh_pr_4806():
  2273. # Check starting values for Cauchy distribution fit.
  2274. np.random.seed(1234)
  2275. x = np.random.randn(42)
  2276. for offset in 10000.0, 1222333444.0:
  2277. loc, scale = stats.cauchy.fit(x + offset)
  2278. assert_allclose(loc, offset, atol=1.0)
  2279. assert_allclose(scale, 0.6, atol=1.0)
  2280. def test_tukeylambda_stats_ticket_1545():
  2281. # Some test for the variance and kurtosis of the Tukey Lambda distr.
  2282. # See test_tukeylamdba_stats.py for more tests.
  2283. mv = stats.tukeylambda.stats(0, moments='mvsk')
  2284. # Known exact values:
  2285. expected = [0, np.pi**2/3, 0, 1.2]
  2286. assert_almost_equal(mv, expected, decimal=10)
  2287. mv = stats.tukeylambda.stats(3.13, moments='mvsk')
  2288. # 'expected' computed with mpmath.
  2289. expected = [0, 0.0269220858861465102, 0, -0.898062386219224104]
  2290. assert_almost_equal(mv, expected, decimal=10)
  2291. mv = stats.tukeylambda.stats(0.14, moments='mvsk')
  2292. # 'expected' computed with mpmath.
  2293. expected = [0, 2.11029702221450250, 0, -0.02708377353223019456]
  2294. assert_almost_equal(mv, expected, decimal=10)
  2295. def test_poisson_logpmf_ticket_1436():
  2296. assert_(np.isfinite(stats.poisson.logpmf(1500, 200)))
  2297. def test_powerlaw_stats():
  2298. """Test the powerlaw stats function.
  2299. This unit test is also a regression test for ticket 1548.
  2300. The exact values are:
  2301. mean:
  2302. mu = a / (a + 1)
  2303. variance:
  2304. sigma**2 = a / ((a + 2) * (a + 1) ** 2)
  2305. skewness:
  2306. One formula (see https://en.wikipedia.org/wiki/Skewness) is
  2307. gamma_1 = (E[X**3] - 3*mu*E[X**2] + 2*mu**3) / sigma**3
  2308. A short calculation shows that E[X**k] is a / (a + k), so gamma_1
  2309. can be implemented as
  2310. n = a/(a+3) - 3*(a/(a+1))*a/(a+2) + 2*(a/(a+1))**3
  2311. d = sqrt(a/((a+2)*(a+1)**2)) ** 3
  2312. gamma_1 = n/d
  2313. Either by simplifying, or by a direct calculation of mu_3 / sigma**3,
  2314. one gets the more concise formula:
  2315. gamma_1 = -2.0 * ((a - 1) / (a + 3)) * sqrt((a + 2) / a)
  2316. kurtosis: (See https://en.wikipedia.org/wiki/Kurtosis)
  2317. The excess kurtosis is
  2318. gamma_2 = mu_4 / sigma**4 - 3
  2319. A bit of calculus and algebra (sympy helps) shows that
  2320. mu_4 = 3*a*(3*a**2 - a + 2) / ((a+1)**4 * (a+2) * (a+3) * (a+4))
  2321. so
  2322. gamma_2 = 3*(3*a**2 - a + 2) * (a+2) / (a*(a+3)*(a+4)) - 3
  2323. which can be rearranged to
  2324. gamma_2 = 6 * (a**3 - a**2 - 6*a + 2) / (a*(a+3)*(a+4))
  2325. """
  2326. cases = [(1.0, (0.5, 1./12, 0.0, -1.2)),
  2327. (2.0, (2./3, 2./36, -0.56568542494924734, -0.6))]
  2328. for a, exact_mvsk in cases:
  2329. mvsk = stats.powerlaw.stats(a, moments="mvsk")
  2330. assert_array_almost_equal(mvsk, exact_mvsk)
  2331. def test_powerlaw_edge():
  2332. # Regression test for gh-3986.
  2333. p = stats.powerlaw.logpdf(0, 1)
  2334. assert_equal(p, 0.0)
  2335. def test_exponpow_edge():
  2336. # Regression test for gh-3982.
  2337. p = stats.exponpow.logpdf(0, 1)
  2338. assert_equal(p, 0.0)
  2339. # Check pdf and logpdf at x = 0 for other values of b.
  2340. p = stats.exponpow.pdf(0, [0.25, 1.0, 1.5])
  2341. assert_equal(p, [np.inf, 1.0, 0.0])
  2342. p = stats.exponpow.logpdf(0, [0.25, 1.0, 1.5])
  2343. assert_equal(p, [np.inf, 0.0, -np.inf])
  2344. def test_gengamma_edge():
  2345. # Regression test for gh-3985.
  2346. p = stats.gengamma.pdf(0, 1, 1)
  2347. assert_equal(p, 1.0)
  2348. # Regression tests for gh-4724.
  2349. p = stats.gengamma._munp(-2, 200, 1.)
  2350. assert_almost_equal(p, 1./199/198)
  2351. p = stats.gengamma._munp(-2, 10, 1.)
  2352. assert_almost_equal(p, 1./9/8)
  2353. def test_ksone_fit_freeze():
  2354. # Regression test for ticket #1638.
  2355. d = np.array(
  2356. [-0.18879233, 0.15734249, 0.18695107, 0.27908787, -0.248649,
  2357. -0.2171497, 0.12233512, 0.15126419, 0.03119282, 0.4365294,
  2358. 0.08930393, -0.23509903, 0.28231224, -0.09974875, -0.25196048,
  2359. 0.11102028, 0.1427649, 0.10176452, 0.18754054, 0.25826724,
  2360. 0.05988819, 0.0531668, 0.21906056, 0.32106729, 0.2117662,
  2361. 0.10886442, 0.09375789, 0.24583286, -0.22968366, -0.07842391,
  2362. -0.31195432, -0.21271196, 0.1114243, -0.13293002, 0.01331725,
  2363. -0.04330977, -0.09485776, -0.28434547, 0.22245721, -0.18518199,
  2364. -0.10943985, -0.35243174, 0.06897665, -0.03553363, -0.0701746,
  2365. -0.06037974, 0.37670779, -0.21684405])
  2366. try:
  2367. olderr = np.seterr(invalid='ignore')
  2368. with suppress_warnings() as sup:
  2369. sup.filter(IntegrationWarning,
  2370. "The maximum number of subdivisions .50. has been "
  2371. "achieved.")
  2372. sup.filter(RuntimeWarning,
  2373. "floating point number truncated to an integer")
  2374. stats.ksone.fit(d)
  2375. finally:
  2376. np.seterr(**olderr)
  2377. def test_norm_logcdf():
  2378. # Test precision of the logcdf of the normal distribution.
  2379. # This precision was enhanced in ticket 1614.
  2380. x = -np.asarray(list(range(0, 120, 4)))
  2381. # Values from R
  2382. expected = [-0.69314718, -10.36010149, -35.01343716, -75.41067300,
  2383. -131.69539607, -203.91715537, -292.09872100, -396.25241451,
  2384. -516.38564863, -652.50322759, -804.60844201, -972.70364403,
  2385. -1156.79057310, -1356.87055173, -1572.94460885, -1805.01356068,
  2386. -2053.07806561, -2317.13866238, -2597.19579746, -2893.24984493,
  2387. -3205.30112136, -3533.34989701, -3877.39640444, -4237.44084522,
  2388. -4613.48339520, -5005.52420869, -5413.56342187, -5837.60115548,
  2389. -6277.63751711, -6733.67260303]
  2390. assert_allclose(stats.norm().logcdf(x), expected, atol=1e-8)
  2391. # also test the complex-valued code path
  2392. assert_allclose(stats.norm().logcdf(x + 1e-14j).real, expected, atol=1e-8)
  2393. # test the accuracy: d(logcdf)/dx = pdf / cdf \equiv exp(logpdf - logcdf)
  2394. deriv = (stats.norm.logcdf(x + 1e-10j)/1e-10).imag
  2395. deriv_expected = np.exp(stats.norm.logpdf(x) - stats.norm.logcdf(x))
  2396. assert_allclose(deriv, deriv_expected, atol=1e-10)
  2397. def test_levy_cdf_ppf():
  2398. # Test levy.cdf, including small arguments.
  2399. x = np.array([1000, 1.0, 0.5, 0.1, 0.01, 0.001])
  2400. # Expected values were calculated separately with mpmath.
  2401. # E.g.
  2402. # >>> mpmath.mp.dps = 100
  2403. # >>> x = mpmath.mp.mpf('0.01')
  2404. # >>> cdf = mpmath.erfc(mpmath.sqrt(1/(2*x)))
  2405. expected = np.array([0.9747728793699604,
  2406. 0.3173105078629141,
  2407. 0.1572992070502851,
  2408. 0.0015654022580025495,
  2409. 1.523970604832105e-23,
  2410. 1.795832784800726e-219])
  2411. y = stats.levy.cdf(x)
  2412. assert_allclose(y, expected, rtol=1e-10)
  2413. # ppf(expected) should get us back to x.
  2414. xx = stats.levy.ppf(expected)
  2415. assert_allclose(xx, x, rtol=1e-13)
  2416. def test_hypergeom_interval_1802():
  2417. # these two had endless loops
  2418. assert_equal(stats.hypergeom.interval(.95, 187601, 43192, 757),
  2419. (152.0, 197.0))
  2420. assert_equal(stats.hypergeom.interval(.945, 187601, 43192, 757),
  2421. (152.0, 197.0))
  2422. # this was working also before
  2423. assert_equal(stats.hypergeom.interval(.94, 187601, 43192, 757),
  2424. (153.0, 196.0))
  2425. # degenerate case .a == .b
  2426. assert_equal(stats.hypergeom.ppf(0.02, 100, 100, 8), 8)
  2427. assert_equal(stats.hypergeom.ppf(1, 100, 100, 8), 8)
  2428. def test_distribution_too_many_args():
  2429. np.random.seed(1234)
  2430. # Check that a TypeError is raised when too many args are given to a method
  2431. # Regression test for ticket 1815.
  2432. x = np.linspace(0.1, 0.7, num=5)
  2433. assert_raises(TypeError, stats.gamma.pdf, x, 2, 3, loc=1.0)
  2434. assert_raises(TypeError, stats.gamma.pdf, x, 2, 3, 4, loc=1.0)
  2435. assert_raises(TypeError, stats.gamma.pdf, x, 2, 3, 4, 5)
  2436. assert_raises(TypeError, stats.gamma.pdf, x, 2, 3, loc=1.0, scale=0.5)
  2437. assert_raises(TypeError, stats.gamma.rvs, 2., 3, loc=1.0, scale=0.5)
  2438. assert_raises(TypeError, stats.gamma.cdf, x, 2., 3, loc=1.0, scale=0.5)
  2439. assert_raises(TypeError, stats.gamma.ppf, x, 2., 3, loc=1.0, scale=0.5)
  2440. assert_raises(TypeError, stats.gamma.stats, 2., 3, loc=1.0, scale=0.5)
  2441. assert_raises(TypeError, stats.gamma.entropy, 2., 3, loc=1.0, scale=0.5)
  2442. assert_raises(TypeError, stats.gamma.fit, x, 2., 3, loc=1.0, scale=0.5)
  2443. # These should not give errors
  2444. stats.gamma.pdf(x, 2, 3) # loc=3
  2445. stats.gamma.pdf(x, 2, 3, 4) # loc=3, scale=4
  2446. stats.gamma.stats(2., 3)
  2447. stats.gamma.stats(2., 3, 4)
  2448. stats.gamma.stats(2., 3, 4, 'mv')
  2449. stats.gamma.rvs(2., 3, 4, 5)
  2450. stats.gamma.fit(stats.gamma.rvs(2., size=7), 2.)
  2451. # Also for a discrete distribution
  2452. stats.geom.pmf(x, 2, loc=3) # no error, loc=3
  2453. assert_raises(TypeError, stats.geom.pmf, x, 2, 3, 4)
  2454. assert_raises(TypeError, stats.geom.pmf, x, 2, 3, loc=4)
  2455. # And for distributions with 0, 2 and 3 args respectively
  2456. assert_raises(TypeError, stats.expon.pdf, x, 3, loc=1.0)
  2457. assert_raises(TypeError, stats.exponweib.pdf, x, 3, 4, 5, loc=1.0)
  2458. assert_raises(TypeError, stats.exponweib.pdf, x, 3, 4, 5, 0.1, 0.1)
  2459. assert_raises(TypeError, stats.ncf.pdf, x, 3, 4, 5, 6, loc=1.0)
  2460. assert_raises(TypeError, stats.ncf.pdf, x, 3, 4, 5, 6, 1.0, scale=0.5)
  2461. stats.ncf.pdf(x, 3, 4, 5, 6, 1.0) # 3 args, plus loc/scale
  2462. def test_ncx2_tails_ticket_955():
  2463. # Trac #955 -- check that the cdf computed by special functions
  2464. # matches the integrated pdf
  2465. a = stats.ncx2.cdf(np.arange(20, 25, 0.2), 2, 1.07458615e+02)
  2466. b = stats.ncx2._cdfvec(np.arange(20, 25, 0.2), 2, 1.07458615e+02)
  2467. assert_allclose(a, b, rtol=1e-3, atol=0)
  2468. def test_ncx2_tails_pdf():
  2469. # ncx2.pdf does not return nans in extreme tails(example from gh-1577)
  2470. # NB: this is to check that nan_to_num is not needed in ncx2.pdf
  2471. with suppress_warnings() as sup:
  2472. sup.filter(RuntimeWarning, "divide by zero encountered in log")
  2473. assert_equal(stats.ncx2.pdf(1, np.arange(340, 350), 2), 0)
  2474. logval = stats.ncx2.logpdf(1, np.arange(340, 350), 2)
  2475. assert_(np.isneginf(logval).all())
  2476. def test_foldnorm_zero():
  2477. # Parameter value c=0 was not enabled, see gh-2399.
  2478. rv = stats.foldnorm(0, scale=1)
  2479. assert_equal(rv.cdf(0), 0) # rv.cdf(0) previously resulted in: nan
  2480. def test_stats_shapes_argcheck():
  2481. # stats method was failing for vector shapes if some of the values
  2482. # were outside of the allowed range, see gh-2678
  2483. mv3 = stats.invgamma.stats([0.0, 0.5, 1.0], 1, 0.5) # 0 is not a legal `a`
  2484. mv2 = stats.invgamma.stats([0.5, 1.0], 1, 0.5)
  2485. mv2_augmented = tuple(np.r_[np.nan, _] for _ in mv2)
  2486. assert_equal(mv2_augmented, mv3)
  2487. # -1 is not a legal shape parameter
  2488. mv3 = stats.lognorm.stats([2, 2.4, -1])
  2489. mv2 = stats.lognorm.stats([2, 2.4])
  2490. mv2_augmented = tuple(np.r_[_, np.nan] for _ in mv2)
  2491. assert_equal(mv2_augmented, mv3)
  2492. # FIXME: this is only a quick-and-dirty test of a quick-and-dirty bugfix.
  2493. # stats method with multiple shape parameters is not properly vectorized
  2494. # anyway, so some distributions may or may not fail.
  2495. # Test subclassing distributions w/ explicit shapes
  2496. class _distr_gen(stats.rv_continuous):
  2497. def _pdf(self, x, a):
  2498. return 42
  2499. class _distr2_gen(stats.rv_continuous):
  2500. def _cdf(self, x, a):
  2501. return 42 * a + x
  2502. class _distr3_gen(stats.rv_continuous):
  2503. def _pdf(self, x, a, b):
  2504. return a + b
  2505. def _cdf(self, x, a):
  2506. # Different # of shape params from _pdf, to be able to check that
  2507. # inspection catches the inconsistency."""
  2508. return 42 * a + x
  2509. class _distr6_gen(stats.rv_continuous):
  2510. # Two shape parameters (both _pdf and _cdf defined, consistent shapes.)
  2511. def _pdf(self, x, a, b):
  2512. return a*x + b
  2513. def _cdf(self, x, a, b):
  2514. return 42 * a + x
  2515. class TestSubclassingExplicitShapes(object):
  2516. # Construct a distribution w/ explicit shapes parameter and test it.
  2517. def test_correct_shapes(self):
  2518. dummy_distr = _distr_gen(name='dummy', shapes='a')
  2519. assert_equal(dummy_distr.pdf(1, a=1), 42)
  2520. def test_wrong_shapes_1(self):
  2521. dummy_distr = _distr_gen(name='dummy', shapes='A')
  2522. assert_raises(TypeError, dummy_distr.pdf, 1, **dict(a=1))
  2523. def test_wrong_shapes_2(self):
  2524. dummy_distr = _distr_gen(name='dummy', shapes='a, b, c')
  2525. dct = dict(a=1, b=2, c=3)
  2526. assert_raises(TypeError, dummy_distr.pdf, 1, **dct)
  2527. def test_shapes_string(self):
  2528. # shapes must be a string
  2529. dct = dict(name='dummy', shapes=42)
  2530. assert_raises(TypeError, _distr_gen, **dct)
  2531. def test_shapes_identifiers_1(self):
  2532. # shapes must be a comma-separated list of valid python identifiers
  2533. dct = dict(name='dummy', shapes='(!)')
  2534. assert_raises(SyntaxError, _distr_gen, **dct)
  2535. def test_shapes_identifiers_2(self):
  2536. dct = dict(name='dummy', shapes='4chan')
  2537. assert_raises(SyntaxError, _distr_gen, **dct)
  2538. def test_shapes_identifiers_3(self):
  2539. dct = dict(name='dummy', shapes='m(fti)')
  2540. assert_raises(SyntaxError, _distr_gen, **dct)
  2541. def test_shapes_identifiers_nodefaults(self):
  2542. dct = dict(name='dummy', shapes='a=2')
  2543. assert_raises(SyntaxError, _distr_gen, **dct)
  2544. def test_shapes_args(self):
  2545. dct = dict(name='dummy', shapes='*args')
  2546. assert_raises(SyntaxError, _distr_gen, **dct)
  2547. def test_shapes_kwargs(self):
  2548. dct = dict(name='dummy', shapes='**kwargs')
  2549. assert_raises(SyntaxError, _distr_gen, **dct)
  2550. def test_shapes_keywords(self):
  2551. # python keywords cannot be used for shape parameters
  2552. dct = dict(name='dummy', shapes='a, b, c, lambda')
  2553. assert_raises(SyntaxError, _distr_gen, **dct)
  2554. def test_shapes_signature(self):
  2555. # test explicit shapes which agree w/ the signature of _pdf
  2556. class _dist_gen(stats.rv_continuous):
  2557. def _pdf(self, x, a):
  2558. return stats.norm._pdf(x) * a
  2559. dist = _dist_gen(shapes='a')
  2560. assert_equal(dist.pdf(0.5, a=2), stats.norm.pdf(0.5)*2)
  2561. def test_shapes_signature_inconsistent(self):
  2562. # test explicit shapes which do not agree w/ the signature of _pdf
  2563. class _dist_gen(stats.rv_continuous):
  2564. def _pdf(self, x, a):
  2565. return stats.norm._pdf(x) * a
  2566. dist = _dist_gen(shapes='a, b')
  2567. assert_raises(TypeError, dist.pdf, 0.5, **dict(a=1, b=2))
  2568. def test_star_args(self):
  2569. # test _pdf with only starargs
  2570. # NB: **kwargs of pdf will never reach _pdf
  2571. class _dist_gen(stats.rv_continuous):
  2572. def _pdf(self, x, *args):
  2573. extra_kwarg = args[0]
  2574. return stats.norm._pdf(x) * extra_kwarg
  2575. dist = _dist_gen(shapes='extra_kwarg')
  2576. assert_equal(dist.pdf(0.5, extra_kwarg=33), stats.norm.pdf(0.5)*33)
  2577. assert_equal(dist.pdf(0.5, 33), stats.norm.pdf(0.5)*33)
  2578. assert_raises(TypeError, dist.pdf, 0.5, **dict(xxx=33))
  2579. def test_star_args_2(self):
  2580. # test _pdf with named & starargs
  2581. # NB: **kwargs of pdf will never reach _pdf
  2582. class _dist_gen(stats.rv_continuous):
  2583. def _pdf(self, x, offset, *args):
  2584. extra_kwarg = args[0]
  2585. return stats.norm._pdf(x) * extra_kwarg + offset
  2586. dist = _dist_gen(shapes='offset, extra_kwarg')
  2587. assert_equal(dist.pdf(0.5, offset=111, extra_kwarg=33),
  2588. stats.norm.pdf(0.5)*33 + 111)
  2589. assert_equal(dist.pdf(0.5, 111, 33),
  2590. stats.norm.pdf(0.5)*33 + 111)
  2591. def test_extra_kwarg(self):
  2592. # **kwargs to _pdf are ignored.
  2593. # this is a limitation of the framework (_pdf(x, *goodargs))
  2594. class _distr_gen(stats.rv_continuous):
  2595. def _pdf(self, x, *args, **kwargs):
  2596. # _pdf should handle *args, **kwargs itself. Here "handling"
  2597. # is ignoring *args and looking for ``extra_kwarg`` and using
  2598. # that.
  2599. extra_kwarg = kwargs.pop('extra_kwarg', 1)
  2600. return stats.norm._pdf(x) * extra_kwarg
  2601. dist = _distr_gen(shapes='extra_kwarg')
  2602. assert_equal(dist.pdf(1, extra_kwarg=3), stats.norm.pdf(1))
  2603. def shapes_empty_string(self):
  2604. # shapes='' is equivalent to shapes=None
  2605. class _dist_gen(stats.rv_continuous):
  2606. def _pdf(self, x):
  2607. return stats.norm.pdf(x)
  2608. dist = _dist_gen(shapes='')
  2609. assert_equal(dist.pdf(0.5), stats.norm.pdf(0.5))
  2610. class TestSubclassingNoShapes(object):
  2611. # Construct a distribution w/o explicit shapes parameter and test it.
  2612. def test_only__pdf(self):
  2613. dummy_distr = _distr_gen(name='dummy')
  2614. assert_equal(dummy_distr.pdf(1, a=1), 42)
  2615. def test_only__cdf(self):
  2616. # _pdf is determined from _cdf by taking numerical derivative
  2617. dummy_distr = _distr2_gen(name='dummy')
  2618. assert_almost_equal(dummy_distr.pdf(1, a=1), 1)
  2619. @pytest.mark.skipif(DOCSTRINGS_STRIPPED, reason="docstring stripped")
  2620. def test_signature_inspection(self):
  2621. # check that _pdf signature inspection works correctly, and is used in
  2622. # the class docstring
  2623. dummy_distr = _distr_gen(name='dummy')
  2624. assert_equal(dummy_distr.numargs, 1)
  2625. assert_equal(dummy_distr.shapes, 'a')
  2626. res = re.findall(r'logpdf\(x, a, loc=0, scale=1\)',
  2627. dummy_distr.__doc__)
  2628. assert_(len(res) == 1)
  2629. @pytest.mark.skipif(DOCSTRINGS_STRIPPED, reason="docstring stripped")
  2630. def test_signature_inspection_2args(self):
  2631. # same for 2 shape params and both _pdf and _cdf defined
  2632. dummy_distr = _distr6_gen(name='dummy')
  2633. assert_equal(dummy_distr.numargs, 2)
  2634. assert_equal(dummy_distr.shapes, 'a, b')
  2635. res = re.findall(r'logpdf\(x, a, b, loc=0, scale=1\)',
  2636. dummy_distr.__doc__)
  2637. assert_(len(res) == 1)
  2638. def test_signature_inspection_2args_incorrect_shapes(self):
  2639. # both _pdf and _cdf defined, but shapes are inconsistent: raises
  2640. assert_raises(TypeError, _distr3_gen, name='dummy')
  2641. def test_defaults_raise(self):
  2642. # default arguments should raise
  2643. class _dist_gen(stats.rv_continuous):
  2644. def _pdf(self, x, a=42):
  2645. return 42
  2646. assert_raises(TypeError, _dist_gen, **dict(name='dummy'))
  2647. def test_starargs_raise(self):
  2648. # without explicit shapes, *args are not allowed
  2649. class _dist_gen(stats.rv_continuous):
  2650. def _pdf(self, x, a, *args):
  2651. return 42
  2652. assert_raises(TypeError, _dist_gen, **dict(name='dummy'))
  2653. def test_kwargs_raise(self):
  2654. # without explicit shapes, **kwargs are not allowed
  2655. class _dist_gen(stats.rv_continuous):
  2656. def _pdf(self, x, a, **kwargs):
  2657. return 42
  2658. assert_raises(TypeError, _dist_gen, **dict(name='dummy'))
  2659. @pytest.mark.skipif(DOCSTRINGS_STRIPPED, reason="docstring stripped")
  2660. def test_docstrings():
  2661. badones = [r',\s*,', r'\(\s*,', r'^\s*:']
  2662. for distname in stats.__all__:
  2663. dist = getattr(stats, distname)
  2664. if isinstance(dist, (stats.rv_discrete, stats.rv_continuous)):
  2665. for regex in badones:
  2666. assert_(re.search(regex, dist.__doc__) is None)
  2667. def test_infinite_input():
  2668. assert_almost_equal(stats.skellam.sf(np.inf, 10, 11), 0)
  2669. assert_almost_equal(stats.ncx2._cdf(np.inf, 8, 0.1), 1)
  2670. def test_lomax_accuracy():
  2671. # regression test for gh-4033
  2672. p = stats.lomax.ppf(stats.lomax.cdf(1e-100, 1), 1)
  2673. assert_allclose(p, 1e-100)
  2674. def test_gompertz_accuracy():
  2675. # Regression test for gh-4031
  2676. p = stats.gompertz.ppf(stats.gompertz.cdf(1e-100, 1), 1)
  2677. assert_allclose(p, 1e-100)
  2678. def test_truncexpon_accuracy():
  2679. # regression test for gh-4035
  2680. p = stats.truncexpon.ppf(stats.truncexpon.cdf(1e-100, 1), 1)
  2681. assert_allclose(p, 1e-100)
  2682. def test_rayleigh_accuracy():
  2683. # regression test for gh-4034
  2684. p = stats.rayleigh.isf(stats.rayleigh.sf(9, 1), 1)
  2685. assert_almost_equal(p, 9.0, decimal=15)
  2686. def test_genextreme_give_no_warnings():
  2687. """regression test for gh-6219"""
  2688. with warnings.catch_warnings(record=True) as w:
  2689. warnings.simplefilter("always")
  2690. p = stats.genextreme.cdf(.5, 0)
  2691. p = stats.genextreme.pdf(.5, 0)
  2692. p = stats.genextreme.ppf(.5, 0)
  2693. p = stats.genextreme.logpdf(-np.inf, 0.0)
  2694. number_of_warnings_thrown = len(w)
  2695. assert_equal(number_of_warnings_thrown, 0)
  2696. def test_genextreme_entropy():
  2697. # regression test for gh-5181
  2698. euler_gamma = 0.5772156649015329
  2699. h = stats.genextreme.entropy(-1.0)
  2700. assert_allclose(h, 2*euler_gamma + 1, rtol=1e-14)
  2701. h = stats.genextreme.entropy(0)
  2702. assert_allclose(h, euler_gamma + 1, rtol=1e-14)
  2703. h = stats.genextreme.entropy(1.0)
  2704. assert_equal(h, 1)
  2705. h = stats.genextreme.entropy(-2.0, scale=10)
  2706. assert_allclose(h, euler_gamma*3 + np.log(10) + 1, rtol=1e-14)
  2707. h = stats.genextreme.entropy(10)
  2708. assert_allclose(h, -9*euler_gamma + 1, rtol=1e-14)
  2709. h = stats.genextreme.entropy(-10)
  2710. assert_allclose(h, 11*euler_gamma + 1, rtol=1e-14)
  2711. def test_genextreme_sf_isf():
  2712. # Expected values were computed using mpmath:
  2713. #
  2714. # import mpmath
  2715. #
  2716. # def mp_genextreme_sf(x, xi, mu=0, sigma=1):
  2717. # # Formula from wikipedia, which has a sign convention for xi that
  2718. # # is the opposite of scipy's shape parameter.
  2719. # if xi != 0:
  2720. # t = mpmath.power(1 + ((x - mu)/sigma)*xi, -1/xi)
  2721. # else:
  2722. # t = mpmath.exp(-(x - mu)/sigma)
  2723. # return 1 - mpmath.exp(-t)
  2724. #
  2725. # >>> mpmath.mp.dps = 1000
  2726. # >>> s = mp_genextreme_sf(mpmath.mp.mpf("1e8"), mpmath.mp.mpf("0.125"))
  2727. # >>> float(s)
  2728. # 1.6777205262585625e-57
  2729. # >>> s = mp_genextreme_sf(mpmath.mp.mpf("7.98"), mpmath.mp.mpf("-0.125"))
  2730. # >>> float(s)
  2731. # 1.52587890625e-21
  2732. # >>> s = mp_genextreme_sf(mpmath.mp.mpf("7.98"), mpmath.mp.mpf("0"))
  2733. # >>> float(s)
  2734. # 0.00034218086528426593
  2735. x = 1e8
  2736. s = stats.genextreme.sf(x, -0.125)
  2737. assert_allclose(s, 1.6777205262585625e-57)
  2738. x2 = stats.genextreme.isf(s, -0.125)
  2739. assert_allclose(x2, x)
  2740. x = 7.98
  2741. s = stats.genextreme.sf(x, 0.125)
  2742. assert_allclose(s, 1.52587890625e-21)
  2743. x2 = stats.genextreme.isf(s, 0.125)
  2744. assert_allclose(x2, x)
  2745. x = 7.98
  2746. s = stats.genextreme.sf(x, 0)
  2747. assert_allclose(s, 0.00034218086528426593)
  2748. x2 = stats.genextreme.isf(s, 0)
  2749. assert_allclose(x2, x)
  2750. def test_burr12_ppf_small_arg():
  2751. prob = 1e-16
  2752. quantile = stats.burr12.ppf(prob, 2, 3)
  2753. # The expected quantile was computed using mpmath:
  2754. # >>> import mpmath
  2755. # >>> mpmath.mp.dps = 100
  2756. # >>> prob = mpmath.mpf('1e-16')
  2757. # >>> c = mpmath.mpf(2)
  2758. # >>> d = mpmath.mpf(3)
  2759. # >>> float(((1-prob)**(-1/d) - 1)**(1/c))
  2760. # 5.7735026918962575e-09
  2761. assert_allclose(quantile, 5.7735026918962575e-09)
  2762. def test_crystalball_function():
  2763. """
  2764. All values are calculated using the independent implementation of the
  2765. ROOT framework (see https://root.cern.ch/).
  2766. Corresponding ROOT code is given in the comments.
  2767. """
  2768. X = np.linspace(-5.0, 5.0, 21)[:-1]
  2769. # for(float x = -5.0; x < 5.0; x+=0.5)
  2770. # std::cout << ROOT::Math::crystalball_pdf(x, 1.0, 2.0, 1.0) << ", ";
  2771. calculated = stats.crystalball.pdf(X, beta=1.0, m=2.0)
  2772. expected = np.array([0.0202867, 0.0241428, 0.0292128, 0.0360652, 0.045645,
  2773. 0.059618, 0.0811467, 0.116851, 0.18258, 0.265652,
  2774. 0.301023, 0.265652, 0.18258, 0.097728, 0.0407391,
  2775. 0.013226, 0.00334407, 0.000658486, 0.000100982,
  2776. 1.20606e-05])
  2777. assert_allclose(expected, calculated, rtol=0.001)
  2778. # for(float x = -5.0; x < 5.0; x+=0.5)
  2779. # std::cout << ROOT::Math::crystalball_pdf(x, 2.0, 3.0, 1.0) << ", ";
  2780. calculated = stats.crystalball.pdf(X, beta=2.0, m=3.0)
  2781. expected = np.array([0.0019648, 0.00279754, 0.00417592, 0.00663121,
  2782. 0.0114587, 0.0223803, 0.0530497, 0.12726, 0.237752,
  2783. 0.345928, 0.391987, 0.345928, 0.237752, 0.12726,
  2784. 0.0530497, 0.0172227, 0.00435458, 0.000857469,
  2785. 0.000131497, 1.57051e-05])
  2786. assert_allclose(expected, calculated, rtol=0.001)
  2787. # for(float x = -5.0; x < 5.0; x+=0.5) {
  2788. # std::cout << ROOT::Math::crystalball_pdf(x, 2.0, 3.0, 2.0, 0.5);
  2789. # std::cout << ", ";
  2790. # }
  2791. calculated = stats.crystalball.pdf(X, beta=2.0, m=3.0, loc=0.5, scale=2.0)
  2792. expected = np.array([0.00785921, 0.0111902, 0.0167037, 0.0265249,
  2793. 0.0423866, 0.0636298, 0.0897324, 0.118876, 0.147944,
  2794. 0.172964, 0.189964, 0.195994, 0.189964, 0.172964,
  2795. 0.147944, 0.118876, 0.0897324, 0.0636298, 0.0423866,
  2796. 0.0265249])
  2797. assert_allclose(expected, calculated, rtol=0.001)
  2798. # for(float x = -5.0; x < 5.0; x+=0.5)
  2799. # std::cout << ROOT::Math::crystalball_cdf(x, 1.0, 2.0, 1.0) << ", ";
  2800. calculated = stats.crystalball.cdf(X, beta=1.0, m=2.0)
  2801. expected = np.array([0.12172, 0.132785, 0.146064, 0.162293, 0.18258,
  2802. 0.208663, 0.24344, 0.292128, 0.36516, 0.478254,
  2803. 0.622723, 0.767192, 0.880286, 0.94959, 0.982834,
  2804. 0.995314, 0.998981, 0.999824, 0.999976, 0.999997])
  2805. assert_allclose(expected, calculated, rtol=0.001)
  2806. # for(float x = -5.0; x < 5.0; x+=0.5)
  2807. # std::cout << ROOT::Math::crystalball_cdf(x, 2.0, 3.0, 1.0) << ", ";
  2808. calculated = stats.crystalball.cdf(X, beta=2.0, m=3.0)
  2809. expected = np.array([0.00442081, 0.00559509, 0.00730787, 0.00994682,
  2810. 0.0143234, 0.0223803, 0.0397873, 0.0830763, 0.173323,
  2811. 0.320592, 0.508717, 0.696841, 0.844111, 0.934357,
  2812. 0.977646, 0.993899, 0.998674, 0.999771, 0.999969,
  2813. 0.999997])
  2814. assert_allclose(expected, calculated, rtol=0.001)
  2815. # for(float x = -5.0; x < 5.0; x+=0.5) {
  2816. # std::cout << ROOT::Math::crystalball_cdf(x, 2.0, 3.0, 2.0, 0.5);
  2817. # std::cout << ", ";
  2818. # }
  2819. calculated = stats.crystalball.cdf(X, beta=2.0, m=3.0, loc=0.5, scale=2.0)
  2820. expected = np.array([0.0176832, 0.0223803, 0.0292315, 0.0397873, 0.0567945,
  2821. 0.0830763, 0.121242, 0.173323, 0.24011, 0.320592,
  2822. 0.411731, 0.508717, 0.605702, 0.696841, 0.777324,
  2823. 0.844111, 0.896192, 0.934357, 0.960639, 0.977646])
  2824. assert_allclose(expected, calculated, rtol=0.001)
  2825. def test_crystalball_function_moments():
  2826. """
  2827. All values are calculated using the pdf formula and the integrate function
  2828. of Mathematica
  2829. """
  2830. # The Last two (alpha, n) pairs test the special case n == alpha**2
  2831. beta = np.array([2.0, 1.0, 3.0, 2.0, 3.0])
  2832. m = np.array([3.0, 3.0, 2.0, 4.0, 9.0])
  2833. # The distribution should be correctly normalised
  2834. expected_0th_moment = np.array([1.0, 1.0, 1.0, 1.0, 1.0])
  2835. calculated_0th_moment = stats.crystalball._munp(0, beta, m)
  2836. assert_allclose(expected_0th_moment, calculated_0th_moment, rtol=0.001)
  2837. # calculated using wolframalpha.com
  2838. # e.g. for beta = 2 and m = 3 we calculate the norm like this:
  2839. # integrate exp(-x^2/2) from -2 to infinity +
  2840. # integrate (3/2)^3*exp(-2^2/2)*(3/2-2-x)^(-3) from -infinity to -2
  2841. norm = np.array([2.5511, 3.01873, 2.51065, 2.53983, 2.507410455])
  2842. a = np.array([-0.21992, -3.03265, np.inf, -0.135335, -0.003174])
  2843. expected_1th_moment = a / norm
  2844. calculated_1th_moment = stats.crystalball._munp(1, beta, m)
  2845. assert_allclose(expected_1th_moment, calculated_1th_moment, rtol=0.001)
  2846. a = np.array([np.inf, np.inf, np.inf, 3.2616, 2.519908])
  2847. expected_2th_moment = a / norm
  2848. calculated_2th_moment = stats.crystalball._munp(2, beta, m)
  2849. assert_allclose(expected_2th_moment, calculated_2th_moment, rtol=0.001)
  2850. a = np.array([np.inf, np.inf, np.inf, np.inf, -0.0577668])
  2851. expected_3th_moment = a / norm
  2852. calculated_3th_moment = stats.crystalball._munp(3, beta, m)
  2853. assert_allclose(expected_3th_moment, calculated_3th_moment, rtol=0.001)
  2854. a = np.array([np.inf, np.inf, np.inf, np.inf, 7.78468])
  2855. expected_4th_moment = a / norm
  2856. calculated_4th_moment = stats.crystalball._munp(4, beta, m)
  2857. assert_allclose(expected_4th_moment, calculated_4th_moment, rtol=0.001)
  2858. a = np.array([np.inf, np.inf, np.inf, np.inf, -1.31086])
  2859. expected_5th_moment = a / norm
  2860. calculated_5th_moment = stats.crystalball._munp(5, beta, m)
  2861. assert_allclose(expected_5th_moment, calculated_5th_moment, rtol=0.001)
  2862. def test_argus_function():
  2863. # There is no usable reference implementation.
  2864. # (RootFit implementation returns unreasonable results which are not
  2865. # normalized correctly.)
  2866. # Instead we do some tests if the distribution behaves as expected for
  2867. # different shapes and scales.
  2868. for i in range(1, 10):
  2869. for j in range(1, 10):
  2870. assert_equal(stats.argus.pdf(i + 0.001, chi=j, scale=i), 0.0)
  2871. assert_(stats.argus.pdf(i - 0.001, chi=j, scale=i) > 0.0)
  2872. assert_equal(stats.argus.pdf(-0.001, chi=j, scale=i), 0.0)
  2873. assert_(stats.argus.pdf(+0.001, chi=j, scale=i) > 0.0)
  2874. for i in range(1, 10):
  2875. assert_equal(stats.argus.cdf(1.0, chi=i), 1.0)
  2876. assert_equal(stats.argus.cdf(1.0, chi=i),
  2877. 1.0 - stats.argus.sf(1.0, chi=i))
  2878. class TestHistogram(object):
  2879. def setup_method(self):
  2880. np.random.seed(1234)
  2881. # We have 8 bins
  2882. # [1,2), [2,3), [3,4), [4,5), [5,6), [6,7), [7,8), [8,9)
  2883. # But actually np.histogram will put the last 9 also in the [8,9) bin!
  2884. # Therefore there is a slight difference below for the last bin, from
  2885. # what you might have expected.
  2886. histogram = np.histogram([1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5,
  2887. 6, 6, 6, 6, 7, 7, 7, 8, 8, 9], bins=8)
  2888. self.template = stats.rv_histogram(histogram)
  2889. data = stats.norm.rvs(loc=1.0, scale=2.5, size=10000, random_state=123)
  2890. norm_histogram = np.histogram(data, bins=50)
  2891. self.norm_template = stats.rv_histogram(norm_histogram)
  2892. def test_pdf(self):
  2893. values = np.array([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5,
  2894. 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5])
  2895. pdf_values = np.asarray([0.0/25.0, 0.0/25.0, 1.0/25.0, 1.0/25.0,
  2896. 2.0/25.0, 2.0/25.0, 3.0/25.0, 3.0/25.0,
  2897. 4.0/25.0, 4.0/25.0, 5.0/25.0, 5.0/25.0,
  2898. 4.0/25.0, 4.0/25.0, 3.0/25.0, 3.0/25.0,
  2899. 3.0/25.0, 3.0/25.0, 0.0/25.0, 0.0/25.0])
  2900. assert_allclose(self.template.pdf(values), pdf_values)
  2901. # Test explicitly the corner cases:
  2902. # As stated above the pdf in the bin [8,9) is greater than
  2903. # one would naively expect because np.histogram putted the 9
  2904. # into the [8,9) bin.
  2905. assert_almost_equal(self.template.pdf(8.0), 3.0/25.0)
  2906. assert_almost_equal(self.template.pdf(8.5), 3.0/25.0)
  2907. # 9 is outside our defined bins [8,9) hence the pdf is already 0
  2908. # for a continuous distribution this is fine, because a single value
  2909. # does not have a finite probability!
  2910. assert_almost_equal(self.template.pdf(9.0), 0.0/25.0)
  2911. assert_almost_equal(self.template.pdf(10.0), 0.0/25.0)
  2912. x = np.linspace(-2, 2, 10)
  2913. assert_allclose(self.norm_template.pdf(x),
  2914. stats.norm.pdf(x, loc=1.0, scale=2.5), rtol=0.1)
  2915. def test_cdf_ppf(self):
  2916. values = np.array([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5,
  2917. 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5])
  2918. cdf_values = np.asarray([0.0/25.0, 0.0/25.0, 0.0/25.0, 0.5/25.0,
  2919. 1.0/25.0, 2.0/25.0, 3.0/25.0, 4.5/25.0,
  2920. 6.0/25.0, 8.0/25.0, 10.0/25.0, 12.5/25.0,
  2921. 15.0/25.0, 17.0/25.0, 19.0/25.0, 20.5/25.0,
  2922. 22.0/25.0, 23.5/25.0, 25.0/25.0, 25.0/25.0])
  2923. assert_allclose(self.template.cdf(values), cdf_values)
  2924. # First three and last two values in cdf_value are not unique
  2925. assert_allclose(self.template.ppf(cdf_values[2:-1]), values[2:-1])
  2926. # Test of cdf and ppf are inverse functions
  2927. x = np.linspace(1.0, 9.0, 100)
  2928. assert_allclose(self.template.ppf(self.template.cdf(x)), x)
  2929. x = np.linspace(0.0, 1.0, 100)
  2930. assert_allclose(self.template.cdf(self.template.ppf(x)), x)
  2931. x = np.linspace(-2, 2, 10)
  2932. assert_allclose(self.norm_template.cdf(x),
  2933. stats.norm.cdf(x, loc=1.0, scale=2.5), rtol=0.1)
  2934. def test_rvs(self):
  2935. N = 10000
  2936. sample = self.template.rvs(size=N, random_state=123)
  2937. assert_equal(np.sum(sample < 1.0), 0.0)
  2938. assert_allclose(np.sum(sample <= 2.0), 1.0/25.0 * N, rtol=0.2)
  2939. assert_allclose(np.sum(sample <= 2.5), 2.0/25.0 * N, rtol=0.2)
  2940. assert_allclose(np.sum(sample <= 3.0), 3.0/25.0 * N, rtol=0.1)
  2941. assert_allclose(np.sum(sample <= 3.5), 4.5/25.0 * N, rtol=0.1)
  2942. assert_allclose(np.sum(sample <= 4.0), 6.0/25.0 * N, rtol=0.1)
  2943. assert_allclose(np.sum(sample <= 4.5), 8.0/25.0 * N, rtol=0.1)
  2944. assert_allclose(np.sum(sample <= 5.0), 10.0/25.0 * N, rtol=0.05)
  2945. assert_allclose(np.sum(sample <= 5.5), 12.5/25.0 * N, rtol=0.05)
  2946. assert_allclose(np.sum(sample <= 6.0), 15.0/25.0 * N, rtol=0.05)
  2947. assert_allclose(np.sum(sample <= 6.5), 17.0/25.0 * N, rtol=0.05)
  2948. assert_allclose(np.sum(sample <= 7.0), 19.0/25.0 * N, rtol=0.05)
  2949. assert_allclose(np.sum(sample <= 7.5), 20.5/25.0 * N, rtol=0.05)
  2950. assert_allclose(np.sum(sample <= 8.0), 22.0/25.0 * N, rtol=0.05)
  2951. assert_allclose(np.sum(sample <= 8.5), 23.5/25.0 * N, rtol=0.05)
  2952. assert_allclose(np.sum(sample <= 9.0), 25.0/25.0 * N, rtol=0.05)
  2953. assert_allclose(np.sum(sample <= 9.0), 25.0/25.0 * N, rtol=0.05)
  2954. assert_equal(np.sum(sample > 9.0), 0.0)
  2955. def test_munp(self):
  2956. for n in range(4):
  2957. assert_allclose(self.norm_template._munp(n),
  2958. stats.norm._munp(n, 1.0, 2.5), rtol=0.05)
  2959. def test_entropy(self):
  2960. assert_allclose(self.norm_template.entropy(),
  2961. stats.norm.entropy(loc=1.0, scale=2.5), rtol=0.05)