L i0|ddlZddlZddlZddlZddlZddlmZddl m Z m Z m Z m Z mZmZmZmZddlmZddlmcmZddlmZddlmZmZddlmZmZdd lm Z dd l!m"Z"m#Z#dd l$m%Z%m&Z&m'Z'dd l(m)Z)dd l*m+Z+gdZ,ejZdej\zZ/ejZdZ0ejZej\Z1ejdZ3dZ4dZ5ddZ6ddZ7GddZ8GddZ9GddZ:dZ;dZe;ee4dZ@Gdd e9ZAeAZBGd!d"e:ZCd#D]dZDeAjeDZFeCjeDZGejeFje@eG_IejeFje?eF_Ifd$ZJd%ZKdZLdZMeJeKe4d&ZNeLeMe4d&ZOGd'd(e9ZPePZQGd)d*e:ZRd+D]dZDePjeDZFeRjeDZGejeFjeOeG_IejeFjeNeF_Ifd,ZSdZTdZUeSe4d-ZVeTe4d-ZWd.ZXd/ZYd0ZZGd1d2e9Z[e[Z\Gd3d4e:Z]d5D]dZDe[jeDZFe]jeDZGejeFjeWeG_IejeFjeVeF_Ifd6Z^dZ_dZ`dZae^e_e4d7Zbe`eae4d7ZcGd8d9e9ZdedZeGd:d;e:ZfdedZgegZhGd?d@e:ZidAD]dZDegjeDZFefjeDZGejeFjeceG_IejeFjebeF_IfdBZjdCZkdZldZmejeke4d7Zneleme4d7ZoGdDdEe9ZpepZqGdFdGe:ZrdHD]dZDepjeDZFerjeDZGejeFjeoeG_IejeFjeneF_IfGdIdJe9ZsesZtGdKdLe:ZuGdMdNe9ZvevZwGdOdPe:ZxGdQdRe9ZyeyZzGdSdTe:Z{GdUdVe9Z|e|Z}GdWdXe:Z~dYZdZZdZeee4d[Zdee4d[ZGd\d]e9ZGd^d_e:ZeZd`D]dZDejeDZFejeDZGejeFjeeG_IejeFjeeF_IfdaZdbZdZdZeee4d7Zeee4d7ZGdcdde9ZeZGdedfe:ZdgD]dZDejeDZFejeDZGejeFjeeG_IejeFjeeF_IfGdhdie9ZeZGdjdke:ZdlZdmZdnZdoeZdZe4eeeedpZej3Zej7ddedqddrZeeedsD]=ZDejeDZFejeDZGeeGeeFjeeFe?Gdtdue9ZeZGdvdwe:ZdxZdyZdZdZee4dzZee4dzZdd{ZGd|d}e9ZeZGd~de:ZdD]dZDejeDZFejeDZGejeFjeeG_IejeFjeeF_IfGdde9ZeZGdde:ZGdde9ZeZGdde:ZdD]dZDejeDZFejeDZGejeFje@eG_IejeFje?eF_Ify)N)doccer)gammalnpsi multigammalnxlogyentrbetalniveloggamma)special)check_random_state)drotget_blas_funcs)norminvgamma)binom) _covariance_rcont)_qmvt_qmvn_qauto)directional_stats) root_scalar)multivariate_normal matrix_normal dirichletdirichlet_multinomialwishart invwishart multinomialspecial_ortho_group ortho_grouprandom_correlation unitary_groupmultivariate_tmultivariate_hypergeom random_tableuniform_directionvonmises_fishernormal_inverse_gammaaseed : {None, int, np.random.RandomState, np.random.Generator}, optional Used for drawing random variates. If `seed` is `None`, the `~np.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with seed. If `seed` is already a ``RandomState`` or ``Generator`` instance, then that object is used. Default is `None`. cN|j}|jdk(r|d}|S)z_ Remove single-dimensional entries from array and convert to scalar, if necessary. r)squeezendimouts _/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/scipy/stats/_multivariate.py_squeeze_outputr4;s( ++-C xx1}"g Jc||}|dvrN|jjj}ddd}||tj|j z}|tj t|z}|S)aDetermine which eigenvalues are "small" given the spectrum. This is for compatibility across various linear algebra functions that should agree about whether or not a Hermitian matrix is numerically singular and what is its numerical matrix rank. This is designed to be compatible with scipy.linalg.pinvh. Parameters ---------- spectrum : 1d ndarray Array of eigenvalues of a Hermitian matrix. cond, rcond : float, optional Cutoff for small eigenvalues. Singular values smaller than rcond * largest_eigenvalue are considered zero. If None or -1, suitable machine precision is used. Returns ------- eps : float Magnitude cutoff for numerical negligibility. )N@@g.A)fd)dtypecharlowernpfinfoepsmaxabs)spectrumcondrcondtfactorr@s r3_eigvalsh_to_epsrHFso0  z NN   % % '%ay288A;??* H & &C Jr5ctj|Dcgc]}t||krdnd|z c}tScc}w)aA helper function for computing the pseudoinverse. Parameters ---------- v : iterable of numbers This may be thought of as a vector of eigenvalues or singular values. eps : float Values with magnitude no greater than eps are considered negligible. Returns ------- v_pinv : 1d float ndarray A vector of pseudo-inverted numbers. rrr;)r>arrayrBfloat)vr@xs r3_pinv_1drOhs6 88!asarray_MscipylinalgeighrHmin ValueErrorlen LinAlgErrorrOmultiplysqrtr@VrankUsumloglog_pdet_pinv)selfMrDrEr=rTallow_singularsur@msgr:s_pinvrbs r3__init__z _PSD.__init__s**Q- ||  %l K1q$. 66!9t MCS/ ! a#gJ q6CF?>2C))'', ,!S! KK2776? +s71a3h;F rvvay)  r5ctjj||jzd}||jk}|S)zJ Check whether x lies in the support of the distribution. r7axis)r>rXrr`r@)rgrNresidual in_supports r3 _support_maskz_PSD._support_masks699>>!dff*2>6( r5c|j9tj|j|jj|_|jSN)rfr>dotrbTrgs r3pinvz _PSD.pinvs4 :: 1DJzzr5)NNTTT)__name__ __module__ __qualname____doc__rnrtpropertyrzr.r5r3rQrQ{s/%N8<37Br5rQc^eZdZdZdfd ZedZejdZdZxZ S)multi_rv_genericzc Class which encapsulates common functionality between all multivariate distributions. cBt|t||_yrv)superrnr _random_statergseed __class__s r3rnzmulti_rv_generic.__init__s /5r5c|jS)a Get or set the Generator object for generating random variates. If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. )rrys r3 random_statezmulti_rv_generic.random_states!!!r5c$t||_yrvr rrgrs r3rzmulti_rv_generic.random_states/5r5c4| t|S|jSrvrrgrs r3_get_random_statez"multi_rv_generic._get_random_states  #%l3 3%% %r5rv) r{r|r}r~rnrrsetterr __classcell__rs@r3rrs@6 " "66&r5rcDeZdZdZedZej dZy)multi_rv_frozenzj Class which encapsulates common functionality between all frozen multivariate distributions. c.|jjSrv)_distrrys r3rzmulti_rv_frozen.random_stateszz'''r5c8t||j_yrv)r rrrs r3rzmulti_rv_frozen.random_states#5d#;  r5N)r{r|r}r~rrrr.r5r3rrs5((<See class definition for a detailed description of parameters.)_mvn_doc_default_callparams_mvn_doc_callparams_note_doc_random_stateceZdZdZdfd ZddZddZdZdZdZ d Z dd Z dd Z d Z dddd dZ dddd dZddZddZddZxZS)multivariate_normal_gena{A multivariate normal random variable. The `mean` keyword specifies the mean. The `cov` keyword specifies the covariance matrix. Methods ------- pdf(x, mean=None, cov=1, allow_singular=False) Probability density function. logpdf(x, mean=None, cov=1, allow_singular=False) Log of the probability density function. cdf(x, mean=None, cov=1, allow_singular=False, maxpts=1000000*dim, abseps=1e-5, releps=1e-5, lower_limit=None) Cumulative distribution function. logcdf(x, mean=None, cov=1, allow_singular=False, maxpts=1000000*dim, abseps=1e-5, releps=1e-5) Log of the cumulative distribution function. rvs(mean=None, cov=1, size=1, random_state=None) Draw random samples from a multivariate normal distribution. entropy(mean=None, cov=1) Compute the differential entropy of the multivariate normal. fit(x, fix_mean=None, fix_cov=None) Fit a multivariate normal distribution to data. Parameters ---------- %(_mvn_doc_default_callparams)s %(_doc_random_state)s Notes ----- %(_mvn_doc_callparams_note)s The covariance matrix `cov` may be an instance of a subclass of `Covariance`, e.g. `scipy.stats.CovViaPrecision`. If so, `allow_singular` is ignored. Otherwise, `cov` must be a symmetric positive semidefinite matrix when `allow_singular` is True; it must be (strictly) positive definite when `allow_singular` is False. Symmetry is not checked; only the lower triangular portion is used. The determinant and inverse of `cov` are computed as the pseudo-determinant and pseudo-inverse, respectively, so that `cov` does not need to have full rank. The probability density function for `multivariate_normal` is .. math:: f(x) = \frac{1}{\sqrt{(2 \pi)^k \det \Sigma}} \exp\left( -\frac{1}{2} (x - \mu)^T \Sigma^{-1} (x - \mu) \right), where :math:`\mu` is the mean, :math:`\Sigma` the covariance matrix, :math:`k` the rank of :math:`\Sigma`. In case of singular :math:`\Sigma`, SciPy extends this definition according to [1]_. .. versionadded:: 0.14.0 References ---------- .. [1] Multivariate Normal Distribution - Degenerate Case, Wikipedia, https://en.wikipedia.org/wiki/Multivariate_normal_distribution#Degenerate_case Examples -------- >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from scipy.stats import multivariate_normal >>> x = np.linspace(0, 5, 10, endpoint=False) >>> y = multivariate_normal.pdf(x, mean=2.5, cov=0.5); y array([ 0.00108914, 0.01033349, 0.05946514, 0.20755375, 0.43939129, 0.56418958, 0.43939129, 0.20755375, 0.05946514, 0.01033349]) >>> fig1 = plt.figure() >>> ax = fig1.add_subplot(111) >>> ax.plot(x, y) >>> plt.show() Alternatively, the object may be called (as a function) to fix the mean and covariance parameters, returning a "frozen" multivariate normal random variable: >>> rv = multivariate_normal(mean=None, cov=1, allow_singular=False) >>> # Frozen object with the same methods but holding the given >>> # mean and covariance fixed. The input quantiles can be any shape of array, as long as the last axis labels the components. This allows us for instance to display the frozen pdf for a non-isotropic random variable in 2D as follows: >>> x, y = np.mgrid[-1:1:.01, -1:1:.01] >>> pos = np.dstack((x, y)) >>> rv = multivariate_normal([0.5, -0.2], [[2.0, 0.3], [0.3, 0.5]]) >>> fig2 = plt.figure() >>> ax2 = fig2.add_subplot(111) >>> ax2.contourf(x, y, rv.pdf(pos)) Ncvt||tj|jt |_yrv)rrnr docformatr~mvn_docdict_paramsrs r3rnz multivariate_normal_gen.__init__) '' 6HI r5c "t||f||d|S)zzCreate a frozen multivariate normal distribution. See `multivariate_normal_frozen` for more information. )rir)multivariate_normal_frozen)rgmeancovrirkwdss r3__call__z multivariate_normal_gen.__call__s( *$=9G/3=7;= =r5ct|tjr|j||S|j d||\}}}t ||}tj |}|||fS)z Infer dimensionality from mean or covariance matrix, ensure that mean and covariance are full vector resp. matrix. Nri) isinstancer Covariance_process_parameters_Covariance_process_parameters_psdrQ CovViaPSD)rgrrridimpsd cov_objects r3_process_parametersz+multivariate_normal_gen._process_parameterssn c;11 266tSA A"99$cJNCss>:C$..s3Jj( (r5c|jd}|tjdgn|}d|d|f} tj||}|||fS#t$r}t ||d}~wwxYw)Nr7z(`cov` represents a covariance matrix in z9 dimensions,and so `mean` must be broadcastable to shape )shaper>rK broadcast_tor[)rgrrrmessagees r3rz6multivariate_normal_gen._process_parameters_Covariancesiim!%rxx~4=cUCCDG6(L -??4-DD#~ -W%1 , -sA A) A$$A)c`|l|B|d}ntj|t}|jdkrd}nX|jd}nHtj|t}|j }n tj |s td|tj|}tj|t}|d}tj|t}|dk(r#|jd}|jdd}|jdk7s|jd|k7rtd|d|jdk(r|tj|z}n|jdk(rtj|}n|jdk(rp|j||fk7r_|j\}}||k7r$d t|jd}t|d |jd t|d}t||jdkDrtd |j|||fS) NrrJr,rz.Dimension of random variable must be a scalar.?z(Array 'mean' must be a vector of length .EArray 'cov' must be square if it is two dimensional, but cov.shape = z,Dimension mismatch: array 'cov' is of shape z#, but 'mean' is a vector of length rUrLr0rsizeisscalarr[zerosreshapeeyediagstrr\)rgrrrrowscolsrls r3rz/multivariate_normal_gen._process_parameters_psds ;|;C**S6Cxx!|!iilzz$e4ii;;s# "-.. <88C=Dzz$e, ;CjjE* !8<<?D++a#C 99>TZZ]c1GuANO O 88q=s #C XX]''#,C XX]syyS#J6JD$t|++.syy>*:!= S/ !Fcii[Q;;>t9+QHS/ ! XX\ //2xxj:; ;D#~r5c tj|t}|jdk(r|tj}|S|jdk(r5|dk(r|ddtjf}|S|tjddf}|Sl Adjust quantiles array so that last axis labels the components of each data point. rJrrNr>rUrLr0newaxisrgrNrs r3_process_quantilesz*multivariate_normal_gen._process_quantilessy JJq & 66Q;"** A VVq[axam$bjj!m$r5cD|j|j}}||z }|jdkDr*|dtjf}|dtjf}tj tj |j|d}d|tz|z|zzS)aLog of the multivariate normal probability density function. Parameters ---------- x : ndarray Points at which to evaluate the log of the probability density function mean : ndarray Mean of the distribution cov_object : Covariance An object representing the Covariance matrix Notes ----- As this function does no argument checking, it should not be called directly; use 'logpdf' instead. r.r7rp) rerar0r>rrcsquarewhiten_LOG_2PI)rgrNrr log_det_covradevmahas r3_logpdfzmultivariate_normal_gen._logpdfs&'//T $h 88a<%c2::o6KRZZ(Dvvbii 1 1# 67bAth4t;<anyrartinfr4 rgrNrrriparamsrrr2 out_of_boundss r3logpdfzmultivariate_normal_gen.logpdfs&))$^D &T:  # #As +ll1dJ/ 66*//C' ('55af==M"$&&C s##r5c2|j|||}|\}}}|j||}tj|j |||}tj |j |kr|j||z } d|| <t|S)aMultivariate normal probability density function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. %(_mvn_doc_default_callparams)s Returns ------- pdf : ndarray or scalar Probability density function evaluated at `x` Notes ----- %(_mvn_doc_callparams_note)s r) rrr>exprrrartr4rs r3pdfzmultivariate_normal_gen.pdf9s&))$^D &T:  # #As +ffT\\!T:67 66*//C' ('55af==M!$C s##r5c |/tj|jtj n|} tj|| \} } | |z | |z } } | | k} d| j dz} | j | j } } | | | | c| | <| | <|jdtj| | fd}fd}tj|d|| z}t|S)aMultivariate normal cumulative distribution function. Parameters ---------- x : ndarray Points at which to evaluate the cumulative distribution function. mean : ndarray Mean of the distribution cov : array_like Covariance matrix of the distribution maxpts : integer The maximum number of points to use for integration abseps : float Absolute error tolerance releps : float Relative error tolerance lower_limit : array_like, optional Lower limit of integration of the cumulative distribution function. Default is negative infinity. Must be broadcastable with `x`. rng : Generator an instance of ``np.random.Generator``, which is used internally for QMC integration. Notes ----- As this function does no argument checking, it should not be called directly; use 'cdf' instead. .. versionadded:: 1.0.0 r7rpc ntt|d|dd}tj|dS)N )errorlimit n_batchesr)rrr>r/)limitsresabsepsrmaxptsnrngs r3func1dz,multivariate_normal_gen._cdf..func1ds>VBQZF&BHC::c!f% %r5) r>fullrrbroadcast_arraysrccopy concatenateapply_along_axisr4)rgrNrrrrreleps lower_limitrr=bai_swapsignsrrr2rs ``` ` @r3_cdfzmultivariate_normal_gen._cdfUsD 'bffW--8  ""1e,14xT1Qvzzrz*+vvx1 y!F)& 1V9 GGBKAR0 & & !!&"f5=s##r5rrc <|j|||} | \} }} | j}|j|| }|sd| z}|j| } |j |||||||| } t j | dkr| dzn| } t j| }|S)aoLog of the multivariate normal cumulative distribution function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. %(_mvn_doc_default_callparams)s maxpts : integer, optional The maximum number of points to use for integration (default ``1000000*dim``) abseps : float, optional Absolute error tolerance (default 1e-5) releps : float, optional Relative error tolerance (default 1e-5) lower_limit : array_like, optional Lower limit of integration of the cumulative distribution function. Default is negative infinity. Must be broadcastable with `x`. rng : Generator, optional an instance of ``np.random.Generator``, which is used internally for QMC integration. Returns ------- cdf : ndarray or scalar Log of the cumulative distribution function evaluated at `x` Notes ----- %(_mvn_doc_callparams_note)s .. versionadded:: 1.0.0 @Br)r covariancerrrr>rrd)rgrNrrrirrrrrrrrcdfr2s r3logcdfzmultivariate_normal_gen.logcdfsF))$^D &T:##  # #As +s]F$$S)ii4fffk3O&&q/cBhsffSk r5c |j|||} | \} }} | j}|j|| }|sd| z}|j| } |j |||||||| } | S)aYMultivariate normal cumulative distribution function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. %(_mvn_doc_default_callparams)s maxpts : integer, optional The maximum number of points to use for integration (default ``1000000*dim``) abseps : float, optional Absolute error tolerance (default 1e-5) releps : float, optional Relative error tolerance (default 1e-5) lower_limit : array_like, optional Lower limit of integration of the cumulative distribution function. Default is negative infinity. Must be broadcastable with `x`. rng : Generator, optional an instance of ``np.random.Generator``, which is used internally for QMC integration. Returns ------- cdf : ndarray or scalar Cumulative distribution function evaluated at `x` Notes ----- %(_mvn_doc_callparams_note)s .. versionadded:: 1.0.0 r)rrrrr)rgrNrrrirrrrrrrrr2s r3rzmultivariate_normal_gen.cdfsF))$^D &T:##  # #As +s]F$$S)ii4fffk3O r5c|j||\}}}|j|}t|tjr,|j }|j |||}t|}|S|xs t}tj|s|f}t||jdfz}|j|} ||j| z}|S)aDraw random samples from a multivariate normal distribution. Parameters ---------- %(_mvn_doc_default_callparams)s size : integer, optional Number of samples to draw (default 1). %(_doc_random_state)s Returns ------- rvs : ndarray or scalar Random variates of size (`size`, `N`), where `N` is the dimension of the random variable. Notes ----- %(_mvn_doc_callparams_note)s r7r)rrrrrrrr4tupler>iterablernormalcolorize) rgrrrrrrr2rrNs r3rvszmultivariate_normal_gen.rvss*!% 8 8s CT:--l; j+"7"7 8''C224dCC!#&C ?57D;;t$w$K:#3#3B#7"99E###/A,,Q//C r5cz|j||\}}}d|jtdzz|jzzS)aGCompute the differential entropy of the multivariate normal. Parameters ---------- %(_mvn_doc_default_callparams)s Returns ------- h : scalar Entropy of the multivariate normal distribution Notes ----- %(_mvn_doc_callparams_note)s ?r)rrarre)rgrrrrs r3entropyzmultivariate_normal_gen.entropys@"!% 8 8s CT:jooA69L9LLMMr5chtj|}|jdk7r td|j\}}|5tj |}|j|fk7r d}t||}n|j d}|tj|}|j||fk7r d}t|tjj|dd\}} t|} tj|| kr d }t||} || fS||z } | j| z|z } || fS) a%Fit a multivariate normal distribution to data. Parameters ---------- x : ndarray (m, n) Data the distribution is fitted to. Must have two axes. The first axis of length `m` represents the number of vectors the distribution is fitted to. The second axis of length `n` determines the dimensionality of the fitted distribution. fix_mean : ndarray(n, ) Fixed mean vector. Must have length `n`. fix_cov: ndarray (n, n) Fixed covariance matrix. Must have shape ``(n, n)``. Returns ------- mean : ndarray (n, ) Maximum likelihood estimate of the mean vector cov : ndarray (n, n) Maximum likelihood estimate of the covariance matrix r,z`x` must be two-dimensional.zd`fix_mean` must be a one-dimensional array the same length as the dimensionality of the vectors `x`.rrpzn`fix_cov` must be a two-dimensional square array of same side length as the dimensionality of the vectors `x`.TrSz2`fix_cov` must be symmetric positive semidefinite.)r>rUr0r[r atleast_1dr atleast_2drWrXrYrHrZrx) rgrNfix_meanfix_cov n_vectorsrrlrrjrkr@r centered_datas r3fitzmultivariate_normal_gen.fit(s;0 JJqM 66Q;;< < 3  }}X.H~~#(J o%D66q6>D  mmG,G}}c *&!o%<<$$WDt$LDAq"1%CvvayC4J o%CSyHM//M1I=CSyr5rv)NrFN)T)NrF)NrFNh㈵>rNrrNNrNN)r{r|r}r~rnrrrrrrrrrrrrr rrrs@r3rr's`DJ=)0 5n"=6$8$89$vHL#'08<$0dEI $+59t+Z#JN(?r5rc^eZdZ d dZedZdZdZddddZddddZ d d Z d Z y) rNct||_|jj|||\|_|_|_|xs|j j |_|sd|jz}||_||_ ||_ y)ahCreate a frozen multivariate normal distribution. Parameters ---------- mean : array_like, default: ``[0]`` Mean of the distribution. cov : array_like, default: ``[1]`` Symmetric positive (semi)definite covariance matrix of the distribution. allow_singular : bool, default: ``False`` Whether to allow a singular covariance matrix. seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. maxpts : integer, optional The maximum number of points to use for integration of the cumulative distribution function (default ``1000000*dim``) abseps : float, optional Absolute error tolerance for the cumulative distribution function (default 1e-5) releps : float, optional Relative error tolerance for the cumulative distribution function (default 1e-5) Examples -------- When called with the default parameters, this will create a 1D random variable with mean 0 and covariance 1: >>> from scipy.stats import multivariate_normal >>> r = multivariate_normal() >>> r.mean array([ 0.]) >>> r.cov array([[1.]]) rN) rrrrrr_allow_singularrirrr)rgrrrirrrrs r3rnz#multivariate_normal_frozen.__init__nsuV-T2 JJ * *4n E -$)T_,O0O0Otxx'F   r5c.|jjSrv)rrrys r3rzmultivariate_normal_frozen.covs)))r5c|jj||j}|jj||j|j }t j|j j|jkr=|j j||jz }t j ||<t|Srv) rrrrrrr>rrartrr4)rgrNr2rs r3rz!multivariate_normal_frozen.logpdfs JJ ) )!TXX 6jj  DIIt? 66$//&&1 2!__::1TYY;GGM"$&&C s##r5cJtj|j|Srvr>rrrgrNs r3rzmultivariate_normal_frozen.pdfvvdkk!n%%r5rc|j|||}tj|dkr|dzn|}tj|}|S)Nrrr)rr>rrd)rgrNrrrr2s r3rz!multivariate_normal_frozen.logcdfsChhqksh;&&q/cBhsffSk r5c V|jj||j}|jj|}|jj ||j |j j|j|j|j||}t|Srv) rrrrrrrrrrrr4)rgrNrrr2s r3rzmultivariate_normal_frozen.cdfs{ JJ ) )!TXX 6jj**3/jjooaDOO,F,F"kk4;; )30s##r5cf|jj|j|j||Srv)rrrrrgrrs r3rzmultivariate_normal_frozen.rvss#zz~~dii$ MMr5c~|jj}|jj}d|tdzz|zzS)zComputes the differential entropy of the multivariate normal. Returns ------- h : scalar Entropy of the multivariate normal distribution r r)rrerar)rgreras r3r z"multivariate_normal_frozen.entropys;??++##dhl+h677r5)NrFNNrrrN) r{r|r}rnrrrrrrrr r.r5r3rrmsODH263j**$&(,%)d$N 8r5r)rrrrramean : array_like, optional Mean of the distribution (default: `None`) rowcov : array_like, optional Among-row covariance matrix of the distribution (default: ``1``) colcov : array_like, optional Among-column covariance matrix of the distribution (default: ``1``) aIf `mean` is set to `None` then a matrix of zeros is used for the mean. The dimensions of this matrix are inferred from the shape of `rowcov` and `colcov`, if these are provided, or set to ``1`` if ambiguous. `rowcov` and `colcov` can be two-dimensional array_likes specifying the covariance matrices directly. Alternatively, a one-dimensional array will be be interpreted as the entries of a diagonal matrix, and a scalar or zero-dimensional array will be interpreted as this value times the identity matrix. )_matnorm_doc_default_callparams_matnorm_doc_callparams_notercdeZdZdZd fd Zd dZdZdZdZddZ ddZ dd Z dd Z d Z xZS)matrix_normal_genaT A matrix normal random variable. The `mean` keyword specifies the mean. The `rowcov` keyword specifies the among-row covariance matrix. The 'colcov' keyword specifies the among-column covariance matrix. Methods ------- pdf(X, mean=None, rowcov=1, colcov=1) Probability density function. logpdf(X, mean=None, rowcov=1, colcov=1) Log of the probability density function. rvs(mean=None, rowcov=1, colcov=1, size=1, random_state=None) Draw random samples. entropy(rowcol=1, colcov=1) Differential entropy. Parameters ---------- %(_matnorm_doc_default_callparams)s %(_doc_random_state)s Notes ----- %(_matnorm_doc_callparams_note)s The covariance matrices specified by `rowcov` and `colcov` must be (symmetric) positive definite. If the samples in `X` are :math:`m \times n`, then `rowcov` must be :math:`m \times m` and `colcov` must be :math:`n \times n`. `mean` must be the same shape as `X`. The probability density function for `matrix_normal` is .. math:: f(X) = (2 \pi)^{-\frac{mn}{2}}|U|^{-\frac{n}{2}} |V|^{-\frac{m}{2}} \exp\left( -\frac{1}{2} \mathrm{Tr}\left[ U^{-1} (X-M) V^{-1} (X-M)^T \right] \right), where :math:`M` is the mean, :math:`U` the among-row covariance matrix, :math:`V` the among-column covariance matrix. The `allow_singular` behaviour of the `multivariate_normal` distribution is not currently supported. Covariance matrices must be full rank. The `matrix_normal` distribution is closely related to the `multivariate_normal` distribution. Specifically, :math:`\mathrm{Vec}(X)` (the vector formed by concatenating the columns of :math:`X`) has a multivariate normal distribution with mean :math:`\mathrm{Vec}(M)` and covariance :math:`V \otimes U` (where :math:`\otimes` is the Kronecker product). Sampling and pdf evaluation are :math:`\mathcal{O}(m^3 + n^3 + m^2 n + m n^2)` for the matrix normal, but :math:`\mathcal{O}(m^3 n^3)` for the equivalent multivariate normal, making this equivalent form algorithmically inefficient. .. versionadded:: 0.17.0 Examples -------- >>> import numpy as np >>> from scipy.stats import matrix_normal >>> M = np.arange(6).reshape(3,2); M array([[0, 1], [2, 3], [4, 5]]) >>> U = np.diag([1,2,3]); U array([[1, 0, 0], [0, 2, 0], [0, 0, 3]]) >>> V = 0.3*np.identity(2); V array([[ 0.3, 0. ], [ 0. , 0.3]]) >>> X = M + 0.1; X array([[ 0.1, 1.1], [ 2.1, 3.1], [ 4.1, 5.1]]) >>> matrix_normal.pdf(X, mean=M, rowcov=U, colcov=V) 0.023410202050005054 >>> # Equivalent multivariate normal >>> from scipy.stats import multivariate_normal >>> vectorised_X = X.T.flatten() >>> equiv_mean = M.T.flatten() >>> equiv_cov = np.kron(V,U) >>> multivariate_normal.pdf(vectorised_X, mean=equiv_mean, cov=equiv_cov) 0.023410202050005054 Alternatively, the object may be called (as a function) to fix the mean and covariance parameters, returning a "frozen" matrix normal random variable: >>> rv = matrix_normal(mean=None, rowcov=1, colcov=1) >>> # Frozen object with the same methods but holding the given >>> # mean and covariance fixed. cvt||tj|jt |_yrv)rrnrrr~matnorm_docdict_paramsrs r3rnzmatrix_normal_gen.__init__h) '' 6LM r5c t||||S)zoCreate a frozen matrix normal distribution. See `matrix_normal_frozen` for more information. r)matrix_normal_frozenrgrrowcovcolcovrs r3rzmatrix_normal_gen.__call__ls $D&&tDDr5c|ctj|t}|j}t |dk7r t dtj |dk(r t dtj|t}|jdk(r7||tjdz}n=|tjdz}n$|jdk(rtj|}|j}t |dk7r t d|d|dk7r t d|ddk(r t d |d}tj|t}|jdk(r7||tjdz}n=|tjdz}n$|jdk(rtj|}|j}t |dk7r t d |d|dk7r t d |ddk(r t d |d}|&d|k7r t d |d|k7r"t dtj||f}||f} | |||fS)z Infer dimensionality from mean or covariance matrices. Handle defaults. Ensure compatible dimensions. rJr,z%Array `mean` must be two dimensional.rzArray `mean` has invalid shape.rz(`rowcov` must be a scalar or a 2D array.zArray `rowcov` must be square.z!Array `rowcov` has invalid shape.z(`colcov` must be a scalar or a 2D array.zArray `colcov` must be square.z!Array `colcov` has invalid shape.z=Arrays `mean` and `rowcov` must have the same number of rows.z@Arrays `mean` and `colcov` must have the same number of columns.) r>rUrLrr\r[rr0identityrr) rgrr2r3 meanshaperowshapenumrowscolshapenumcolsdimss r3rz%matrix_normal_gen._process_parameterstsQ  ::d%0D I9~" !HIIvvi1n% !BCCF%0 ;;! "++il";;"++a.0 [[A WWV_F<< x=A GH H A;(1+ %=> > A;! @A A1+F%0 ;;! "++il";;"++a.0 [[A WWV_F<< x=A GH H A;(1+ %=> > A;! @A A1+  |w& "899|w& ";<<88Wg./D!T66))r5ctj|t}|jdk(r|tjddf}|j dd|k7r t d|S)zp Adjust quantiles array so that last two axes labels the components of each data point. rJr,NzJThe shape of array `X` is not compatible with the distribution parameters.)r>rUrLr0rrr[)rgXr;s r3rz$matrix_normal_gen._process_quantiless] JJq & 66Q;"**a- A 7723<4 AB Br5cd|\}} tj||z dd} tj|jtj| |d} tj tj tj | dd} d|| ztz| |zz||zz| zzS)aLog of the matrix normal probability density function. Parameters ---------- dims : tuple Dimensions of the matrix variates X : ndarray Points at which to evaluate the log of the probability density function mean : ndarray Mean of the distribution row_prec_rt : ndarray A decomposition such that np.dot(row_prec_rt, row_prec_rt.T) is the inverse of the among-row covariance matrix log_det_rowcov : float Logarithm of the determinant of the among-row covariance matrix col_prec_rt : ndarray A decomposition such that np.dot(col_prec_rt, col_prec_rt.T) is the inverse of the among-column covariance matrix log_det_colcov : float Logarithm of the determinant of the among-column covariance matrix Notes ----- As this function does no argument checking, it should not be called directly; use 'logpdf' instead. r7rrrpr)r>moveaxis tensordotrxrwrcrr) rgr;r>r row_prec_rtlog_det_rowcov col_prec_rtlog_det_colcovr8r:roll_dev scale_devrs r3rzmatrix_normal_gen._logpdfs< ;;qvr1-LL!#+!>C vvbffRYYy1;!Dwwx/'.2HH /02678 8r5c |j|||\}}}}|j||}t|d}t|d}|j||||j|j |j|j }t |S)aLog of the matrix normal probability density function. Parameters ---------- X : array_like Quantiles, with the last two axes of `X` denoting the components. %(_matnorm_doc_default_callparams)s Returns ------- logpdf : ndarray Log of the probability density function evaluated at `X` Notes ----- %(_matnorm_doc_callparams_note)s Fr)rrrQrrbrer4) rgr>rr2r3r;rowpsdcolpsdr2s r3rzmatrix_normal_gen.logpdfs&&*%=%=dF>D&F"dFF  # #At ,fU3fU3ll4D&((FOOVXX!??,s##r5cPtj|j||||S)aMatrix normal probability density function. Parameters ---------- X : array_like Quantiles, with the last two axes of `X` denoting the components. %(_matnorm_doc_default_callparams)s Returns ------- pdf : ndarray Probability density function evaluated at `X` Notes ----- %(_matnorm_doc_callparams_note)s r)rgr>rr2r3s r3rzmatrix_normal_gen.pdfs"&vvdkk!T66:;;r5ct|}|j|||\}}}}tjj |d}tjj |d}|j |}|j |d||dfjddd} |tjd|| |dz} |dk(r| j|j} | S) aDraw random samples from a matrix normal distribution. Parameters ---------- %(_matnorm_doc_default_callparams)s size : integer, optional Number of samples to draw (default 1). %(_doc_random_state)s Returns ------- rvs : ndarray or scalar Random variates of size (`size`, `dims`), where `dims` is the dimension of the random matrices. Notes ----- %(_matnorm_doc_callparams_note)s Tr=rrrr,zjp,ipq,kq->ijk)optimize) intrrWrXcholeskyrstandard_normal transposer>einsumrr) rgrr2r3rrr;rowcholcolcholstd_normr2s r3rzmatrix_normal_gen.rvss*4y%)%=%=dF>D&F"dFF,,''d';,,''d';--l;  //q'4a)0 )Aq!  RYY/&'(,.. 19++djj)C r5ctj|jd|jdf}|j|||\}}}}t |d}t |d}|j ||j |j S)aLog of the matrix normal probability density function. Parameters ---------- rowcov : array_like, optional Among-row covariance matrix of the distribution (default: ``1``) colcov : array_like, optional Among-column covariance matrix of the distribution (default: ``1``) Returns ------- entropy : float Entropy of the distribution Notes ----- %(_matnorm_doc_callparams_note)s rFr)r>rrrrQ_entropyre)rgr2r3 dummy_meanr;_rIrJs r3r zmatrix_normal_gen.entropyCs~(XXv||A Q@A "&":"::;A;A#CafU3fU3}}T6??FOODDr5cT|\}}d|z|zdtzzd|z|zzd|z|zzSNr r)r)rgr;row_cov_logdetcol_cov_logdetrps r3rXzmatrix_normal_gen._entropy`sC1a! q8|,sQw/GGa.() *r5rvrNrrNrrrNrr)r{r|r}r~rnrrrrrrrr rXrrs@r3r*r*sCbHNE@*D $8L$8<*'RE:*r5r*c2eZdZdZddZdZdZd dZdZy) r0a Create a frozen matrix normal distribution. Parameters ---------- %(_matnorm_doc_default_callparams)s seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is `None` the `~np.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with seed. If `seed` is already a ``RandomState`` or ``Generator`` instance, then that object is used. Default is `None`. Examples -------- >>> import numpy as np >>> from scipy.stats import matrix_normal >>> distn = matrix_normal(mean=np.zeros((3,3))) >>> X = distn.rvs(); X array([[-0.02976962, 0.93339138, -0.09663178], [ 0.67405524, 0.28250467, -0.93308929], [-0.31144782, 0.74535536, 1.30412916]]) >>> distn.pdf(X) 2.5160642368346784e-05 >>> distn.logpdf(X) -10.590229595124615 Nct||_|jj|||\|_|_|_|_t|j d|_t|j d|_ y)NFr) r*rrr;rr2r3rQrIrJr1s r3rnzmatrix_normal_frozen.__init__s]&t, JJ * *4 @ 7 49dk4;4;;u= 4;;u= r5c n|jj||j}|jj|j||j|j j |j j|jj |jj}t|Srv) rrr;rrrIrbrerJr4)rgr>r2s r3rzmatrix_normal_frozen.logpdfsy JJ ) )!TYY 7jj  Atyy$++--!%!5!5t{{}}!%!5!57s##r5cJtj|j|Srvr)rgr>s r3rzmatrix_normal_frozen.pdfr r5c||jj|j|j|j||Srv)rrrr2r3r$s r3rzmatrix_normal_frozen.rvss.zz~~diidkk4*, ,r5c|jj|j|jj|j jSrv)rrXr;rIrerJrys r3r zmatrix_normal_frozen.entropys8zz""499dkk.B.B#';;#7#79 9r5rr&) r{r|r}r~rnrrrr r.r5r3r0r0is <>$&,9r5r0)rrrr zalpha : array_like The concentration parameters. The number of entries determines the dimensionality of the distribution. )!_dirichlet_doc_default_callparamsrctj|}tj|dkr td|jdk7rtd|j d|S)Nrz%All parameters must be greater than 0rzrUrZr[r0ralphas r3_dirichlet_check_parametersrms^ JJu E vve}@AA q**/++a9: : Lr5ctj|}|jddz|jdk7rE|jd|jdk7r&td|jd|jd|jd|jdk7rtjdtj |dz g}|j dk(rtj||}n2|j dk(rtj||f}n tdtj|dkr tdtj|dkDr td |dk(}|dk}|j|jk7r>tj||jd d j|j}tj||}tj |r td tjtj |dd z dkDjr#tdtj |dd|S)Nrrz|Vector 'x' must have either the same number of entries as, or one entry fewer than, parameter vector 'a', but alpha.shape = z and x.shape = rr,zUThe input must be one dimensional or a two dimensional matrix containing the entries.z8Each entry in 'x' must be greater than or equal to zero.z/Each entry in 'x' must be smaller or equal one.r7rpzJEach entry in 'x' must be greater than zero if its alpha is less than one.rg& .>zLThe input vector 'x' must lie within the normal simplex. but np.sum(x, 0) = )r>rUrr[rKrcr0appendvstackrZrArepeatr logical_andrBr)rlrNxkxeq0alphalt1chks r3_dirichlet_check_inputrws 1 AwwqzA~Q'AGGAJ%++a.,HDDIKK=Q**+''!56 6  wwqzU[[^# XXq266!Q<'( ) 77a< !R A WW\ 1b'"AJK K vvay1}$% % vvay1}JKK FD Hww%++99Xqwwr{<DDQWWM ..x (C vvc{34 4 rvva|c!"V+00288:q! ~QHI I Hr5c|tjt|ttj|z S)avInternal helper function to compute the log of the useful quotient. .. math:: B(\alpha) = \frac{\prod_{i=1}{K}\Gamma(\alpha_i)} {\Gamma\left(\sum_{i=1}^{K} \alpha_i \right)} Parameters ---------- %(_dirichlet_doc_default_callparams)s Returns ------- B : scalar Helper quotient, internal use only )r>rcrrks r3_lnBrys)$ 66'%. !GBFF5M$: ::r5c^eZdZdZd fd Zd dZdZdZdZdZ dZ d Z d Z d d Z xZS) dirichlet_gena A Dirichlet random variable. The ``alpha`` keyword specifies the concentration parameters of the distribution. .. versionadded:: 0.15.0 Methods ------- pdf(x, alpha) Probability density function. logpdf(x, alpha) Log of the probability density function. rvs(alpha, size=1, random_state=None) Draw random samples from a Dirichlet distribution. mean(alpha) The mean of the Dirichlet distribution var(alpha) The variance of the Dirichlet distribution cov(alpha) The covariance of the Dirichlet distribution entropy(alpha) Compute the differential entropy of the Dirichlet distribution. Parameters ---------- %(_dirichlet_doc_default_callparams)s %(_doc_random_state)s Notes ----- Each :math:`\alpha` entry must be positive. The distribution has only support on the simplex defined by .. math:: \sum_{i=1}^{K} x_i = 1 where :math:`0 < x_i < 1`. If the quantiles don't lie within the simplex, a ValueError is raised. The probability density function for `dirichlet` is .. math:: f(x) = \frac{1}{\mathrm{B}(\boldsymbol\alpha)} \prod_{i=1}^K x_i^{\alpha_i - 1} where .. math:: \mathrm{B}(\boldsymbol\alpha) = \frac{\prod_{i=1}^K \Gamma(\alpha_i)} {\Gamma\bigl(\sum_{i=1}^K \alpha_i\bigr)} and :math:`\boldsymbol\alpha=(\alpha_1,\ldots,\alpha_K)`, the concentration parameters and :math:`K` is the dimension of the space where :math:`x` takes values. Note that the `dirichlet` interface is somewhat inconsistent. The array returned by the rvs function is transposed with respect to the format expected by the pdf and logpdf. Examples -------- >>> import numpy as np >>> from scipy.stats import dirichlet Generate a dirichlet random variable >>> quantiles = np.array([0.2, 0.2, 0.6]) # specify quantiles >>> alpha = np.array([0.4, 5, 15]) # specify concentration parameters >>> dirichlet.pdf(quantiles, alpha) 0.2843831684937255 The same PDF but following a log scale >>> dirichlet.logpdf(quantiles, alpha) -1.2574327653159187 Once we specify the dirichlet distribution we can then calculate quantities of interest >>> dirichlet.mean(alpha) # get the mean of the distribution array([0.01960784, 0.24509804, 0.73529412]) >>> dirichlet.var(alpha) # get variance array([0.00089829, 0.00864603, 0.00909517]) >>> dirichlet.entropy(alpha) # calculate the differential entropy -4.3280162474082715 We can also return random samples from the distribution >>> dirichlet.rvs(alpha, size=1, random_state=1) array([[0.00766178, 0.24670518, 0.74563305]]) >>> dirichlet.rvs(alpha, size=2, random_state=2) array([[0.01639427, 0.1292273 , 0.85437844], [0.00156917, 0.19033695, 0.80809388]]) Alternatively, the object may be called (as a function) to fix concentration parameters, returning a "frozen" Dirichlet random variable: >>> rv = dirichlet(alpha) >>> # Frozen object with the same methods but holding the given >>> # concentration parameters fixed. cvt||tj|jt |_yrv)rrnrrr~dirichlet_docdict_paramsrs r3rnzdirichlet_gen.__init__ws) '' 6NO r5ct||SNr/)dirichlet_frozenrgrlrs r3rzdirichlet_gen.__call__{sD11r5ct|}| tjt|dz |jjdzS)aLog of the Dirichlet probability density function. Parameters ---------- x : ndarray Points at which to evaluate the log of the probability density function %(_dirichlet_doc_default_callparams)s Notes ----- As this function does no argument checking, it should not be called directly; use 'logpdf' instead. rr)ryr>rcrrx)rgrNrllnBs r3rzdirichlet_gen._logpdf~s: 5kurvvuUQY477;;;r5cjt|}t||}|j||}t|S)ayLog of the Dirichlet probability density function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. %(_dirichlet_doc_default_callparams)s Returns ------- pdf : ndarray or scalar Log of the probability density function evaluated at `x`. )rmrwrr4rgrNrlr2s r3rzdirichlet_gen.logpdfs5,E2 "5! ,ll1e$s##r5ct|}t||}tj|j ||}t |S)akThe Dirichlet probability density function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. %(_dirichlet_doc_default_callparams)s Returns ------- pdf : ndarray or scalar The probability density function evaluated at `x`. )rmrwr>rrr4rs r3rzdirichlet_gen.pdfs>,E2 "5! ,ffT\\!U+,s##r5c^t|}|tj|z }t|S)zMean of the Dirichlet distribution. Parameters ---------- %(_dirichlet_doc_default_callparams)s Returns ------- mu : ndarray or scalar Mean of the Dirichlet distribution. rmr>rcr4)rgrlr2s r3rzdirichlet_gen.means+,E2rvve}%s##r5ct|}tj|}|||z z||z|dzzz }t|S)zVariance of the Dirichlet distribution. Parameters ---------- %(_dirichlet_doc_default_callparams)s Returns ------- v : ndarray or scalar Variance of the Dirichlet distribution. rr)rgrlalpha0r2s r3varzdirichlet_gen.varsF,E2'Vf_!,LMs##r5ct|}tj|}||z }tj|tj||z |dzz }t |S)zCovariance matrix of the Dirichlet distribution. Parameters ---------- %(_dirichlet_doc_default_callparams)s Returns ------- cov : ndarray The covariance matrix of the distribution. r)rmr>rcrouterr4)rgrlrrrs r3rzdirichlet_gen.covsT,E2 FNwwqzBHHQN*vz:s##r5cNt|}tj|}t|}|jd}|||z t j j|zztj|dz t j j|zz }t|S)a Differential entropy of the Dirichlet distribution. Parameters ---------- %(_dirichlet_doc_default_callparams)s Returns ------- h : scalar Entropy of the Dirichlet distribution rr) rmr>rcryrrWr rr4)rgrlrrKr2s r3r zdirichlet_gen.entropys,E25k KKNVaZ5==#4#4V#<<r5r)rrrrrrr zdf : int Degrees of freedom, must be greater than or equal to dimension of the scale matrix scale : array_like Symmetric positive definite scale matrix of the distribution )_doc_default_callparams_doc_callparams_noterceZdZdZdfd ZddZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZddZdZdZdZxZS) wishart_genaqA Wishart random variable. The `df` keyword specifies the degrees of freedom. The `scale` keyword specifies the scale matrix, which must be symmetric and positive definite. In this context, the scale matrix is often interpreted in terms of a multivariate normal precision matrix (the inverse of the covariance matrix). These arguments must satisfy the relationship ``df > scale.ndim - 1``, but see notes on using the `rvs` method with ``df < scale.ndim``. Methods ------- pdf(x, df, scale) Probability density function. logpdf(x, df, scale) Log of the probability density function. rvs(df, scale, size=1, random_state=None) Draw random samples from a Wishart distribution. entropy() Compute the differential entropy of the Wishart distribution. Parameters ---------- %(_doc_default_callparams)s %(_doc_random_state)s Raises ------ scipy.linalg.LinAlgError If the scale matrix `scale` is not positive definite. See Also -------- invwishart, chi2 Notes ----- %(_doc_callparams_note)s The scale matrix `scale` must be a symmetric positive definite matrix. Singular matrices, including the symmetric positive semi-definite case, are not supported. Symmetry is not checked; only the lower triangular portion is used. The Wishart distribution is often denoted .. math:: W_p(\nu, \Sigma) where :math:`\nu` is the degrees of freedom and :math:`\Sigma` is the :math:`p \times p` scale matrix. The probability density function for `wishart` has support over positive definite matrices :math:`S`; if :math:`S \sim W_p(\nu, \Sigma)`, then its PDF is given by: .. math:: f(S) = \frac{|S|^{\frac{\nu - p - 1}{2}}}{2^{ \frac{\nu p}{2} } |\Sigma|^\frac{\nu}{2} \Gamma_p \left ( \frac{\nu}{2} \right )} \exp\left( -tr(\Sigma^{-1} S) / 2 \right) If :math:`S \sim W_p(\nu, \Sigma)` (Wishart) then :math:`S^{-1} \sim W_p^{-1}(\nu, \Sigma^{-1})` (inverse Wishart). If the scale matrix is 1-dimensional and equal to one, then the Wishart distribution :math:`W_1(\nu, 1)` collapses to the :math:`\chi^2(\nu)` distribution. The algorithm [2]_ implemented by the `rvs` method may produce numerically singular matrices with :math:`p - 1 < \nu < p`; the user may wish to check for this condition and generate replacement samples as necessary. .. versionadded:: 0.16.0 References ---------- .. [1] M.L. Eaton, "Multivariate Statistics: A Vector Space Approach", Wiley, 1983. .. [2] W.B. Smith and R.R. Hocking, "Algorithm AS 53: Wishart Variate Generator", Applied Statistics, vol. 21, pp. 341-345, 1972. Examples -------- >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from scipy.stats import wishart, chi2 >>> x = np.linspace(1e-5, 8, 100) >>> w = wishart.pdf(x, df=3, scale=1); w[:5] array([ 0.00126156, 0.10892176, 0.14793434, 0.17400548, 0.1929669 ]) >>> c = chi2.pdf(x, 3); c[:5] array([ 0.00126156, 0.10892176, 0.14793434, 0.17400548, 0.1929669 ]) >>> plt.plot(x, w) >>> plt.show() The input quantiles can be any shape of array, as long as the last axis labels the components. Alternatively, the object may be called (as a function) to fix the degrees of freedom and scale parameters, returning a "frozen" Wishart random variable: >>> rv = wishart(df=1, scale=1) >>> # Frozen object with the same methods but holding the given >>> # degrees of freedom and scale fixed. cvt||tj|jt |_yrvrrnrrr~wishart_docdict_paramsrs r3rnzwishart_gen.__init__r-r5ct|||S)zbCreate a frozen Wishart distribution. See `wishart_frozen` for more information. )wishart_frozenrgdfscalers r3rzwishart_gen.__call__s b%..r5cv|d}tj|t}|jdk(r$|tjtjf}n|jdk(rtj |}nw|jdk(rA|j d|j dk(s"tdt|j d|jdkDrtd|j|j d}||}n3tj|s td ||dz kr td |||fS) NrrJrrr,zIArray 'scale' must be square if it is two dimensional, but scale.scale = rz@Array 'scale' must be at most two-dimensional, but scale.ndim = z$Degrees of freedom must be a scalar.zNDegrees of freedom must be greater than the dimension of scale matrix minus 1.) r>rUrLr0rrrr[rr)rgrrrs r3rzwishart_gen._process_parameterss, =E 5. ::?"**bjj01E ZZ1_GGENE ZZ1_U[[^u{{1~%E336u{{3C2DAGH H ZZ!^ 116 >? ?kk!n :BRCD D 37]BC CB~r5ctj|t}|jdk(r0|tj|ddddtj fz}|jdk(r[|dk(r(|tj tj ddf}ntj |ddddtj f}n|jdk(r\|jd|jdk(s"tdt|jd|ddddtj f}nw|jdk(rA|jd|jdk(sItd t|jd|jdkDrtd |j|jdd||fk(s!td ||fd |jddd|S) rrJrNrr,zDQuantiles must be square if they are two dimensional, but x.shape = rzbQuantiles must be square in the first two dimensions if they are three dimensional, but x.shape = zmQuantiles must be at most two-dimensional with an additional dimension for multiple components, but x.ndim = z2Quantiles have incompatible dimensions: should be z, got ) r>rUrLr0rrrrr[rrs r3rzwishart_gen._process_quantiless JJq & 66Q;BFF3K1bjj 011A 66Q;axbjj"**a/0GGAJq!RZZ/0 VVq[771:+ &&)!''l^1677!Q "#A VVq[771:+ DDGL>QRTUUVVaZ --.VVH67 7 wwq|Sz)$%(#JrUr0rr[rrprod)rgrrrs r3 _process_sizezwishart_gen._process_size%syzz$ 99> #D YY]%%(t%5$689 9 IIKd %xr5chtj|jd}tj|j}tj|jd} t|jdD]v} |j |dddd| f\} || <t j j|df|dddd| f|dddd| f<|dddd| fj| | <xd||z dz z|zd| zz d|z|ztzd|z|zztd|z|zz } | S)aLog of the Wishart probability density function. Parameters ---------- x : ndarray Points at which to evaluate the log of the probability density function dim : int Dimension of the scale matrix df : int Degrees of freedom scale : ndarray Scale matrix log_det_scale : float Logarithm of the determinant of the scale matrix C : ndarray Cholesky factorization of the scale matrix, lower triangular. Notes ----- As this function does no argument checking, it should not be called directly; use 'logpdf' instead. r7NTr r) r>emptyrrange_cholesky_logdetrWrX cho_solvetrace_LOG_2r) rgrNrrr log_det_scaleC log_det_x scale_inv_xtr_scale_inv_xirZr2s r3rzwishart_gen._logpdf3s->HHQWWR[) hhqww' !''"+.qwwr{# =A"33AaAgJ?OAy|#(<<#9#91d)Qq!QwZ#PK1a +Aq!G 4 : : rrgrrrrrs r3_varzwishart_gen._vars<Qh~~ rxxd## r  r5cj|j||\}}}|j|||}t|S)zVariance of the Wishart distribution. Parameters ---------- %(_doc_default_callparams)s Returns ------- var : float The variance of the distribution rrr4rs r3rzwishart_gen.vars911"e<RiiR's##r5c <||dz zdz}|j||zj||fz}tjt |Dcgc]!}|j ||dzz dz|dz#c}j|f|dddzj } tj|||fz} ttdddgt|z} tj|d} || | | z<tj|} | | | | z<| Scc}w)ax Parameters ---------- n : integer Number of variates to generate shape : iterable Shape of the variates to generate dim : int Dimension of the scale matrix df : int Degrees of freedom random_state : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. Notes ----- As this function does no argument checking, it should not be called directly; use 'rvs' instead. rr,rr Nr7k) rrr>r_r chisquarerxrrslicer\ tril_indices diag_indices)rgrrrrrn_tril covariancesr variancesAsize_idxtril_idxdiag_idxs r3 _standard_rvszwishart_gen._standard_rvs s::A!#"))6*"75&?3 UU%*3Z1 !)222qs8A:A2FK1229'3&:?"+;F3GGHq  HHUc3Z' (%dD123u:=>??3"-!,(X ??3'!*(X !1s&Dc|j|}|j|||||}tj|D]>}tj|||} tj| | j ||<@|S)a]Draw random samples from a Wishart distribution. Parameters ---------- n : integer Number of variates to generate shape : iterable Shape of the variates to generate dim : int Dimension of the scale matrix df : int Degrees of freedom C : ndarray Cholesky factorization of the scale matrix, lower triangular. %(_doc_random_state)s Notes ----- As this function does no argument checking, it should not be called directly; use 'rvs' instead. )rrr>ndindexrwrx) rgrrrrrrrindexCAs r3_rvszwishart_gen._rvs6 s{.--l;    q%b, ?ZZ& (E1U8$Bvvb"$$'AeH (r5c|j|\}}|j||\}}}tjj |d}|j ||||||} t | S)aDraw random samples from a Wishart distribution. Parameters ---------- %(_doc_default_callparams)s size : integer or iterable of integers, optional Number of samples to draw (default 1). %(_doc_random_state)s Returns ------- rvs : ndarray Random variates of shape (`size`) + (``dim``, ``dim``), where ``dim`` is the dimension of the scale matrix. Notes ----- %(_doc_callparams_note)s TrMrrrWrXrPrr4 rgrrrrrrrrr2s r3rzwishart_gen.rvsc n*%%d+511"e<R LL ! !%t ! 4ii5#r1l;s##r5c d|dzz|zd|z|dzztzztd|z|zd||z dz ztjt |Dcgc]}t d|dz|dzz zc}zz d|z|zzScc}w)aCompute the differential entropy of the Wishart. Parameters ---------- dim : int Dimension of the scale matrix df : int Degrees of freedom log_det_scale : float Logarithm of the determinant of the scale matrix Notes ----- As this function does no argument checking, it should not be called directly; use 'entropy' instead. r r)rrr>rcrr)rgrrrrs r3rXzwishart_gen._entropy s& 3q5MM ) #IQ & ( ) R % & 28a< 26649#J?qS"q&AaC.)*?$   "HsN   @sB c||j||\}}}|j|\}}|j|||S)a'Compute the differential entropy of the Wishart. Parameters ---------- %(_doc_default_callparams)s Returns ------- h : scalar Entropy of the Wishart distribution Notes ----- %(_doc_callparams_note)s rrrXrgrrrrZrs r3r zwishart_gen.entropy sD"11"e<R007=}}S"m44r5ctjj|d}dtjtj |j z}||fS)aCompute Cholesky decomposition and determine (log(det(scale)). Parameters ---------- scale : ndarray Scale matrix. Returns ------- c_decomp : ndarray The Cholesky decomposition of `scale`. logdet : scalar The log of the determinant of `scale`. Notes ----- This computation of ``logdet`` is equivalent to ``np.linalg.slogdet(scale)``. It is ~2x faster though. TrMr,)rWrXrPr>rcrdr)rgrc_decomplogdets r3rzwishart_gen._cholesky_logdet sM*<<((d(;RVVBFF8#4#4#6788r5rvNNNr&)r{r|r}r~rnrrrrrrrrrrrrrrrrrXr rrrs@r3rristm^N/8#J ,\$:1,"$ *@&*$ 2h+Z$> 85* r5rcDeZdZdZd dZdZdZdZdZdZ d d Z d Z y) raXCreate a frozen Wishart distribution. Parameters ---------- df : array_like Degrees of freedom of the distribution scale : array_like Scale matrix of the distribution seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. Nct||_|jj||\|_|_|_|jj |j \|_|_yrv) rrrrrrrrrrs r3rnzwishart_frozen.__init__ sV & (, (F(F )%$'4:%)ZZ%@%@%L""r5c|jj||j}|jj||j|j|j |j |j}t|Srv) rrrrrrrrr4rgrNr2s r3rzwishart_frozen.logpdf s^ JJ ) )!TXX 6jj  DHHdggtzz!%!3!3TVV=s##r5cJtj|j|Srvrrs r3rzwishart_frozen.pdf r r5c|jj|j|j|j}t |Srvrrrrrr4rgr2s r3rzwishart_frozen.mean 1jjtxx$**=s##r5c|jj|j|j|j}| t |S|Srvrrrrrr4rs r3rzwishart_frozen.mode :jjtxx$**='*s#?C?r5c|jj|j|j|j}t |Srvrrrrrr4rs r3rzwishart_frozen.var s/jjoodhh<s##r5c|jj|\}}|jj|||j|j|j |}t |Srvrrrrrrr4rgrrrrr2s r3rzwishart_frozen.rvs sP::++D15jjooa$''"ffl4s##r5cx|jj|j|j|jSrvrrXrrrrys r3r zwishart_frozen.entropy )zz""488TWWd6H6HIIr5rvr&) r{r|r}r~rnrrrrrrr r.r5r3rr s2"M $&$@$$ Jr5r)rrrrrrr ceZdZdZdfd ZddZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZddZdZdZxZS)invwishart_genacAn inverse Wishart random variable. The `df` keyword specifies the degrees of freedom. The `scale` keyword specifies the scale matrix, which must be symmetric and positive definite. In this context, the scale matrix is often interpreted in terms of a multivariate normal covariance matrix. Methods ------- pdf(x, df, scale) Probability density function. logpdf(x, df, scale) Log of the probability density function. rvs(df, scale, size=1, random_state=None) Draw random samples from an inverse Wishart distribution. entropy(df, scale) Differential entropy of the distribution. Parameters ---------- %(_doc_default_callparams)s %(_doc_random_state)s Raises ------ scipy.linalg.LinAlgError If the scale matrix `scale` is not positive definite. See Also -------- wishart Notes ----- %(_doc_callparams_note)s The scale matrix `scale` must be a symmetric positive definite matrix. Singular matrices, including the symmetric positive semi-definite case, are not supported. Symmetry is not checked; only the lower triangular portion is used. The inverse Wishart distribution is often denoted .. math:: W_p^{-1}(\nu, \Psi) where :math:`\nu` is the degrees of freedom and :math:`\Psi` is the :math:`p \times p` scale matrix. The probability density function for `invwishart` has support over positive definite matrices :math:`S`; if :math:`S \sim W^{-1}_p(\nu, \Sigma)`, then its PDF is given by: .. math:: f(S) = \frac{|\Sigma|^\frac{\nu}{2}}{2^{ \frac{\nu p}{2} } |S|^{\frac{\nu + p + 1}{2}} \Gamma_p \left(\frac{\nu}{2} \right)} \exp\left( -tr(\Sigma S^{-1}) / 2 \right) If :math:`S \sim W_p^{-1}(\nu, \Psi)` (inverse Wishart) then :math:`S^{-1} \sim W_p(\nu, \Psi^{-1})` (Wishart). If the scale matrix is 1-dimensional and equal to one, then the inverse Wishart distribution :math:`W_1(\nu, 1)` collapses to the inverse Gamma distribution with parameters shape = :math:`\frac{\nu}{2}` and scale = :math:`\frac{1}{2}`. Instead of inverting a randomly generated Wishart matrix as described in [2], here the algorithm in [4] is used to directly generate a random inverse-Wishart matrix without inversion. .. versionadded:: 0.16.0 References ---------- .. [1] M.L. Eaton, "Multivariate Statistics: A Vector Space Approach", Wiley, 1983. .. [2] M.C. Jones, "Generating Inverse Wishart Matrices", Communications in Statistics - Simulation and Computation, vol. 14.2, pp.511-514, 1985. .. [3] Gupta, M. and Srivastava, S. "Parametric Bayesian Estimation of Differential Entropy and Relative Entropy". Entropy 12, 818 - 843. 2010. .. [4] S.D. Axen, "Efficiently generating inverse-Wishart matrices and their Cholesky factors", :arXiv:`2310.15884v1`. 2023. Examples -------- >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from scipy.stats import invwishart, invgamma >>> x = np.linspace(0.01, 1, 100) >>> iw = invwishart.pdf(x, df=6, scale=1) >>> iw[:3] array([ 1.20546865e-15, 5.42497807e-06, 4.45813929e-03]) >>> ig = invgamma.pdf(x, 6/2., scale=1./2) >>> ig[:3] array([ 1.20546865e-15, 5.42497807e-06, 4.45813929e-03]) >>> plt.plot(x, iw) >>> plt.show() The input quantiles can be any shape of array, as long as the last axis labels the components. Alternatively, the object may be called (as a function) to fix the degrees of freedom and scale parameters, returning a "frozen" inverse Wishart random variable: >>> rv = invwishart(df=1, scale=1) >>> # Frozen object with the same methods but holding the given >>> # degrees of freedom and scale fixed. cvt||tj|jt |_yrvrrs r3rnzinvwishart_gen.__init__ r-r5ct|||S)znCreate a frozen inverse Wishart distribution. See `invwishart_frozen` for more information. )invwishart_frozenrs r3rzinvwishart_gen.__call__ s !UD11r5cftj|jd}tj|jd}td|f}|dkDrqt |jdD]U} |j |dddd| f\} || <|d| |dd} tj j| d z|| <Wn,tj|d |dd|d d z|d z |ddd |z|zd |zz d |z|ztzd ||zdzz|zzz td |z|z } | S) aLog of the inverse Wishart probability density function. Parameters ---------- x : ndarray Points at which to evaluate the log of the probability density function. dim : int Dimension of the scale matrix df : int Degrees of freedom log_det_scale : float Logarithm of the determinant of the scale matrix C : ndarray Cholesky factorization of the scale matrix, lower triangular. Notes ----- As this function does no argument checking, it should not be called directly; use 'logpdf' instead. r7trsmrNrrTsider=r,rrr ) r>rrrrrrXrrdrr) rgrNrrrrrtr_scale_x_invrrCxrr2s r3rzinvwishart_gen._logpdf sE0HHQWWR[) !''"+.v- 71772;' 9#'#8#81a7#D IaLR$7$&IINN1$5q$8q! 9 66!D'?IaL !$ QtW 4N1 b=(3+??b3'#cA*>*JJLCFC() r5c|j||\}}}|j||}|j|\}}|j|||||}t |S)aLog of the inverse Wishart probability density function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. Each quantile must be a symmetric positive definite matrix. %(_doc_default_callparams)s Returns ------- pdf : ndarray Log of the probability density function evaluated at `x` Notes ----- %(_doc_callparams_note)s rrs r3rzinvwishart_gen.logpdf sd(11"e<R  # #As +007=ll1c2}a8s##r5cNtj|j|||S)aInverse Wishart probability density function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. Each quantile must be a symmetric positive definite matrix. %(_doc_default_callparams)s Returns ------- pdf : ndarray Probability density function evaluated at `x` Notes ----- %(_doc_callparams_note)s rrs r3rzinvwishart_gen.pdf rr5c4||dzkDr |||z dz z }|Sd}|S)aIMean of the inverse Wishart distribution. Parameters ---------- dim : int Dimension of the scale matrix %(_doc_default_callparams)s Notes ----- As this function does no argument checking, it should not be called directly; use 'mean' instead. rNr.rs r3rzinvwishart_gen._mean s4 a<28a<(C C r5cr|j||\}}}|j|||}| t|S|S)aXMean of the inverse Wishart distribution. Only valid if the degrees of freedom are greater than the dimension of the scale matrix plus one. Parameters ---------- %(_doc_default_callparams)s Returns ------- mean : float or None The mean of the distribution rrs r3rzinvwishart_gen.mean sB 11"e<Rjjb%('*s#?C?r5c|||zdzz S)aIMode of the inverse Wishart distribution. Parameters ---------- dim : int Dimension of the scale matrix %(_doc_default_callparams)s Notes ----- As this function does no argument checking, it should not be called directly; use 'mode' instead. rr.rs r3rzinvwishart_gen._mode sS1 %%r5cj|j||\}}}|j|||}t|S)zMode of the inverse Wishart distribution. Parameters ---------- %(_doc_default_callparams)s Returns ------- mode : float The Mode of the distribution rrs r3rzinvwishart_gen.mode' s911"e<Rjjb%(s##r5c||dzkDr_||z dz|dzz}|j}|||z dz tj||zz }|||z ||z dz dzz||z dz zz}|Sd}|S)aLVariance of the inverse Wishart distribution. Parameters ---------- dim : int Dimension of the scale matrix %(_doc_default_callparams)s Notes ----- As this function does no argument checking, it should not be called directly; use 'var' instead. rrr,Nrrs r3rzinvwishart_gen._var8 s a<8a<5!8+C>>#D BHqLBHHT4$88 8C BHcA 11R#X\B BC C r5cr|j||\}}}|j|||}| t|S|S)aXVariance of the inverse Wishart distribution. Only valid if the degrees of freedom are greater than the dimension of the scale matrix plus three. Parameters ---------- %(_doc_default_callparams)s Returns ------- var : float The variance of the distribution rrs r3rzinvwishart_gen.varP sB11"e<RiiR''*s#?C?r5c@tj|||fz}tj|d\}}||dz zdz} |jg|| |d||f<tj|} ||z dz| z} |j | g||dz|d| | f<|S) a Parameters ---------- n : integer Number of variates to generate shape : iterable Shape of the variates to generate dim : int Dimension of the scale matrix df : int Degrees of freedom random_state : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. Returns ------- A : ndarray Random variates of shape (`shape`) + (``dim``, ``dim``). Each slice `A[..., :, :]` is lower-triangular, and its inverse is the lower Cholesky factor of a draw from `invwishart(df, np.eye(dim))`. Notes ----- As this function does no argument checking, it should not be called directly; use 'rvs' instead. r7rrr,r.)rrr )r>rrraranger) rgrrrrrrtri_rowstri_colsrrchi_dfss r3_inv_standard_rvsz invwishart_gen._inv_standard_rvsc sH HHUc3Z' ( __SB7(A!#%1%8%8!5!&!&9& #x !" yy~8a<4')33]u]c]4 #tT/r5c P|j|}|j|||||}td|f}td|f} tj|j ddD]@} |dkDr"|d|| |dd} | d| | ddd || <*|d || d z d z|| d <B|S) afDraw random samples from an inverse Wishart distribution. Parameters ---------- n : integer Number of variates to generate shape : iterable Shape of the variates to generate dim : int Dimension of the scale matrix df : int Degrees of freedom C : ndarray Cholesky factorization of the scale matrix, lower triangular. %(_doc_random_state)s Notes ----- As this function does no argument checking, it should not be called directly; use 'rvs' instead. rtrmmNr=rrTr)rr=trans_arr,)rr!rr>rr) rgrrrrrrrrr#rrs r3rzinvwishart_gen._rvs s.--l;  " "1eS"l Cv-v-ZZ - ?EQw"ah>B$M%"#D'AeHTN":Q!>% ?r5c|j|\}}|j||\}}}tjj |d}|j ||||||} t | S)aDraw random samples from an inverse Wishart distribution. Parameters ---------- %(_doc_default_callparams)s size : integer or iterable of integers, optional Number of samples to draw (default 1). %(_doc_random_state)s Returns ------- rvs : ndarray Random variates of shape (`size`) + (``dim``, ``dim``), where ``dim`` is the dimension of the scale matrix. Notes ----- %(_doc_callparams_note)s TrMrrs r3rzinvwishart_gen.rvs rr5c&td|dzDcgc] }d||z |zz}}tj|}td|z|d|z|zzd|dzz|tz zzd||zdzzt ||j zz Scc}w)Nrr r1)rr>rUrrrrc)rgrrrrpsi_eval_pointss r3rXzinvwishart_gen._entropy s9>q#'9JKA3"s(Q,/KK**_5C"Hc*S3Y^; 37O}v5 67 28a< _ 5 9 9 ; << <LsBc||j||\}}}|j|\}}|j|||Srvrrs r3r zinvwishart_gen.entropy sB11"e<R007=}}S"m44r5rvrr&)r{r|r}r~rnrrrrrrrrrrr!rrrXr rrs@r3r r  s`qfN2)V$41,*@(&"$"0@&4l)V$><5r5r c@eZdZd dZdZdZdZdZdZd dZ d Z y) r Ncrt||_|jj||\|_|_|_t jj|j d|_ dtjtj|jjz|_y)aGCreate a frozen inverse Wishart distribution. Parameters ---------- df : array_like Degrees of freedom of the distribution scale : array_like Scale matrix of the distribution seed : {None, int, `numpy.random.Generator`}, optional If `seed` is None the `numpy.random.Generator` singleton is used. If `seed` is an int, a new ``Generator`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` instance then that instance is used. TrMr,N)r rrrrrrWrXrPrr>rcrdrrrs r3rnzinvwishart_frozen.__init__ s"$D) (, (F(F ) %$'4: &&tzz&>tvv/@(A!BBr5c|jj||j}|jj||j|j|j |j }t|Srv)rrrrrrrr4rs r3rzinvwishart_frozen.logpdf sX JJ ) )!TXX 6jj  DHHdgg!%!3!3TVV=s##r5cJtj|j|Srvrrs r3rzinvwishart_frozen.pdf r r5c|jj|j|j|j}| t |S|Srvrrs r3rzinvwishart_frozen.mean rr5c|jj|j|j|j}t |Srvrrs r3rzinvwishart_frozen.mode rr5c|jj|j|j|j}| t |S|Srvrrs r3rzinvwishart_frozen.var! s8jjoodhh<'*s#?C?r5c|jj|\}}|jj|||j|j|j |}t |Srvrrs r3rzinvwishart_frozen.rvs% sR::++D15jjooa$''"ffl4s##r5cx|jj|j|j|jSrvrrys r3r zinvwishart_frozen.entropy- rr5rvr&) r{r|r}rnrrrrrrr r.r5r3r r  s.C4$ &@$@$Jr5r )rrrrrrzsn : int Number of trials p : array_like Probability of a trial falling into each category; should sum to 1 a`n` should be a nonnegative integer. Each element of `p` should be in the interval :math:`[0,1]` and the elements should sum to 1. If they do not sum to 1, the last element of the `p` array is not used and is replaced with the remaining probability left over from the earlier elements. cjeZdZdZdfd ZddZdZdZdZdZ dZ d Z d Z d Z d Zdd ZxZS)multinomial_gena A multinomial random variable. Methods ------- pmf(x, n, p) Probability mass function. logpmf(x, n, p) Log of the probability mass function. rvs(n, p, size=1, random_state=None) Draw random samples from a multinomial distribution. entropy(n, p) Compute the entropy of the multinomial distribution. cov(n, p) Compute the covariance matrix of the multinomial distribution. Parameters ---------- %(_doc_default_callparams)s %(_doc_random_state)s Notes ----- %(_doc_callparams_note)s The probability mass function for `multinomial` is .. math:: f(x) = \frac{n!}{x_1! \cdots x_k!} p_1^{x_1} \cdots p_k^{x_k}, supported on :math:`x=(x_1, \ldots, x_k)` where each :math:`x_i` is a nonnegative integer and their sum is :math:`n`. .. versionadded:: 0.19.0 Examples -------- >>> from scipy.stats import multinomial >>> rv = multinomial(8, [0.3, 0.2, 0.5]) >>> rv.pmf([1, 3, 4]) 0.042000000000000072 The multinomial distribution for :math:`k=2` is identical to the corresponding binomial distribution (tiny numerical differences notwithstanding): >>> from scipy.stats import binom >>> multinomial.pmf([3, 4], n=7, p=[0.4, 0.6]) 0.29030399999999973 >>> binom.pmf(3, 7, 0.4) 0.29030400000000012 The functions ``pmf``, ``logpmf``, ``entropy``, and ``cov`` support broadcasting, under the convention that the vector parameters (``x`` and ``p``) are interpreted as if each row along the last axis is a single object. For instance: >>> multinomial.pmf([[3, 4], [3, 5]], n=[7, 8], p=[.3, .7]) array([0.2268945, 0.25412184]) Here, ``x.shape == (2, 2)``, ``n.shape == (2,)``, and ``p.shape == (2,)``, but following the rules mentioned above they behave as if the rows ``[3, 4]`` and ``[3, 5]`` in ``x`` and ``[.3, .7]`` in ``p`` were a single object, and as if we had ``x.shape = (2,)``, ``n.shape = (2,)``, and ``p.shape = ()``. To obtain the individual elements without broadcasting, we would do this: >>> multinomial.pmf([3, 4], n=7, p=[.3, .7]) 0.2268945 >>> multinomial.pmf([3, 5], 8, p=[.3, .7]) 0.25412184 This broadcasting also works for ``cov``, where the output objects are square matrices of size ``p.shape[-1]``. For example: >>> multinomial.cov([4, 5], [[.3, .7], [.4, .6]]) array([[[ 0.84, -0.84], [-0.84, 0.84]], [[ 1.2 , -1.2 ], [-1.2 , 1.2 ]]]) In this example, ``n.shape == (2,)`` and ``p.shape == (2, 2)``, and following the rules above, these broadcast as if ``p.shape == (2,)``. Thus the result should also be of shape ``(2,)``, but since each output is a :math:`2 \times 2` matrix, the result in fact has shape ``(2, 2, 2)``, where ``result[0]`` is equal to ``multinomial.cov(n=4, p=[.3, .7])`` and ``result[1]`` is equal to ``multinomial.cov(n=5, p=[.4, .6])``. Alternatively, the object may be called (as a function) to fix the `n` and `p` parameters, returning a "frozen" multinomial random variable: >>> rv = multinomial(n=7, p=[.3, .7]) >>> # Frozen object with the same methods but holding the given >>> # degrees of freedom and scale fixed. See also -------- scipy.stats.binom : The binomial distribution. numpy.random.Generator.multinomial : Sampling from the multinomial distribution. scipy.stats.multivariate_hypergeom : The multivariate hypergeometric distribution. cvt||tj|jt |_yrv)rrnrrr~multinomial_docdict_paramsrs r3rnzmultinomial_gen.__init__ s,    T\\+E F r5ct|||S)zjCreate a frozen multinomial distribution. See `multinomial_frozen` for more information. )multinomial_frozen)rgrr_rs r3rzmultinomial_gen.__call__ s "!Q--r5ctjtjtj|tjj dz}tj |tjd}d|dddfjdz }tjd |jdz |kD}||||df<tj|r"d |d }tj|td tj|dkd}|tj|d kDdz}tj |td}|dk}||||zfS)zReturns: n_, p_, npcond. n_ and p_ are arrays of the correct shape; npcond is a boolean array flagging values out of the domain. rTr;rr.Nr7rprz;Some rows of `p` do not sum to 1.0 within tolerance of eps=z. Currently, the last element of these rows is adjusted to compensate, but this condition will produce NaNs beginning in SciPy 1.18.0. Please ensure that rows of `p` sum to 1.0 to avoid futher disruption.r) stacklevelr)r>r? result_typerUfloat32r@rKfloat64rcrBrwarningswarn FutureWarningrO) rgrr_r@ p_adjusted i_adjustedrpcondnconds r3rz#multinomial_gen._process_parameters s1 hhr~~bjjmRZZ@AEEJ HHQbjjt 4!C"H+//r/22 VVA2./#5 &z2*b. 66*  <rUrOr0r[rrrrc)rgrNrr_xxrDs r3rz"multinomial_gen._process_quantiles s ZZ % 77a<23 3 77a<  ; ))+"o ! }A/0 0 vvbAgB' rAvB''rvvbr*a/04xr5ctj|}|jdk7r|||<|S|r|jdk(r|S||d<|S)Nr.r>rUr0rgresultrD bad_values r3 _checkresultzmultinomial_gen._checkresult sPF# 99>$F4L  {{a  #F3K r5ct|dztjt||t|dzz dzS)Nrr7rp)rr>rcrrgrNrr_s r3_logpmfzmultinomial_gen._logpmf s3qs|bffU1a[71Q3<%?bIIIr5c|j||\}}}|j|||\}}|j|||}|tj|j tj z}|j||tj }|tj|j tj z}|j||tjS)aLog of the Multinomial probability mass function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. %(_doc_default_callparams)s Returns ------- logpmf : ndarray or scalar Log of the probability mass function evaluated at `x` Notes ----- %(_doc_callparams_note)s rJ) rrrPr>rrbool_rMrnan) rgrNrr_npcondxcondrKxcond_npcond_s r3logpmfzmultinomial_gen.logpmf s$//15 1f**1a35aA&&,,bhh??""66BFF7;288EKKrxx@@  "&&99r5cNtj|j|||S)aMultinomial probability mass function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. %(_doc_default_callparams)s Returns ------- pmf : ndarray or scalar Probability density function evaluated at `x` Notes ----- %(_doc_callparams_note)s r>rrXrOs r3pmfzmultinomial_gen.pmf4 s $vvdkk!Q*++r5c|j||\}}}|dtjf|z}|j||tjS)zMean of the Multinomial distribution. Parameters ---------- %(_doc_default_callparams)s Returns ------- mean : float The mean of the distribution .)rr>rrMrS)rgrr_rTrKs r3rzmultinomial_gen.meanH sL//15 1f3 ?#A%  88r5cX|j||\}}}|dtjtjf}|tjd| |z}t |j dD]}|d||fxx||d|fzz cc<|j ||tjS)zCovariance matrix of the multinomial distribution. Parameters ---------- %(_doc_default_callparams)s Returns ------- cov : ndarray The covariance matrix of the distribution .z...j,...k->...jkr7)rr>rrSrrrMrS)rgrr_rTnnrKrs r3rzmultinomial_gen.covX s//15 1f sBJJ * +bii 2QB::qwwr{# -A 319 1S!V9 ,  -  88r5cj|j||\}}}tjdtj|dz}|tjt |dz}|t |dzz}|dtjf}t|j|j|jz dz}|xjd|zz c_ tjtj|||t |dzzdd|z f}|j||z|tjS)aCompute the entropy of the multinomial distribution. The entropy is computed using this expression: .. math:: f(x) = - \log n! - n\sum_{i=1}^k p_i \log p_i + \sum_{i=1}^k \sum_{x=0}^n \binom n x p_i^x(1-p_i)^{n-x} \log x! Parameters ---------- %(_doc_default_callparams)s Returns ------- h : scalar Entropy of the Multinomial distribution Notes ----- %(_doc_callparams_note)s rr7rp.)r)rr>rrArcrrrr0rrr[rMrS)rgrr_rTrNterm1new_axes_neededterm2s r3r zmultinomial_gen.entropyo s.//15 1f EE!BFF1IaK "&&ar** 1 c2::o affaff-6: 4''uyyAq)'!A#,6O!346  ??r5cv|j||\}}}|j|}|j|||S)aDraw random samples from a Multinomial distribution. Parameters ---------- %(_doc_default_callparams)s size : integer or iterable of integers, optional Number of samples to draw (default 1). %(_doc_random_state)s Returns ------- rvs : ndarray or scalar Random variates of shape (`size`, `len(p)`) Notes ----- %(_doc_callparams_note)s )rrr!)rgrr_rrrTs r3rzmultinomial_gen.rvs sA&//15 1f--l; ''1d33r5rvr)r{r|r}r~rnrrrrMrPrXr[rrr rrrs@r3r3r3Z sLfPG .#@. J:@,(9 9.%@N4r5r3c>eZdZdZd dZdZdZdZdZdZ d d Z y) r7aZCreate a frozen Multinomial distribution. Parameters ---------- n : int number of trials p: array_like probability of a trial falling into each category; should sum to 1 seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. Nct|_jj||\___fd}|j_y)NcJjjjfSrv)rr_rT)rr_rgs r3rz8multinomial_frozen.__init__.._process_parameters s664664;;. .r5)r3rrrr_rT)rgrr_rrs` r3rnzmultinomial_frozen.__init__ sE$T* &*jj&D&DQ&J#  /*= &r5cd|jj||j|jSrv)rrXrr_rs r3rXzmultinomial_frozen.logpmf #zz  DFFDFF33r5cd|jj||j|jSrv)rr[rr_rs r3r[zmultinomial_frozen.pmf !zz~~a00r5cb|jj|j|jSrv)rrrr_rys r3rzmultinomial_frozen.mean zztvvtvv..r5cb|jj|j|jSrv)rrrr_rys r3rzmultinomial_frozen.cov zz~~dffdff--r5cb|jj|j|jSrv)rr rr_rys r3r zmultinomial_frozen.entropy s!zz!!$&&$&&11r5cf|jj|j|j||Srv)rrrr_r$s r3rzmultinomial_frozen.rvs s#zz~~dffdffdLAAr5rvr&) r{r|r}r~rnrXr[rrr rr.r5r3r7r7 s+ =41/.2Br5r7)rXr[rrrc:eZdZdZdfd ZddZdZddZxZS) special_ortho_group_genaA Special Orthogonal matrix (SO(N)) random variable. Return a random rotation matrix, drawn from the Haar distribution (the only uniform distribution on SO(N)) with a determinant of +1. The `dim` keyword specifies the dimension N. Methods ------- rvs(dim=None, size=1, random_state=None) Draw random samples from SO(N). Parameters ---------- dim : scalar Dimension of matrices seed : {None, int, np.random.RandomState, np.random.Generator}, optional Used for drawing random variates. If `seed` is `None`, the `~np.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with seed. If `seed` is already a ``RandomState`` or ``Generator`` instance, then that object is used. Default is `None`. Notes ----- The ``rvs`` method returns a random rotation matrix drawn from the Haar distribution, the only uniform distribution on SO(N). The algorithm generates a Haar-distributed orthogonal matrix in O(N) using the ``rvs`` method of `ortho_group`, then adjusts the matrix to ensure that the determinant is +1. For a random rotation in three dimensions, see `scipy.spatial.transform.Rotation.random`. Examples -------- >>> import numpy as np >>> from scipy.stats import special_ortho_group >>> x = special_ortho_group.rvs(3) >>> np.dot(x, x.T) array([[ 1.00000000e+00, 1.13231364e-17, -2.86852790e-16], [ 1.13231364e-17, 1.00000000e+00, -1.46845020e-16], [ -2.86852790e-16, -1.46845020e-16, 1.00000000e+00]]) >>> import scipy.linalg >>> scipy.linalg.det(x) 1.0 This generates one random matrix from SO(3). It is orthogonal and has a determinant of 1. Alternatively, the object may be called (as a function) to fix the `dim` parameter, returning a "frozen" special_ortho_group random variable: >>> rv = special_ortho_group(5) >>> # Frozen object with the same methods but holding the >>> # dimension parameter fixed. See Also -------- ortho_group, scipy.spatial.transform.Rotation.random clt||tj|j|_yrvrrnrrr~rs r3rnz special_ortho_group_gen.__init__-& '' 5 r5ct||S)zlCreate a frozen SO(N) distribution. See `special_ortho_group_frozen` for more information. r/)special_ortho_group_frozenrgrrs r3rz special_ortho_group_gen.__call__1s *#D99r5cp|(tj|r|dks|t|k7r td|S)5Dimension N must be specified; it cannot be inferred.rzrDimension of rotation must be specified, and must be a scalar nonnegative integer.r>rrOr[rgrs r3rz+special_ortho_group_gen._process_parameters8s> ;bkk#.#'SCH_MN N r5c|j|}tj|||}tjj |}|r%|ddddfxx|dtj fzcc<|S)asDraw random samples from SO(N). Parameters ---------- dim : integer Dimension of rotation space (N). size : integer, optional Number of samples to draw (default 1). Returns ------- rvs : ndarray or scalar Random size N-dimensional matrices, dimension (size, dim, dim) .rN)rr#rr>rXdetr)rgrrrqdetss r3rzspecial_ortho_group_gen.rvs@sa --l; OOC| 4yy}}Q  c1aiLDbjj1 1Lr5rvrr& r{r|r}r~rnrrrrrs@r3rrrr s@D6:r5rrceZdZddZddZy)rwNcdt||_|jj||_y)aCreate a frozen SO(N) distribution. Parameters ---------- dim : scalar Dimension of matrices seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. Examples -------- >>> from scipy.stats import special_ortho_group >>> g = special_ortho_group(5) >>> x = g.rvs() N)rrrrrrxs r3rnz#special_ortho_group_frozen.__init__\s&,-T2 ::11#6r5cP|jj|j||Srvrrrr$s r3rzspecial_ortho_group_frozen.rvsuzz~~dhhl;;r5rr&r{r|r}rnrr.r5r3rwrw[ 72>> import numpy as np >>> from scipy.stats import ortho_group >>> x = ortho_group.rvs(3) >>> np.dot(x, x.T) array([[ 1.00000000e+00, 1.13231364e-17, -2.86852790e-16], [ 1.13231364e-17, 1.00000000e+00, -1.46845020e-16], [ -2.86852790e-16, -1.46845020e-16, 1.00000000e+00]]) >>> import scipy.linalg >>> np.fabs(scipy.linalg.det(x)) 1.0 This generates one random matrix from O(3). It is orthogonal and has a determinant of +1 or -1. Alternatively, the object may be called (as a function) to fix the `dim` parameter, returning a "frozen" ortho_group random variable: >>> rv = ortho_group(5) >>> # Frozen object with the same methods but holding the >>> # dimension parameter fixed. See Also -------- special_ortho_group clt||tj|j|_yrvrtrs r3rnzortho_group_gen.__init__rur5ct||S)zcCreate a frozen O(N) distribution. See `ortho_group_frozen` for more information. r/)ortho_group_frozenrxs r3rzortho_group_gen.__call__s "#D11r5cp|(tj|r|dks|t|k7r td|SrzrzQDimension of rotation must be specified,and must be a scalar nonnegative integer.r{r|s r3rz#ortho_group_gen._process_parameters> ;bkk#.#'SCH_IJ J r5c\|j|}t|}|j|}|dkDr|fnd}|j|||fz}tj j |\}}|jddd}||t|z dtjd d fz}|S) arDraw random samples from O(N). Parameters ---------- dim : integer Dimension of rotation space (N). size : integer, optional Number of samples to draw (default 1). Returns ------- rvs : ndarray or scalar Random size N-dimensional matrices, dimension (size, dim, dim) rr.rrr=r7offsetaxis1axis2.N) rrOrrr>rXqrrrBrrgrrrzrrr:s r3rzortho_group_gen.rvss --l; 4y&&s+(w   TS#J%6  7yy||A1 JJarJ 4 aAhRZZ* ++r5rvrr&rrs@r3rrys@D62r5rceZdZddZddZy)rNcdt||_|jj||_y)aCreate a frozen O(N) distribution. Parameters ---------- dim : scalar Dimension of matrices seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. Examples -------- >>> from scipy.stats import ortho_group >>> g = ortho_group(5) >>> x = g.rvs() N)rrrrrxs r3rnzortho_group_frozen.__init__s&,%T* ::11#6r5cP|jj|j||Srvrr$s r3rzortho_group_frozen.rvsrr5rr&rr.r5r3rrrr5rcFeZdZdZdfd Zd dZdZdZdZd dZ xZ S) random_correlation_genae A random correlation matrix. Return a random correlation matrix, given a vector of eigenvalues. The returned matrix is symmetric positive semidefinite with unit diagonal. The `eigs` keyword specifies the eigenvalues of the correlation matrix, and implies the dimension. Methods ------- rvs(eigs=None, random_state=None) Draw random correlation matrices, all with eigenvalues eigs. Parameters ---------- eigs : 1d ndarray Eigenvalues of correlation matrix. All eigenvalues need to be non-negative and need to sum to the number of eigenvalues. seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. tol : float, optional Tolerance for input parameter checks diag_tol : float, optional Tolerance for deviation of the diagonal of the resulting matrix. Default: 1e-7 Raises ------ RuntimeError Floating point error prevented generating a valid correlation matrix. Returns ------- rvs : ndarray or scalar Random size N-dimensional matrices, dimension (size, dim, dim), each having eigenvalues eigs. Notes ----- Generates a random correlation matrix following a numerically stable algorithm spelled out by Davies & Higham. This algorithm uses a single O(N) similarity transformation to construct a symmetric positive semi-definite matrix, and applies a series of Givens rotations to scale it to have ones on the diagonal. References ---------- .. [1] Davies, Philip I; Higham, Nicholas J; "Numerically stable generation of correlation matrices and their factors", BIT 2000, Vol. 40, No. 4, pp. 640 651 Examples -------- >>> import numpy as np >>> from scipy.stats import random_correlation >>> rng = np.random.default_rng() >>> x = random_correlation.rvs((.5, .8, 1.2, 1.5), random_state=rng) >>> x array([[ 1. , -0.02423399, 0.03130519, 0.4946965 ], [-0.02423399, 1. , 0.20334736, 0.04039817], [ 0.03130519, 0.20334736, 1. , 0.02694275], [ 0.4946965 , 0.04039817, 0.02694275, 1. ]]) >>> import scipy.linalg >>> e, v = scipy.linalg.eigh(x) >>> e array([ 0.5, 0.8, 1.2, 1.5]) clt||tj|j|_yrvrtrs r3rnzrandom_correlation_gen.__init__`rur5c t||||S)zrCreate a frozen random correlation matrix. See `random_correlation_frozen` for more information. )rtoldiag_tol)random_correlation_frozen)rgeigsrrrs r3rzrandom_correlation_gen.__call__ds )Dc2:< rUrLrr0rr[fabsrc)rgrrrrNs r3rz*random_correlation_gen._process_parameterslszz$e,ii 99>TZZ]c1SAX/0 0 77266$<#% & ,LM M JAC4x !HII JDyr5c|dz }|dz }|dk(rytjt|dz||zz d}|tj||z|z }dtjd||zzz }|dk(rd} || fS||z} || fS)a&Computes a 2x2 Givens matrix to put 1's on the diagonal. The input matrix is a 2x2 symmetric matrix M = [ aii aij ; aij ajj ]. The output matrix g is a 2x2 anti-symmetric matrix of the form [ c s ; -s c ]; the elements c and s are returned. Applying the output matrix to the input matrix (as b=g.T M g) results in a matrix with bii=1, provided tr(M) - det(M) >= 1 and floating point issues do not occur. Otherwise, some other valid rotation is returned. When tr(M)==2, also bjj=1. rr)rrr,)mathr_rAcopysign) rgaiiajjaijaiidajjdddrFcrjs r3 _givens_to_1z#random_correlation_gen._givens_to_1}sRxRx 19 YYs36DI-q1 24==S) )T 1 2!8$ $ 6A!t !A!t r5c|jjr<|jtjk(r|j d|j dk(s t |j d}t|dz D]}|||fdk(r|||fdkDr!t|dz|D]}|||fdksn"n t|dz|D]}|||fdkDsn|j|||f||f|||f\}}|j}t|||| |||zd||zddd t|||| |||||dd |S)z Given a psd matrix m, rotate to put one's on the diagonal, turning it into a correlation matrix. This also requires the trace equal the dimensionality. Note: modifies input matrix rrT)roffxincxoffyincy overwrite_x overwrite_y) flags c_contiguousr;r>r=rr[rrravelr)rgmr:rjrrjmvs r3_to_corrzrandom_correlation_gen._to_corrsq$$BJJ)> aggaj(,  GGAJqs 5AAw!|1a41qsAAAw{qsAAAw{$$Qq!tWa1gqAw?DAqB RQB!c!!!t 5 RQB!aaa!t 5/ 56r5c|j||\}}|j|}tj||}t j t j |t j ||j}|j|}t|jdz j|kDr td|S)aDraw random correlation matrices. Parameters ---------- eigs : 1d ndarray Eigenvalues of correlation matrix tol : float, optional Tolerance for input parameter checks diag_tol : float, optional Tolerance for deviation of the diagonal of the resulting matrix. Default: 1e-7 Raises ------ RuntimeError Floating point error prevented generating a valid correlation matrix. Returns ------- rvs : ndarray or scalar Random size N-dimensional matrices, dimension (size, dim, dim), each having eigenvalues eigs. r)rrz-Failed to generate a valid correlation matrix) rrr#rr>rwrrxrrBrrA RuntimeError)rgrrrrrrs r3rzrandom_correlation_gen.rvss4,,Ts,; T--l; OOClO ; FF266!RWWT]+QSS 1 MM!  qzz|a $ $ & 1NO Or5rvNgvIh%<=gHz>) r{r|r}r~rnrrrrrrrs@r3rrs*KZ6<"B'R&r5rceZdZddZddZy)rNct||_||_||_|jj ||j\}|_y)axCreate a frozen random correlation matrix distribution. Parameters ---------- eigs : 1d ndarray Eigenvalues of correlation matrix seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. tol : float, optional Tolerance for input parameter checks diag_tol : float, optional Tolerance for deviation of the diagonal of the resulting matrix. Default: 1e-7 Raises ------ RuntimeError Floating point error prevented generating a valid correlation matrix. Returns ------- rvs : ndarray or scalar Random size N-dimensional matrices, dimension (size, dim, dim), each having eigenvalues eigs. rN)rrrrrr)rgrrrrrZs r3rnz"random_correlation_frozen.__init__sBB,D1   zz55d5I 49r5c||jj|j||j|jS)N)rrr)rrrrrrs r3rzrandom_correlation_frozen.rvss3zz~~diil"&((T]]D Dr5rrvrr.r5r3rrs$JLDr5rc:eZdZdZdfd ZddZdZddZxZS) unitary_group_genaA matrix-valued U(N) random variable. Return a random unitary matrix. The `dim` keyword specifies the dimension N. Methods ------- rvs(dim=None, size=1, random_state=None) Draw random samples from U(N). Parameters ---------- dim : scalar Dimension of matrices. seed : {None, int, np.random.RandomState, np.random.Generator}, optional Used for drawing random variates. If `seed` is `None`, the `~np.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with seed. If `seed` is already a ``RandomState`` or ``Generator`` instance, then that object is used. Default is `None`. Notes ----- This class is similar to `ortho_group`. References ---------- .. [1] F. Mezzadri, "How to generate random matrices from the classical compact groups", :arXiv:`math-ph/0609050v2`. Examples -------- >>> import numpy as np >>> from scipy.stats import unitary_group >>> x = unitary_group.rvs(3) >>> np.dot(x, x.conj().T) array([[ 1.00000000e+00, 1.13231364e-17, -2.86852790e-16], [ 1.13231364e-17, 1.00000000e+00, -1.46845020e-16], [ -2.86852790e-16, -1.46845020e-16, 1.00000000e+00]]) # may vary This generates one random matrix from U(3). The dot product confirms that it is unitary up to machine precision. Alternatively, the object may be called (as a function) to fix the `dim` parameter, return a "frozen" unitary_group random variable: >>> rv = unitary_group(5) See Also -------- ortho_group clt||tj|j|_yrvrtrs r3rnzunitary_group_gen.__init__Zrur5ct||S)zCreate a frozen (U(N)) n-dimensional unitary matrix distribution. See `unitary_group_frozen` for more information. r/)unitary_group_frozenrxs r3rzunitary_group_gen.__call__^s $Cd33r5cp|(tj|r|dks|t|k7r td|Srr{r|s r3rz%unitary_group_gen._process_parameterserr5c|j|}t|}|j|}|dkDr|fnd}dtjdz |j |||fzd|j |||fzzzz}t jj|\}}|jddd }||t|z d t jd d fz}|S) aiDraw random samples from U(N). Parameters ---------- dim : integer Dimension of space (N). size : integer, optional Number of samples to draw (default 1). Returns ------- rvs : ndarray or scalar Random size N-dimensional matrices, dimension (size, dim, dim) rr.r,ry?rr=r7r.N) rrOrrr_rr>rXrrrBrrs r3rzunitary_group_gen.rvsms --l; 4y&&s+(w diilNL//TS#J5F/G|22Sz8I2JJK Lyy||A1 JJarJ 4 aAhRZZ* ++r5rvrr&rrs@r3rrs8t64 r5rceZdZddZddZy)rNcdt||_|jj||_y)aCreate a frozen (U(N)) n-dimensional unitary matrix distribution. Parameters ---------- dim : scalar Dimension of matrices seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. Examples -------- >>> from scipy.stats import unitary_group >>> x = unitary_group(3) >>> x.rvs() N)rrrrrxs r3rnzunitary_group_frozen.__init__s&,'t, ::11#6r5cP|jj|j||Srvrr$s r3rzunitary_group_frozen.rvsrr5rr&rr.r5r3rrrr5raloc : array_like, optional Location of the distribution. (default ``0``) shape : array_like, optional Positive semidefinite matrix of the distribution. (default ``1``) df : float, optional Degrees of freedom of the distribution; must be greater than zero. If ``np.inf`` then results are multivariate normal. The default is ``1``. allow_singular : bool, optional Whether to allow a singular matrix. (default ``False``) aSetting the parameter `loc` to ``None`` is equivalent to having `loc` be the zero-vector. The parameter `shape` can be a scalar, in which case the shape matrix is the identity times that value, a vector of diagonal entries for the shape matrix, or a two-dimensional array_like. )_mvt_doc_default_callparams_mvt_doc_callparams_noterceZdZdZdfd Z ddZddZddZdZ ddZ ddddd d Z dd Z dd Z dd Z dZdZxZS)multivariate_t_gena A multivariate t-distributed random variable. The `loc` parameter specifies the location. The `shape` parameter specifies the positive semidefinite shape matrix. The `df` parameter specifies the degrees of freedom. In addition to calling the methods below, the object itself may be called as a function to fix the location, shape matrix, and degrees of freedom parameters, returning a "frozen" multivariate t-distribution random. Methods ------- pdf(x, loc=None, shape=1, df=1, allow_singular=False) Probability density function. logpdf(x, loc=None, shape=1, df=1, allow_singular=False) Log of the probability density function. cdf(x, loc=None, shape=1, df=1, allow_singular=False, *, maxpts=None, lower_limit=None, random_state=None) Cumulative distribution function. rvs(loc=None, shape=1, df=1, size=1, random_state=None) Draw random samples from a multivariate t-distribution. entropy(loc=None, shape=1, df=1) Differential entropy of a multivariate t-distribution. Parameters ---------- %(_mvt_doc_default_callparams)s %(_doc_random_state)s Notes ----- %(_mvt_doc_callparams_note)s The matrix `shape` must be a (symmetric) positive semidefinite matrix. The determinant and inverse of `shape` are computed as the pseudo-determinant and pseudo-inverse, respectively, so that `shape` does not need to have full rank. The probability density function for `multivariate_t` is .. math:: f(x) = \frac{\Gamma((\nu + p)/2)}{\Gamma(\nu/2)\nu^{p/2}\pi^{p/2}|\Sigma|^{1/2}} \left[1 + \frac{1}{\nu} (\mathbf{x} - \boldsymbol{\mu})^{\top} \boldsymbol{\Sigma}^{-1} (\mathbf{x} - \boldsymbol{\mu}) \right]^{-(\nu + p)/2}, where :math:`p` is the dimension of :math:`\mathbf{x}`, :math:`\boldsymbol{\mu}` is the :math:`p`-dimensional location, :math:`\boldsymbol{\Sigma}` the :math:`p \times p`-dimensional shape matrix, and :math:`\nu` is the degrees of freedom. .. versionadded:: 1.6.0 References ---------- .. [1] Arellano-Valle et al. "Shannon Entropy and Mutual Information for Multivariate Skew-Elliptical Distributions". Scandinavian Journal of Statistics. Vol. 40, issue 1. Examples -------- The object may be called (as a function) to fix the `loc`, `shape`, `df`, and `allow_singular` parameters, returning a "frozen" multivariate_t random variable: >>> import numpy as np >>> from scipy.stats import multivariate_t >>> rv = multivariate_t([1.0, -0.5], [[2.1, 0.3], [0.3, 1.5]], df=2) >>> # Frozen object with the same methods but holding the given location, >>> # scale, and degrees of freedom fixed. Create a contour plot of the PDF. >>> import matplotlib.pyplot as plt >>> x, y = np.mgrid[-1:3:.01, -2:1.5:.01] >>> pos = np.dstack((x, y)) >>> fig, ax = plt.subplots(1, 1) >>> ax.set_aspect('equal') >>> plt.contourf(x, y, rv.pdf(pos)) Nct||tj|jt |_t ||_y)zInitialize a multivariate t-distributed random variable. Parameters ---------- seed : Random state. N)rrnrrr~mvt_docdict_paramsr rrs r3rnzmultivariate_t_gen.__init__'s8 '' 6HI /5r5cf|tjk(rt||||St|||||S)zjCreate a frozen multivariate t-distribution. See `multivariate_t_frozen` for parameters. )rrrir)locrrrir)r>rrmultivariate_t_frozen)rgrrrrirs r3rzmultivariate_t_gen.__call__3sB <-3E=K379 9%Eb4BO Or5c |j|||\}}}}|j||}t||}|j|||j|j |||j }tj|S)aZMultivariate t-distribution probability density function. Parameters ---------- x : array_like Points at which to evaluate the probability density function. %(_mvt_doc_default_callparams)s Returns ------- pdf : Probability density function evaluated at `x`. Examples -------- >>> from scipy.stats import multivariate_t >>> x = [0.4, 5] >>> loc = [0, 1] >>> shape = [[1, 0.1], [0.1, 1]] >>> df = 7 >>> multivariate_t.pdf(x, loc, shape, df) 0.00075713 r) rrrQrrbrerar>r) rgrNrrrrir shape_infors r3rzmultivariate_t_gen.pdf@sx0#66sE2FS%  # #As +%? ajllJ4G4G!:??4vvf~r5c |j|||\}}}}|j||}t|}|j|||j|j |||j S)aLog of the multivariate t-distribution probability density function. Parameters ---------- x : array_like Points at which to evaluate the log of the probability density function. %(_mvt_doc_default_callparams)s Returns ------- logpdf : Log of the probability density function evaluated at `x`. Examples -------- >>> from scipy.stats import multivariate_t >>> x = [0.4, 5] >>> loc = [0, 1] >>> shape = [[1, 0.1], [0.1, 1]] >>> df = 7 >>> multivariate_t.logpdf(x, loc, shape, df) -7.1859802 See Also -------- pdf : Probability density function. )rrrQrrbrera)rgrNrrrrrs r3rzmultivariate_t_gen.logpdf_sj:#66sE2FS%  # #As +%[ ||AsJLL*2E2Er3&OO- -r5c|tjk(rtj|||||S||z }tjtj ||j d} d||zz} t| } td|z} |dz tj|tjzz} d|z}| tjdd|z | zzz}t| | z | z |z |zS)aBUtility method `pdf`, `logpdf` for parameters. Parameters ---------- x : ndarray Points at which to evaluate the log of the probability density function. loc : ndarray Location of the distribution. prec_U : ndarray A decomposition such that `np.dot(prec_U, prec_U.T)` is the inverse of the shape matrix. log_pdet : float Logarithm of the determinant of the shape matrix. df : float Degrees of freedom of the distribution. dim : int Dimension of the quantiles x. rank : int Rank of the shape matrix. Notes ----- As this function does no argument checking, it should not be called directly; use 'logpdf' instead. r7rpr @rr) r>rrrrrwrcrrdpir4)rgrNrprec_UrerrrarrrFrBrDEs r3rzmultivariate_t_gen._logpdfs8 <&..q#vxN N#gyyV,-11r1: 28  AJ C"H  FRVVBJ' ' (N BRUdN*+ +q1uqy1}q011r5c `| t|n |jsd|z|j||}|/tj|j tj n|}||z ||z }}tj||\} } | | k} d| jdz} | j| j} } | | | | c| | <| | <|j dtj| | fd} fd}tj|d| | z}t|S)Nir7rpc>|d|d}}t||dS)Nr)r)rrrrrrrrs r3rz'multivariate_t_gen._cdf..func1ds2"1:vabzqAUAq#6q9 9r5) r rrr>rrrrrcrrrr4)rgrNrrrrrrrrrrrrrrrrs `` ` @@r3rzmultivariate_t_gen._cdfs2  #$\2C$$CCZF  # #As +%-wwsyy266'23> S+"3;""1k21Qvzzrz*+vvx1 y!F)& 1V9 GGBKAR0 : :!!&"f5=s##r5rrrc |j|||\} }}}t||j}|j||||| |||S)aMultivariate t-distribution cumulative distribution function. Parameters ---------- x : array_like Points at which to evaluate the cumulative distribution function. %(_mvt_doc_default_callparams)s maxpts : int, optional Maximum number of points to use for integration. The default is 1000 times the number of dimensions. lower_limit : array_like, optional Lower limit of integration of the cumulative distribution function. Default is negative infinity. Must be broadcastable with `x`. %(_doc_random_state)s Returns ------- cdf : ndarray or scalar Cumulative distribution function evaluated at `x`. Examples -------- >>> from scipy.stats import multivariate_t >>> x = [0.4, 5] >>> loc = [0, 1] >>> shape = [[1, 0.1], [0.1, 1]] >>> df = 7 >>> multivariate_t.cdf(x, loc, shape, df) 0.64798491 r)rrQrVr) rgrNrrrrirrrrs r3rzmultivariate_t_gen.cdfsVB#66sE2FS%U>:==yyCC$l4 4r5c$|tjk(rtd|jSt |}d|j zfd}fd}|dzdztj |dzz }tj||k\||f||S)N)rr cd||zz}d|z}t| t|zd|ztj|tjzzz|t |t |z zzzS)Nr )rr>rdrr)rrhalfsumhalf_df shape_terms r3regularz,multivariate_t_gen._entropy..regulars}S2X&GBhG!!GG$44)bffR"%%Z0013:w<#g,.400 r5c"|tjz||z z||dz z|dzzdz z |dz|dz z|dzzdz z|d|dzzd|dzzzdz z|d zzd z z|dzd|dzzd |dzzz d zz|d zzdz zzdS)Nr,grgrgr.)rrX)rrrs r3 asymptoticz/multivariate_t_gen._entropy..asymptotic s dmmo%b0q/BH,q01q&C!G$r4x/!34c1fq36z1A56TABFGq&AQJc1f4r9:RXEJ K    r5drr) r>rrr rQrerdxpx apply_where) rgrrrrrr thresholdrs @r3rXzmultivariate_t_gen._entropys <&t7??A A%[ :...   #IMRVVC[1_5 rYb :wOOr5cX|jd||\}}}}|j|||S)zCalculate the differential entropy of a multivariate t-distribution. Parameters ---------- %(_mvt_doc_default_callparams)s Returns ------- h : float Differential entropy NrrX)rgrrrrs r3r zmultivariate_t_gen.entropys4#66tUBGS%}}S"e,,r5c|j|||\}}}}| t|}n |j}tj|rtj |}n|j |||z }|jtj|||} || tj|dz z} t| S)aDraw random samples from a multivariate t-distribution. Parameters ---------- %(_mvt_doc_default_callparams)s size : integer, optional Number of samples to draw (default 1). %(_doc_random_state)s Returns ------- rvs : ndarray or scalar Random variates of size (`size`, `P`), where `P` is the dimension of the random variable. Examples -------- >>> from scipy.stats import multivariate_t >>> x = [0.4, 5] >>> loc = [0, 1] >>> shape = [[1, 0.1], [0.1, 1]] >>> df = 7 >>> multivariate_t.rvs(loc, shape, df) array([[0.93477495, 3.00408716]]) r.N) rr rr>isinfonesrrrr_r4) rgrrrrrrrrNrsampless r3rzmultivariate_t_gen.rvs.s@#66sE2FS%  #$\2C$$C 88B< A bt ,r1A  # #BHHSM5t # DBGGAJy111w''r5c tj|t}|jdk(r|tj}|S|jdk(r5|dk(r|ddtjf}|S|tjddf}|Srrrs r3rz%multivariate_t_gen._process_quantiles]sy JJq & 66Q;"** A  VVq[axam$bjj!m$r5cD|;|9tjdt}tjdt}d}n|Rtj|t}|jdkrd}n|jd}tj |}n|=tj|t}|j }tj|}nBtj|t}tj|t}|j }|dk(r#|jd}|jdd}|jdk7s|jd|k7rtd|d|jdk(r|tj|z}n|jdk(rtj|}n|jdk(ry|j||fk7rh|j\}}||k7r$dt|jd}t|d}|t|jt|fz}t||jdkDrtd |j|d}n0|dkr td tj|r td ||||fS) z Infer dimensionality from location array and shape matrix, handle defaults, and ensure compatible dimensions. rrJrr,z'Array 'loc' must be a vector of length rrzSDimension mismatch: array 'cov' is of shape %s, but 'loc' is a vector of length %d.rz'df' must be greater than zero.z8'df' is 'nan' but must be greater than zero or 'np.inf'.)r>rUrLr0rrrrrr[rrr\isnan)rgrrrrrrrls r3rz&multivariate_t_gen._process_parameterslsA ;5=**Qe,CJJq.EC [JJuE2EzzA~kk!n((3-C ]**S.C((CFF3KEJJuE2E**S.C((C !8++a.CMM!Q'E 88q=CIIaLC/Fse1MN N ::?BFF3K'E ZZ1_GGENE ZZ1_c !:JD$t|++.u{{+;*S-s3x88S/ ! ZZ!^ //4zzl<= = :B 1W>? ? XXb\WX XC""r5rvNrrFN)NrrFr`rrbra)r{r|r}r~rnrrrrrrrXr rrrrrs@r3rrsnPd 6@E O>!-F)2VEI%$N%4T%4N PD-"-(^ 9#r5rcBeZdZ d dZdZdddddZdZd dZdZy) rNct||_|jj|||\}}}}||||f\|_|_|_|_t|||_y)aCreate a frozen multivariate t distribution. Parameters ---------- %(_mvt_doc_default_callparams)s Examples -------- >>> import numpy as np >>> from scipy.stats import multivariate_t >>> loc = np.zeros(3) >>> shape = np.eye(3) >>> df = 10 >>> dist = multivariate_t(loc, shape, df) >>> dist.rvs() array([[ 0.81412036, -1.53612361, 0.42199647]]) >>> dist.pdf([1, 1, 1]) array([0.01237803]) rN) rrrrrrrrQr)rgrrrrirrs r3rnzmultivariate_t_frozen.__init__s^,(- "jj<>> from scipy.stats import multivariate_hypergeom >>> multivariate_hypergeom.pmf(x=[8, 4], m=[10, 20], n=12) 0.0025207176631464523 The `multivariate_hypergeom` distribution is identical to the corresponding `hypergeom` distribution (tiny numerical differences notwithstanding) when only two types (good and bad) of objects are present in the population as in the example above. Consider another example for a comparison with the hypergeometric distribution: >>> from scipy.stats import hypergeom >>> multivariate_hypergeom.pmf(x=[3, 1], m=[10, 5], n=4) 0.4395604395604395 >>> hypergeom.pmf(k=3, M=15, n=4, N=10) 0.43956043956044005 The functions ``pmf``, ``logpmf``, ``mean``, ``var``, ``cov``, and ``rvs`` support broadcasting, under the convention that the vector parameters (``x``, ``m``, and ``n``) are interpreted as if each row along the last axis is a single object. For instance, we can combine the previous two calls to `multivariate_hypergeom` as >>> multivariate_hypergeom.pmf(x=[[8, 4], [3, 1]], m=[[10, 20], [10, 5]], ... n=[12, 4]) array([0.00252072, 0.43956044]) This broadcasting also works for ``cov``, where the output objects are square matrices of size ``m.shape[-1]``. For example: >>> multivariate_hypergeom.cov(m=[[7, 9], [10, 15]], n=[8, 12]) array([[[ 1.05, -1.05], [-1.05, 1.05]], [[ 1.56, -1.56], [-1.56, 1.56]]]) That is, ``result[0]`` is equal to ``multivariate_hypergeom.cov(m=[7, 9], n=8)`` and ``result[1]`` is equal to ``multivariate_hypergeom.cov(m=[10, 15], n=12)``. Alternatively, the object may be called (as a function) to fix the `m` and `n` parameters, returning a "frozen" multivariate hypergeometric random variable. >>> rv = multivariate_hypergeom(m=[10, 20], n=12) >>> rv.pmf(x=[8, 4]) 0.0025207176631464523 See Also -------- scipy.stats.hypergeom : The hypergeometric distribution. scipy.stats.multinomial : The multinomial distribution. References ---------- .. [1] The Multivariate Hypergeometric Distribution, http://www.randomservices.org/random/urn/MultiHypergeometric.html .. [2] Thomas J. Sargent and John Stachurski, 2020, Multivariate Hypergeometric Distribution https://python.quantecon.org/multi_hyper.html cvt||tj|jt |_yrv)rrnrrr~mhg_docdict_paramsrs r3rnz#multivariate_hypergeom_gen.__init__rr5ct|||S)zCreate a frozen multivariate_hypergeom distribution. See `multivariate_hypergeom_frozen` for more information. r/)multivariate_hypergeom_frozen)rgrrrs r3rz#multivariate_hypergeom_gen.__call__s -Q==r5c $tj|}tj|}|jdk(r|jt}|jdk(r|jt}tj |j tjs tdtj |j tjs td|jdk(r td|jdk7r|dtjf}tj||\}}|jdk7r|d}|dk}|jd}|dk||kDz}|||||tj|d|zfS) Nrz'm' must an array of integers.z'n' must an array of integers.z1'm' must be an array with at least one dimension...rr7rp)r>rUrastyperO issubdtyper;integer TypeErrorr0r[rrrcr)rgrrmcondrhrDs r3rz.multivariate_hypergeom_gen._process_parameterssE JJqM JJqM 66Q; A 66Q; A}}QWWbjj1<= =}}QWWbjj1<= = 66Q;89 9 66Q;#rzz/"A""1a(1 66Q;& AA EErENQ1q5!!QubffU&rUrr;rrr0r[rrrrrrc)rgrNrhrrrUs r3rz-multivariate_hypergeom_gen._process_quantilessV JJqM}}QWWbjj1<= = 66Q;89 9wwr{aggbk) ))* 6--.WWR[M<= = 66Q;#rzz/"A#rzz/"A((Aq!4 1a 66Q;V9aiqAQ1q5!1aEu2&!%%R%.A*=>@ @r5ctj|}|jdk7r|||<n|r|S|jdk(r|dS|S)Nrr.rIrJs r3rMz'multivariate_hypergeom_gen._checkresultsHF# 99>$F4L   ;;! ":  r5ctj|tj}tj|tj}||||}}||||}}t|dzdt|dz||z dzz ||<t|dzdt|dz||z dzz ||<tj||<tj||<|j d}||z S)NrJrr7rp)r> zeros_liker=r rSrc) rgrNrhrrmxcondrDnumdens r3rPz"multivariate_hypergeom_gen._logpmfsmmARZZ0mmARZZ0&z1fW:1%y!UF)1qsA!QqSU);;VG ac1~qsAaCE(::UF ffF VVE gg2gSyr5cR|j||\}}}}}}|j||||\}}}}}} ||z} |tj|jtj z}|j ||||| |} | tj|jtj z} |j| | tj } |tj| jtj z} |j| | tjS)aLog of the multivariate hypergeometric probability mass function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. %(_doc_default_callparams)s Returns ------- logpmf : ndarray or scalar Log of the probability mass function evaluated at `x` Notes ----- %(_doc_callparams_note)s rJ) rrr>rrrRrPrMrrS)rgrNrrrhrrDmncondrU xcond_reducedrrKrVmncond_s r3rXz!multivariate_hypergeom_gen.logpmfs$)-(@(@A(F%1av11!Q1= Aq!U 99aAq&%8&,,bhh!GG""66BFF7;288M$7$7rxxHH  "&&99r5cRtj|j|||}|S)aMultivariate hypergeometric probability mass function. Parameters ---------- x : array_like Quantiles, with the last axis of `x` denoting the components. %(_doc_default_callparams)s Returns ------- pmf : ndarray or scalar Probability density function evaluated at `x` Notes ----- %(_doc_callparams_note)s rZ)rgrNrrr2s r3r[zmultivariate_hypergeom_gen.pmfs$$ffT[[Aq)* r5c|j||\}}}}}}|jdk7r*|dtjf|dtjf}}|dk(}tjj ||}|||z z}|jdk7rE|dtjftj |jtjz}|j||tjS)zMean of the multivariate hypergeometric distribution. Parameters ---------- %(_doc_default_callparams)s Returns ------- mean : array_like or scalar The mean of the distribution r.maskrJ rrr>rma masked_arrayrrrRrMrS)rgrrrhrZr#rDmus r3rzmultivariate_hypergeom_gen.means!% 8 8A >1aAv 66Q;S"**_%qbjj'9qAQ EE  qt  , !W 66Q;S"**_-hhrxxrxx89F  VRVV44r5c(|j||\}}}}}}|jdk7r*|dtjf|dtjf}}|dk(|dz dk(z}tjj ||}||z|z ||z z|z ||z z|dz z }|jdk7rE|dtjftj |jtjz}|j||tjS)aQVariance of the multivariate hypergeometric distribution. Parameters ---------- %(_doc_default_callparams)s Returns ------- array_like The variances of the components of the distribution. This is the diagonal of the covariance matrix of the distribution r.rr(rJr*)rgrrrhrZr#rDoutputs r3rzmultivariate_hypergeom_gen.var1s!% 8 8A >1aAv 66Q;S"**_%qbjj'9qAQ1Q3!8$ EE  qt  ,QqAaC"ac*AaC0 66Q;S"**_-hhv||288<=F  88r5c|j||\}}}}}}|jdk7rH|dtjtjf}|dtjtjf}|dk(|dz dk(z}tjj ||}| ||z z|dz z tj d||z|dzz }|jdk7r|d|d}}|d}|jd}t|D]K} |||z z|d| fz||d| fz z|d| | f<|d| | f|dz z |d| | f<|d| | f|dzz |d| | f<M|jdk7rT|dtjtjftj|jtj z}|j||tjS) aCovariance matrix of the multivariate hypergeometric distribution. Parameters ---------- %(_doc_default_callparams)s Returns ------- cov : array_like The covariance matrix of the distribution r.rr(z...i,...j->...ijr,).rrr7rJ) rrr>rr+r,rSrrrrRrMrS) rgrrrhrZr#rDr/rrs r3rzmultivariate_hypergeom_gen.covJs!% 8 8A >1aAv 66Q;#rzz2::-.A#rzz2::-.AQ1Q3!8$ EE  qt  ,"!*ac")).1569:A? 66Q;Y<9qA ?Dggbks ;A!"acQsAvY!6!CF) !DF319  &sAqy 1QqS 9F319  &sAqy 1QT :F319  ; 66Q;S"**bjj89hhv||288<=F  88r5c:|j||\}}}}}}|j|}|t|tr|f}|,t j |j |j}n2t j ||j dfz|j}|}t|j ddz D]D} ||d| fz }|dk(} | |j|d| f|| z|| z|z|d| f<||d| fz }F||d|j ddz f<|S)aDraw random samples from a multivariate hypergeometric distribution. Parameters ---------- %(_doc_default_callparams)s size : integer or iterable of integers, optional Number of samples to draw. Default is ``None``, in which case a single variate is returned as an array with shape ``m.shape``. %(_doc_random_state)s Returns ------- rvs : array_like Random variates of shape ``size`` or ``m.shape`` (if ``size=None``). Notes ----- %(_doc_callparams_note)s Also note that NumPy's `multivariate_hypergeometric` sampler is not used as it doesn't support broadcasting. rJr7r.rr) rrrrOr>rrr;rhypergeometric) rgrrrrrhrZrremrn0masks r3rzmultivariate_hypergeom_gen.rvspsC0 33Aq91aAq--l;   4 58D <((177!''2C((41772;/1ACqwwr{Q' A#q& /C!VF"7'66qay7:V|786z<@7BBCQK CQKA %&Cq ! r5rvr)r{r|r}r~rnrrrrMrPrXr[rrrrrrs@r3rrsLo`J>E@@6 ":H*5092$9L2r5rc:eZdZd dZdZdZdZdZdZd dZ y) rNct|_jj||\______fd}|j_y)Ncjjjjjj fSrv)rhrrrrDr#)rrrgs r3rzCmultivariate_hypergeom_frozen.__init__.._process_parameterss4FFDFFDFFJJ KK! !r5) rrrrhrrrrDr#)rgrrrrs` r3rnz&multivariate_hypergeom_frozen.__init__sW/5  66q!<  TZ  !*= &r5cd|jj||j|jSrv)rrXrrrs r3rXz$multivariate_hypergeom_frozen.logpmfrhr5cd|jj||j|jSrv)rr[rrrs r3r[z!multivariate_hypergeom_frozen.pmfrjr5cb|jj|j|jSrv)rrrrrys r3rz"multivariate_hypergeom_frozen.meanrlr5cb|jj|j|jSrv)rrrrrys r3rz!multivariate_hypergeom_frozen.varrnr5cb|jj|j|jSrv)rrrrrys r3rz!multivariate_hypergeom_frozen.covrnr5ch|jj|j|j||SNrr)rrrrr$s r3rz!multivariate_hypergeom_frozen.rvss.zz~~dffdff#'+79 9r5rvr&) r{r|r}rnrXr[rrrrr.r5r3rrs% =41/..9r5r)rXr[rrrrceZdZdZdfd ZdddZdZdZdZdddd d Z e d Z e d Z e d Ze dZe dZe dZxZS)random_table_genaContingency tables from independent samples with fixed marginal sums. This is the distribution of random tables with given row and column vector sums. This distribution represents the set of random tables under the null hypothesis that rows and columns are independent. It is used in hypothesis tests of independence. Because of assumed independence, the expected frequency of each table element can be computed from the row and column sums, so that the distribution is completely determined by these two vectors. Methods ------- logpmf(x) Log-probability of table `x` to occur in the distribution. pmf(x) Probability of table `x` to occur in the distribution. mean(row, col) Mean table. rvs(row, col, size=None, method=None, random_state=None) Draw random tables with given row and column vector sums. Parameters ---------- %(_doc_row_col)s %(_doc_random_state)s Notes ----- %(_doc_row_col_note)s Random elements from the distribution are generated either with Boyett's [1]_ or Patefield's algorithm [2]_. Boyett's algorithm has O(N) time and space complexity, where N is the total sum of entries in the table. Patefield's algorithm has O(K x log(N)) time complexity, where K is the number of cells in the table and requires only a small constant work space. By default, the `rvs` method selects the fastest algorithm based on the input, but you can specify the algorithm with the keyword `method`. Allowed values are "boyett" and "patefield". .. versionadded:: 1.10.0 Examples -------- >>> from scipy.stats import random_table >>> row = [1, 5] >>> col = [2, 3, 1] >>> random_table.mean(row, col) array([[0.33333333, 0.5 , 0.16666667], [1.66666667, 2.5 , 0.83333333]]) Alternatively, the object may be called (as a function) to fix the row and column vector sums, returning a "frozen" distribution. >>> dist = random_table(row, col) >>> dist.rvs(random_state=123) array([[1, 0, 0], [1, 3, 1]]) References ---------- .. [1] J. Boyett, AS 144 Appl. Statist. 28 (1979) 329-332 .. [2] W.M. Patefield, AS 159 Appl. Statist. 30 (1981) 91-97 Nc$t||yrvrrnrs r3rnzrandom_table_gen.__init__ r5r/ct|||S)z~Create a frozen distribution of tables with given marginals. See `random_table_frozen` for more information. r/)random_table_frozen)rgrowcolrs r3rzrandom_table_gen.__call__s #3$77r5c|j||\}}}tj|}|jdkr t dtj |j tj}tjd5|s6tj|jt|k(s t ddddtj|dkr t dtj|d }tj|d } |jd t|k7r t d | jd t|k7r t d tj |jdd } tj||k(d tj| |k(d z} d} tj| |d tj| |d z| |z tj| || d z | | <tj" | | <| dS#1swYxYw)aLog-probability of table to occur in the distribution. Parameters ---------- %(_doc_x)s %(_doc_row_col)s Returns ------- logpmf : ndarray or scalar Log of the probability mass function evaluated at `x`. Notes ----- %(_doc_row_col_note)s If row and column marginals of `x` do not match `row` and `col`, negative infinity is returned. Examples -------- >>> from scipy.stats import random_table >>> import numpy as np >>> x = [[1, 5, 1], [2, 3, 1]] >>> row = np.sum(x, axis=1) >>> col = np.sum(x, axis=0) >>> random_table.logpmf(x, row, col) -1.6306401200847027 Alternatively, the object may be called (as a function) to fix the row and column vector sums, returning a "frozen" distribution. >>> d = random_table(row, col) >>> d.logpmf(x) -1.6306401200847027 r,z$`x` must be at least two-dimensionalignore)invalidz%`x` must contain only integral valuesNrz)`x` must contain only non-negative valuesr7rpr=z"shape of `x` must agree with `row`z"shape of `x` must agree with `col`ct|dzSr)r)rNs r3lnfacz&random_table_gen.logpmf..lnfaces1q5> !r5)r7r=r.)rr>rUr0r[rr;rerrstateallrrOrrcrr\rr) rgrNrGrHrrr dtype_is_intr2c2rr)rMs r3rXzrandom_table_gen.logpmf#sL**341a JJqM 66A:CD D}}QWWbjj9 [[ * Jqxx}/A(B !HII J 66!a%=HI I VVAB  VVAB  88B<3q6 !AB B 88B<3q6 !AB Bhhqwws|$vvbAgB'"&&qr*BB "VVE!H2.ar1JJQx "$&&qwh"GHD ffWTE 2w9 J Js 9IIcNtj|j|||S)aProbability of table to occur in the distribution. Parameters ---------- %(_doc_x)s %(_doc_row_col)s Returns ------- pmf : ndarray or scalar Probability mass function evaluated at `x`. Notes ----- %(_doc_row_col_note)s If row and column marginals of `x` do not match `row` and `col`, zero is returned. Examples -------- >>> from scipy.stats import random_table >>> import numpy as np >>> x = [[1, 5, 1], [2, 3, 1]] >>> row = np.sum(x, axis=1) >>> col = np.sum(x, axis=0) >>> random_table.pmf(x, row, col) 0.19580419580419592 Alternatively, the object may be called (as a function) to fix the row and column vector sums, returning a "frozen" distribution. >>> d = random_table(row, col) >>> d.pmf(x) 0.19580419580419592 rZ)rgrNrGrHs r3r[zrandom_table_gen.pmfns!Lvvdkk!S#.//r5c`|j||\}}}tj|||z S)aAMean of distribution of conditional tables. %(_doc_mean_params)s Returns ------- mean: ndarray Mean of the distribution. Notes ----- %(_doc_row_col_note)s Examples -------- >>> from scipy.stats import random_table >>> row = [1, 5] >>> col = [2, 3, 1] >>> random_table.mean(row, col) array([[0.33333333, 0.5 , 0.16666667], [1.66666667, 2.5 , 0.83333333]]) Alternatively, the object may be called (as a function) to fix the row and column vector sums, returning a "frozen" distribution. >>> d = random_table(row, col) >>> d.mean() array([[0.33333333, 0.5 , 0.16666667], [1.66666667, 2.5 , 0.83333333]]) )rr>r)rgrGrHrrrs r3rzrandom_table_gen.means1>**341axx1~!!r5rmethodrc|j||\}}}|j|||\}} |j|}|j||||} | |||||j | S)agDraw random tables with fixed column and row marginals. Parameters ---------- %(_doc_row_col)s size : integer, optional Number of samples to draw (default 1). method : str, optional Which method to use, "boyett" or "patefield". If None (default), selects the fastest method for this input. %(_doc_random_state)s Returns ------- rvs : ndarray Random 2D tables of shape (`size`, `len(row)`, `len(col)`). Notes ----- %(_doc_row_col_note)s Examples -------- >>> from scipy.stats import random_table >>> row = [1, 5] >>> col = [2, 3, 1] >>> random_table.rvs(row, col, random_state=123) array([[1., 0., 0.], [1., 3., 1.]]) Alternatively, the object may be called (as a function) to fix the row and column vector sums, returning a "frozen" distribution. >>> d = random_table(row, col) >>> d.rvs(random_state=123) array([[1., 0., 0.], [1., 3., 1.]]) )r_process_size_shaper_process_rvs_methodr) rgrGrHrrVrrrrrmeths r3rzrandom_table_gen.rvssyP**341a..tQ: e--l; ''1a8Aq!T<088??r5ctj|tjd}tj|tjd}tj|dk7r t dtj|dk7r t dtj |dkr t dtj |dkr t dtj |}|tj |k7r t d tj|tj|k(s t d tj|tj|k(s t d |||fS) z Check that row and column vectors are one-dimensional, that they do not contain negative or non-integer entries, and that the sums over both vectors are equal. Tr9rz`row` must be one-dimensionalz`col` must be one-dimensionalrz*each element of `row` must be non-negativez*each element of `col` must be non-negativez'sums over `row` and `col` must be equalz(each element of `row` must be an integerz(each element of `col` must be an integer) r>rKint64r0r[rrcrOrU)rGrHrrrs r3rz$random_table_gen._process_parameterss HHSt 4 HHSt 4 771:?<= = 771:?<= = 66!a%=IJ J 66!a%=IJ J FF1I q >FG Gvva2::c?*+GH Hvva2::c?*+GH H!Qwr5cLt|t|f}|d|fStj|}tj|jtj rtj |dkr tdtj|t||zfS)zW Compute the number of samples to be drawn and the shape of the output rrz/`size` must be a non-negative integer or `None`) r\r>r rr;rrr[rr)rrrrs r3rXz$random_table_gen._process_size_shapes QQ  <e8O}}T"}}TZZ4tax8HNO Owwt}eDkE111r5c |j||||j|jd} ||S#t$rt d|dt |wxYw)N)Nboyett patefield'z!' not recognized, must be one of ) _rvs_select _rvs_boyett_rvs_patefieldKeyErrorr[set)clsrVrrr known_methodss r3rYz$random_table_gen._process_rvs_methodsx//!Q*oo++  E ( ( Eq)//2=/A.BDE E Es 2$Acd}t|t|z}||tj|dzz|zkDr |jS|jS)Nrr)r\r>rdrdrc)rgrrrfacrs r3rbzrandom_table_gen._rvs_select$sL FSVO sRVVAE]"Q& &%% %r5c4tj|||||Srv)r rvs_rcont1rGrHntotrrs r3rczrandom_table_gen._rvs_boyett-  c4|DDr5c4tj|||||Srv)r rvs_rcont2rms r3rdzrandom_table_gen._rvs_patefield1ror5rv)r{r|r}r~rnrrXr[rr staticmethodrrX classmethodrYrbrcrdrrs@r3rArAs@D*.8IV&0P "D%)D.@`< 2 2 E EEEEEr5rAc2eZdZdddZdZdZdZddZy) rFNr/ct|_jj||_fd}|j_y)NcjSrv)_params)rrrgs r3rz9random_table_frozen.__init__.._process_parameters?s << r5)rArrrw)rgrGrHrrs` r3rnzrandom_table_frozen.__init__:s8%d+ zz55c3?  )< &r5c<|jj|ddSrv)rrXrs r3rXzrandom_table_frozen.logpmfCszz  D$//r5c<|jj|ddSrv)rr[rs r3r[zrandom_table_frozen.pmfFszz~~at,,r5c:|jjddSrv)rrrys r3rzrandom_table_frozen.meanIszztT**r5cB|jjdd|||S)NrU)rr)rgrrVrs r3rzrandom_table_frozen.rvsLs'zz~~dDtF+79 9r5r)r{r|r}rnrXr[rrr.r5r3rFrF9s)-=0-+9r5rFzprow : array_like Sum of table entries in each row. col : array_like Sum of table entries in each column.zx : array-like Two-dimensional table of non-negative integers, or a multi-dimensional array with the last two dimensions corresponding with the tables.zThe row and column vectors must be one-dimensional, not empty, and each sum up to the same value. They cannot contain negative or noninteger entries.z Parameters ---------- )r _doc_row_col_doc_x_doc_mean_params_doc_row_col_note)r|r~rcVtj|xs |j||_yrv)rrr~)objdocdicttemplates r3_docfillr{s""8#:s{{GDCKr5)rXr[rrc:eZdZdZdfd ZddZdZddZxZS)uniform_direction_genaA vector-valued uniform direction. Return a random direction (unit vector). The `dim` keyword specifies the dimensionality of the space. Methods ------- rvs(dim=None, size=1, random_state=None) Draw random directions. Parameters ---------- dim : scalar Dimension of directions. seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional Used for drawing random variates. If `seed` is `None`, the `~np.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with seed. If `seed` is already a ``RandomState`` or ``Generator`` instance, then that object is used. Default is `None`. Notes ----- This distribution generates unit vectors uniformly distributed on the surface of a hypersphere. These can be interpreted as random directions. For example, if `dim` is 3, 3D vectors from the surface of :math:`S^2` will be sampled. References ---------- .. [1] Marsaglia, G. (1972). "Choosing a Point from the Surface of a Sphere". Annals of Mathematical Statistics. 43 (2): 645-646. Examples -------- >>> import numpy as np >>> from scipy.stats import uniform_direction >>> x = uniform_direction.rvs(3) >>> np.linalg.norm(x) 1. This generates one random direction, a vector on the surface of :math:`S^2`. Alternatively, the object may be called (as a function) to return a frozen distribution with fixed `dim` parameter. Here, we create a `uniform_direction` with ``dim=3`` and draw 5 observations. The samples are then arranged in an array of shape 5x3. >>> rng = np.random.default_rng() >>> uniform_sphere_dist = uniform_direction(3) >>> unit_vectors = uniform_sphere_dist.rvs(5, random_state=rng) >>> unit_vectors array([[ 0.56688642, -0.1332634 , -0.81294566], [-0.427126 , -0.74779278, 0.50830044], [ 0.3793989 , 0.92346629, 0.05715323], [ 0.36428383, -0.92449076, -0.11231259], [-0.27733285, 0.94410968, -0.17816678]]) clt||tj|j|_yrvrtrs r3rnzuniform_direction_gen.__init__rur5ct||S)z}Create a frozen n-dimensional uniform direction distribution. See `uniform_direction` for more information. r/)uniform_direction_frozenrxs r3rzuniform_direction_gen.__call__s ($77r5c|(tj|r|dks|t|k7r tdt|S)rzrzMDimension of vector must be specified, and must be an integer greater than 0.r{r|s r3rz)uniform_direction_gen._process_parameterssB ;bkk#.#'SCH_FG G3xr5c|j|}|tjgt}tj|}|j |}t |||}|S)a{Draw random samples from S(N-1). Parameters ---------- dim : integer Dimension of space (N). size : int or tuple of ints, optional Given a shape of, for example, (m,n,k), m*n*k samples are generated, and packed in an m-by-n-by-k arrangement. Because each sample is N-dimensional, the output shape is (m,n,k,N). If no shape is specified, a single (N-D) sample is returned. random_state : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional Pseudorandom number generator state used to generate resamples. If `random_state` is ``None`` (or `np.random`), the `numpy.random.RandomState` singleton is used. If `random_state` is an int, a new ``RandomState`` instance is used, seeded with `random_state`. If `random_state` is already a ``Generator`` or ``RandomState`` instance then that instance is used. Returns ------- rvs : ndarray Random direction vectors rJ)rr>rKrOr r_sample_uniform_direction)rgrrrrs r3rzuniform_direction_gen.rvssZ>--l; <88Bc*D}}T"&&s++C|Dr5rvrrrs@r3rrs?B68'r5rceZdZddZddZy)rNcdt||_|jj||_y)aCreate a frozen n-dimensional uniform direction distribution. Parameters ---------- dim : int Dimension of matrices seed : {None, int, `numpy.random.Generator`, `numpy.random.RandomState`}, optional If `seed` is None (or `np.random`), the `numpy.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with `seed`. If `seed` is already a ``Generator`` or ``RandomState`` instance then that instance is used. Examples -------- >>> from scipy.stats import uniform_direction >>> x = uniform_direction(3) >>> x.rvs() N)rrrrrxs r3rnz!uniform_direction_frozen.__init__ s&0+40 ::11#6r5cP|jj|j||Srvrr$s r3rzuniform_direction_frozen.rvs'rr5rrr.r5r3rr s 76rorQrXr)rrr samples_shapers r3rr+sF IIdC(M**=9G ryy~~gB~>>G Nr5aalpha : array_like The concentration parameters. The number of entries along the last axis determines the dimensionality of the distribution. Each entry must be strictly positive. n : int or array_like The number of trials. Each element must be a non-negative integer. )$_dirichlet_mn_doc_default_callparamsrctj|}tj|}|l tj||\}}tj|}tj |dkstj ||k7r td|}tj |dkr tdtj|}tj |dkstj ||k7r td|}tj |d}tj||\}}||||fS||||fS#t$r}d}t||d}~wwxYw)Nz&`x` and `alpha` must be broadcastable.rz,`x` must contain only non-negative integers.z*`alpha` must contain only positive values.z#`n` must be a non-negative integer.r7rp)r>rUrr[floorrrc)rlrrNrrlx_intn_int sum_alphas r3'_dirichlet_multinomial_check_parametersrPs; JJu E 1 A} )**1e4HAu   66!a%=BFF1:.KL L  vveqjEFF HHQKE vva!e}qEz*>?? Au2&I&&y!4LIq$%IE9a KE9a3KK) ):CS/q ( )sE E'E""E'cJeZdZdZd fd Zd dZdZdZdZdZ dZ xZ S) dirichlet_multinomial_gena| A Dirichlet multinomial random variable. The Dirichlet multinomial distribution is a compound probability distribution: it is the multinomial distribution with number of trials `n` and class probabilities ``p`` randomly sampled from a Dirichlet distribution with concentration parameters ``alpha``. Methods ------- logpmf(x, alpha, n): Log of the probability mass function. pmf(x, alpha, n): Probability mass function. mean(alpha, n): Mean of the Dirichlet multinomial distribution. var(alpha, n): Variance of the Dirichlet multinomial distribution. cov(alpha, n): The covariance of the Dirichlet multinomial distribution. Parameters ---------- %(_dirichlet_mn_doc_default_callparams)s %(_doc_random_state)s See Also -------- scipy.stats.dirichlet : The dirichlet distribution. scipy.stats.multinomial : The multinomial distribution. References ---------- .. [1] Dirichlet-multinomial distribution, Wikipedia, https://www.wikipedia.org/wiki/Dirichlet-multinomial_distribution Examples -------- >>> from scipy.stats import dirichlet_multinomial Get the PMF >>> n = 6 # number of trials >>> alpha = [3, 4, 5] # concentration parameters >>> x = [1, 2, 3] # counts >>> dirichlet_multinomial.pmf(x, alpha, n) 0.08484162895927604 If the sum of category counts does not equal the number of trials, the probability mass is zero. >>> dirichlet_multinomial.pmf(x, alpha, n=7) 0.0 Get the log of the PMF >>> dirichlet_multinomial.logpmf(x, alpha, n) -2.4669689491013327 Get the mean >>> dirichlet_multinomial.mean(alpha, n) array([1.5, 2. , 2.5]) Get the variance >>> dirichlet_multinomial.var(alpha, n) array([1.55769231, 1.84615385, 2.01923077]) Get the covariance >>> dirichlet_multinomial.cov(alpha, n) array([[ 1.55769231, -0.69230769, -0.86538462], [-0.69230769, 1.84615385, -1.15384615], [-0.86538462, -1.15384615, 2.01923077]]) Alternatively, the object may be called (as a function) to fix the `alpha` and `n` parameters, returning a "frozen" Dirichlet multinomial random variable. >>> dm = dirichlet_multinomial(alpha, n) >>> dm.pmf(x) 0.08484162895927579 All methods are fully vectorized. Each element of `x` and `alpha` is a vector (along the last axis), each element of `n` is an integer (scalar), and the result is computed element-wise. >>> x = [[1, 2, 3], [4, 5, 6]] >>> alpha = [[1, 2, 3], [4, 5, 6]] >>> n = [6, 15] >>> dirichlet_multinomial.pmf(x, alpha, n) array([0.06493506, 0.02626937]) >>> dirichlet_multinomial.cov(alpha, n).shape # both covariance matrices (2, 3, 3) Broadcasting according to standard NumPy conventions is supported. Here, we have four sets of concentration parameters (each a two element vector) for each of three numbers of trials (each a scalar). >>> alpha = [[3, 4], [4, 5], [5, 6], [6, 7]] >>> n = [[6], [7], [8]] >>> dirichlet_multinomial.mean(alpha, n).shape (3, 4, 2) cvt||tj|jt |_yrv)rrnrrr~dirichlet_mn_docdict_paramsrs r3rnz"dirichlet_multinomial_gen.__init__s, '' (CE r5ct|||Sr)dirichlet_multinomial_frozen)rgrlrrs r3rz"dirichlet_multinomial_gen.__call__s+E14@@r5ct|||\}}}}tjt|t|dzzt||zz }|t||zt|t|dzzz j dz }tj |||j dk7tj |dS)aThe log of the probability mass function. Parameters ---------- x: ndarray Category counts (non-negative integers). Must be broadcastable with shape parameter ``alpha``. If multidimensional, the last axis must correspond with the categories. %(_dirichlet_mn_doc_default_callparams)s Returns ------- out: ndarray or scalar Log of the probability mass function. rr7rpr.)rr>rUr rcplacer)rgrNrlrrSar2s r3rXz dirichlet_multinomial_gen.logpmfs$>eQJ 2q!jj"Q7(1r6:JJK Q8A;!a%#@AFFBFOO a155b5>)BFF732wr5cNtj|j|||S)aProbability mass function for a Dirichlet multinomial distribution. Parameters ---------- x: ndarray Category counts (non-negative integers). Must be broadcastable with shape parameter ``alpha``. If multidimensional, the last axis must correspond with the categories. %(_dirichlet_mn_doc_default_callparams)s Returns ------- out: ndarray or scalar Probability mass function. rZ)rgrNrlrs r3r[zdirichlet_multinomial_gen.pmfs "vvdkk!UA.//r5ct||\}}}|dtjf|dtjf}}||z|z S)zMean of a Dirichlet multinomial distribution. Parameters ---------- %(_dirichlet_mn_doc_default_callparams)s Returns ------- out: ndarray Mean of a Dirichlet multinomial distribution. .rr>rrgrlrrrs r3rzdirichlet_multinomial_gen.meansG;5!D2q#rzz/"BsBJJ$721urzr5ct||\}}}|dtjf|dtjf}}||z|z d||z z z||zzd|zz S)abThe variance of the Dirichlet multinomial distribution. Parameters ---------- %(_dirichlet_mn_doc_default_callparams)s Returns ------- out: array_like The variances of the components of the distribution. This is the diagonal of the covariance matrix of the distribution. .rrrs r3rzdirichlet_multinomial_gen.var!sf;5!D2q#rzz/"BsBJJ$721urzQ2X&!b&1QV<rrr) rgrlrrrraiajriis r3rzdirichlet_multinomial_gen.cov3s;5!D2q#''1-#rzz2::-.3 BJJ3N0O2a#$qbjj!);'<<b4i"'!QV,B7 YYsyy} %CRK r5rv) r{r|r}r~rnrrXr[rrrrrs@r3rrqs/iTE A20&"=$r5rc2eZdZddZdZdZdZdZdZy) rNc`t||\}}}||_||_t||_yrv)rrlrrr)rgrlrrrs r3rnz%dirichlet_multinomial_frozen.__init__Ps.>uaH r1 .t4 r5cd|jj||j|jSrv)rrXrlrrs r3rXz#dirichlet_multinomial_frozen.logpmfVs#zz  DJJ77r5cd|jj||j|jSrv)rr[rlrrs r3r[z dirichlet_multinomial_frozen.pmfYs!zz~~aTVV44r5cb|jj|j|jSrv)rrrlrrys r3rz!dirichlet_multinomial_frozen.mean\szztzz46622r5cb|jj|j|jSrv)rrrlrrys r3rz dirichlet_multinomial_frozen.var_zz~~djj$&&11r5cb|jj|j|jSrv)rrrlrrys r3rz dirichlet_multinomial_frozen.covbrr5rv) r{r|r}rnrXr[rrrr.r5r3rrOs 5 85322r5r)rXr[rrrceZdZdZdfd ZddZdZdZdZdZ ddZ dd Z d Z d Z d Zd ZdZddZdZddZdZxZS)vonmises_fisher_gena$A von Mises-Fisher variable. The `mu` keyword specifies the mean direction vector. The `kappa` keyword specifies the concentration parameter. Methods ------- pdf(x, mu=None, kappa=1) Probability density function. logpdf(x, mu=None, kappa=1) Log of the probability density function. rvs(mu=None, kappa=1, size=1, random_state=None) Draw random samples from a von Mises-Fisher distribution. entropy(mu=None, kappa=1) Compute the differential entropy of the von Mises-Fisher distribution. fit(data) Fit a von Mises-Fisher distribution to data. Parameters ---------- mu : array_like Mean direction of the distribution. Must be a one-dimensional unit vector of norm 1. kappa : float Concentration parameter. Must be positive. seed : {None, int, np.random.RandomState, np.random.Generator}, optional Used for drawing random variates. If `seed` is `None`, the `~np.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with seed. If `seed` is already a ``RandomState`` or ``Generator`` instance, then that object is used. Default is `None`. See Also -------- scipy.stats.vonmises : Von-Mises Fisher distribution in 2D on a circle uniform_direction : uniform distribution on the surface of a hypersphere Notes ----- The von Mises-Fisher distribution is a directional distribution on the surface of the unit hypersphere. The probability density function of a unit vector :math:`\mathbf{x}` is .. math:: f(\mathbf{x}) = \frac{\kappa^{d/2-1}}{(2\pi)^{d/2}I_{d/2-1}(\kappa)} \exp\left(\kappa \mathbf{\mu}^T\mathbf{x}\right), where :math:`\mathbf{\mu}` is the mean direction, :math:`\kappa` the concentration parameter, :math:`d` the dimension and :math:`I` the modified Bessel function of the first kind. As :math:`\mu` represents a direction, it must be a unit vector or in other words, a point on the hypersphere: :math:`\mathbf{\mu}\in S^{d-1}`. :math:`\kappa` is a concentration parameter, which means that it must be positive (:math:`\kappa>0`) and that the distribution becomes more narrow with increasing :math:`\kappa`. In that sense, the reciprocal value :math:`1/\kappa` resembles the variance parameter of the normal distribution. The von Mises-Fisher distribution often serves as an analogue of the normal distribution on the sphere. Intuitively, for unit vectors, a useful distance measure is given by the angle :math:`\alpha` between them. This is exactly what the scalar product :math:`\mathbf{\mu}^T\mathbf{x}=\cos(\alpha)` in the von Mises-Fisher probability density function describes: the angle between the mean direction :math:`\mathbf{\mu}` and the vector :math:`\mathbf{x}`. The larger the angle between them, the smaller the probability to observe :math:`\mathbf{x}` for this particular mean direction :math:`\mathbf{\mu}`. In dimensions 2 and 3, specialized algorithms are used for fast sampling [2]_, [3]_. For dimensions of 4 or higher the rejection sampling algorithm described in [4]_ is utilized. This implementation is partially based on the geomstats package [5]_, [6]_. .. versionadded:: 1.11 References ---------- .. [1] Von Mises-Fisher distribution, Wikipedia, https://en.wikipedia.org/wiki/Von_Mises%E2%80%93Fisher_distribution .. [2] Mardia, K., and Jupp, P. Directional statistics. Wiley, 2000. .. [3] J. Wenzel. Numerically stable sampling of the von Mises Fisher distribution on S2. https://www.mitsuba-renderer.org/~wenzel/files/vmf.pdf .. [4] Wood, A. Simulation of the von mises fisher distribution. Communications in statistics-simulation and computation 23, 1 (1994), 157-164. https://doi.org/10.1080/03610919408813161 .. [5] geomstats, Github. MIT License. Accessed: 06.01.2023. https://github.com/geomstats/geomstats .. [6] Miolane, N. et al. Geomstats: A Python Package for Riemannian Geometry in Machine Learning. Journal of Machine Learning Research 21 (2020). http://jmlr.org/papers/v21/19-027.html Examples -------- **Visualization of the probability density** Plot the probability density in three dimensions for increasing concentration parameter. The density is calculated by the ``pdf`` method. >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from scipy.stats import vonmises_fisher >>> from matplotlib.colors import Normalize >>> n_grid = 100 >>> u = np.linspace(0, np.pi, n_grid) >>> v = np.linspace(0, 2 * np.pi, n_grid) >>> u_grid, v_grid = np.meshgrid(u, v) >>> vertices = np.stack([np.cos(v_grid) * np.sin(u_grid), ... np.sin(v_grid) * np.sin(u_grid), ... np.cos(u_grid)], ... axis=2) >>> x = np.outer(np.cos(v), np.sin(u)) >>> y = np.outer(np.sin(v), np.sin(u)) >>> z = np.outer(np.ones_like(u), np.cos(u)) >>> def plot_vmf_density(ax, x, y, z, vertices, mu, kappa): ... vmf = vonmises_fisher(mu, kappa) ... pdf_values = vmf.pdf(vertices) ... pdfnorm = Normalize(vmin=pdf_values.min(), vmax=pdf_values.max()) ... ax.plot_surface(x, y, z, rstride=1, cstride=1, ... facecolors=plt.cm.viridis(pdfnorm(pdf_values)), ... linewidth=0) ... ax.set_aspect('equal') ... ax.view_init(azim=-130, elev=0) ... ax.axis('off') ... ax.set_title(rf"$\kappa={kappa}$") >>> fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(9, 4), ... subplot_kw={"projection": "3d"}) >>> left, middle, right = axes >>> mu = np.array([-np.sqrt(0.5), -np.sqrt(0.5), 0]) >>> plot_vmf_density(left, x, y, z, vertices, mu, 5) >>> plot_vmf_density(middle, x, y, z, vertices, mu, 20) >>> plot_vmf_density(right, x, y, z, vertices, mu, 100) >>> plt.subplots_adjust(top=1, bottom=0.0, left=0.0, right=1.0, wspace=0.) >>> plt.show() As we increase the concentration parameter, the points are getting more clustered together around the mean direction. **Sampling** Draw 5 samples from the distribution using the ``rvs`` method resulting in a 5x3 array. >>> rng = np.random.default_rng() >>> mu = np.array([0, 0, 1]) >>> samples = vonmises_fisher(mu, 20).rvs(5, random_state=rng) >>> samples array([[ 0.3884594 , -0.32482588, 0.86231516], [ 0.00611366, -0.09878289, 0.99509023], [-0.04154772, -0.01637135, 0.99900239], [-0.14613735, 0.12553507, 0.98126695], [-0.04429884, -0.23474054, 0.97104814]]) These samples are unit vectors on the sphere :math:`S^2`. To verify, let us calculate their euclidean norms: >>> np.linalg.norm(samples, axis=1) array([1., 1., 1., 1., 1.]) Plot 20 observations drawn from the von Mises-Fisher distribution for increasing concentration parameter :math:`\kappa`. The red dot highlights the mean direction :math:`\mu`. >>> def plot_vmf_samples(ax, x, y, z, mu, kappa): ... vmf = vonmises_fisher(mu, kappa) ... samples = vmf.rvs(20) ... ax.plot_surface(x, y, z, rstride=1, cstride=1, linewidth=0, ... alpha=0.2) ... ax.scatter(samples[:, 0], samples[:, 1], samples[:, 2], c='k', s=5) ... ax.scatter(mu[0], mu[1], mu[2], c='r', s=30) ... ax.set_aspect('equal') ... ax.view_init(azim=-130, elev=0) ... ax.axis('off') ... ax.set_title(rf"$\kappa={kappa}$") >>> mu = np.array([-np.sqrt(0.5), -np.sqrt(0.5), 0]) >>> fig, axes = plt.subplots(nrows=1, ncols=3, ... subplot_kw={"projection": "3d"}, ... figsize=(9, 4)) >>> left, middle, right = axes >>> plot_vmf_samples(left, x, y, z, mu, 5) >>> plot_vmf_samples(middle, x, y, z, mu, 20) >>> plot_vmf_samples(right, x, y, z, mu, 100) >>> plt.subplots_adjust(top=1, bottom=0.0, left=0.0, ... right=1.0, wspace=0.) >>> plt.show() The plots show that with increasing concentration :math:`\kappa` the resulting samples are centered more closely around the mean direction. **Fitting the distribution parameters** The distribution can be fitted to data using the ``fit`` method returning the estimated parameters. As a toy example let's fit the distribution to samples drawn from a known von Mises-Fisher distribution. >>> mu, kappa = np.array([0, 0, 1]), 20 >>> samples = vonmises_fisher(mu, kappa).rvs(1000, random_state=rng) >>> mu_fit, kappa_fit = vonmises_fisher.fit(samples) >>> mu_fit, kappa_fit (array([0.01126519, 0.01044501, 0.99988199]), 19.306398751730995) We see that the estimated parameters `mu_fit` and `kappa_fit` are very close to the ground truth parameters. c$t||yrvrCrs r3rnzvonmises_fisher_gen.__init__DrDr5ct|||S)zsCreate a frozen von Mises-Fisher distribution. See `vonmises_fisher_frozen` for more information. r/)vonmises_fisher_frozenrgr-kappars r3rzvonmises_fisher_gen.__call__Gs &b%d;;r5ctj|}|jdkDr tdtjtj j |ds td|jdkDs tdd}tj|r|dkr t|t|dk(r td |j}|||fS) z~ Infer dimensionality from mu and ensure that mu is a one-dimensional unit vector and kappa positive. rz%'mu' must have one-dimensional shape.rz%'mu' must be a unit vector of norm 1.z$'mu' must have at least two entries.z"'kappa' must be a positive scalar.rrzFor 'kappa=0' the von Mises-Fisher distribution becomes the uniform distribution on the sphere surface. Consider using 'scipy.stats.uniform_direction' instead.) r>rUr0r[allcloserXrrrrL)rgr-rkappa_error_msgrs r3rz'vonmises_fisher_gen._process_parametersNs ZZ^ 77Q;DE E{{299>>"-r2DE Eww{CD D>{{5!UQY_- - <2 HI IggB~r5c|jd|k7r tdtjtjj |dds d}t|y)Nr7znThe dimensionality of the last axis of 'x' must match the dimensionality of the von Mises Fisher distribution.rpr8'x' must be unit vectors of norm 1 along last dimension.)rr[r>rrXr)rgrNrrls r3_check_data_vs_distz'vonmises_fisher_gen._check_data_vs_distfsY 772;# >? ?{{299>>!">5r:LCS/ !;r5cd|z}d|dz ztj|z|tzz tjt|dz |z |z SNr r,r)r>rdrr rgrrhalfdims r3_log_norm_factorz$vonmises_fisher_gen._log_norm_factorosX)sQwu -(0BBs7Q;./0278 9r5ctj|}|j||tjd||}|j ||||zzS)zLog of the von Mises-Fisher probability density function. As this function does no argument checking, it should not be called directly; use 'logpdf' instead. z i,...i->...)r>rUrrSr)rgrNrr-r dotproductss r3rzvonmises_fisher_gen._logpdf}sP JJqM   C(ii r15 $$S%05;3FFFr5cV|j||\}}}|j||||S)aLog of the von Mises-Fisher probability density function. Parameters ---------- x : array_like Points at which to evaluate the log of the probability density function. The last axis of `x` must correspond to unit vectors of the same dimensionality as the distribution. mu : array_like, default: None Mean direction of the distribution. Must be a one-dimensional unit vector of norm 1. kappa : float, default: 1 Concentration parameter. Must be positive. Returns ------- logpdf : ndarray or scalar Log of the probability density function evaluated at `x`. )rrrgrNr-rrs r3rzvonmises_fisher_gen.logpdfs1*11"e<R||AsB..r5c||j||\}}}tj|j||||S)aVon Mises-Fisher probability density function. Parameters ---------- x : array_like Points at which to evaluate the probability density function. The last axis of `x` must correspond to unit vectors of the same dimensionality as the distribution. mu : array_like Mean direction of the distribution. Must be a one-dimensional unit vector of norm 1. kappa : float Concentration parameter. Must be positive. Returns ------- pdf : ndarray or scalar Probability density function evaluated at `x`. )rr>rrrs r3rzvonmises_fisher_gen.pdfs:*11"e<Rvvdll1c2u566r5ctj|d|d}|j|||}tjtj|tj |gd}|S)z In 2D, the von Mises-Fisher distribution reduces to the von Mises distribution which can be efficiently sampled by numpy. This method is much faster than the general rejection sampling based algorithm. rrrr7rp)r>arctan2vonmisesstackcossin)rgr-rrr mean_angle angle_samplesrs r3_rvs_2dzvonmises_fisher_gen._rvs_2dsbZZ1r!u- $--j%d-K ((BFF=1266-3HI "$r5c |d}n|}|j|}dtj|d|z tjd|zzz|z z}tjdtj |z }t d||}tj|||dz||dzgd}|tj|}|S) ah Generate samples from a von Mises-Fisher distribution with mu = [1, 0, 0] and kappa. Samples then have to be rotated towards the desired mean direction mu. This method is much faster than the general rejection sampling based algorithm. Reference: https://www.mitsuba-renderer.org/~wenzel/files/vmf.pdf rrr=r,r).rr7rp) randomr>rdrr_rrrr/) rgrrr sample_sizerNtemp uniformcirclers r3_rvs_3dzvonmises_fisher_gen._rvs_3ds <KK    , R!Vrvvb5j'999:5@ @wwrBIIaL()1![,O ((AtmF&;; =#88: "$ <jj)Gr5cx|dz }|.tj|s|f}tj|}nd}tjd|dzz|dzz}d|z|z|z }|dk(r|dz |dzz|dzd z |d zzz }d |z d |zz } || z|tj dtj |zdtj |zz zz} d} tj|f} d |z} | |kr|j| | || z }dd|z|zz dd|z |zz z }|j|| z }||z|tj d|z|z ||zzd|zz zz| z tj |kD}tj|}||| | | |z| |z } | |krt|| |}tjdtjd| dzz |}tj| d|gd}||j||fz}|Stj|}|S)a$ Generate samples from a n-dimensional von Mises-Fisher distribution with mu = [1, 0, ..., 0] and kappa via rejection sampling. Samples then have to be rotated towards the desired mean direction mu. Reference: https://doi.org/10.1080/03610919408813161 rrrr,r=rgr@rrr rz...,...i->...irrp)r>rrrr_rdlog1prbetarrcrrSrrr/)rgrrrr dim_minus_one n_samplesr_ envelop_paramnode correction n_acceptedrNrsym_betacoord_x accept_tol criterion accepted_iter coord_restrs r3_rejection_samplingz'vonmises_fisher_gen._rejection_samplingsa  ;;t$x $IIwwq5B;!);;<ed*m; A +1_ucz9,a/2UCZ?@M]"rM'9:dl]RVVM%::BHH]334&55  HHi] # %9$#(('.7*.D)FHA -99Q&(224G &,,Y-CDJ2661}+y7IAjm3 4 - 'J%9$(/}j/;= YY bgga!q&j1:? ..!I, !;!D  oodcWn5Gjj)Gr5ctj|f}d|d<tj|dddftj|dz |fg}tjj tj |\}}tj tj||dddfdddf|rd}nd}tjd|||z}|S)aA QR decomposition is used to find the rotation that maps the north pole (1, 0,...,0) to the vector mu. This rotation is then applied to all samples. Parameters ---------- samples: array_like, shape = [..., n] mu : array-like, shape=[n, ] Point to parametrise the rotation. Returns ------- samples : rotated samples rrNrr7z ij,...j->...i) r>rrrXrrRrmatmulrS) rgrr-r base_pointembedded rotmatrixrZrotsigns r3_rotate_samplesz#vonmises_fisher_gen._rotate_samples-s XXsg&  1 >>2dAg;#'30H"IJyy||BLL$:; 1 ;;ryyJq$w,?@AF KGG))OY@7Jr5c|dk(r|j||||}n-|dk(r|j|||}n|j||||}|dk7r|j|||}|S)Nr,r)rrrr)rgrr-rrrrs r3rzvonmises_fisher_gen._rvsJsq !8ll2udLAG AXll5$ =G..sE4/;=G !8**7B> ?r5cR|j||\}}}|j||S)aCompute the differential entropy of the von Mises-Fisher distribution. Parameters ---------- mu : array_like, default: None Mean direction of the distribution. Must be a one-dimensional unit vector of norm 1. kappa : float, default: 1 Concentration parameter. Must be positive. Returns ------- h : scalar Entropy of the von Mises-Fisher distribution. r)rgr-rrrZs r3r zvonmises_fisher_gen.entropys-$00U; Q}}S%((r5c tj|}|jdk7r tdtjtj j |dds d}t||jd}t|}|j}|j d|z fd}t|d d }|j}||fS) aFit the von Mises-Fisher distribution to data. Parameters ---------- x : array-like Data the distribution is fitted to. Must be two dimensional. The second axis of `x` must be unit vectors of norm 1 and determine the dimensionality of the fitted von Mises-Fisher distribution. Returns ------- mu : ndarray Estimated mean direction. kappa : float Estimated concentration parameter. r,z'x' must be two dimensional.r7rprrr cBtdz g|}|d|dz z S)Nrr)r )r bessel_valsrrs r3solve_for_kappaz0vonmises_fisher_gen.fit..solve_for_kappas0w! 4e+a.014 4r5brentq)g:0yE>geA)rVbracket) r>rUr0r[rrXrrrmean_directionmean_resultant_lengthrroot) rgrNrlrdirstatsr-rroot_resrrrs @@r3rzvonmises_fisher_gen.fits( JJqM 66Q;;< <{{299>>!">5r:LCS/ !ggbk%Q'  $ $  * *) 5x'24 5yr5rvNrNrr)r{r|r}r~rnrrrrrrrrrrrrrrXr rrrs@r3rrqscQd<0" 9 G/070  9r5rcXeZdZdZd dZdZddZdZddZddZ dd Z d Z d Z dd Z y)normal_inverse_gamma_gena2Normal-inverse-gamma distribution. The normal-inverse-gamma distribution is the conjugate prior of a normal distribution with unknown mean and variance. Methods ------- pdf(x, s2, mu=0, lmbda=1, a=1, b=1) Probability density function. logpdf(x, s2, mu=0, lmbda=1, a=1, b=1) Log of the probability density function. mean(mu=0, lmbda=1, a=1, b=1) Distribution mean. var(mu=0, lmbda=1, a=1, b=1) Distribution variance. rvs(mu=0, lmbda=1, a=1, b=1, size=None, random_state=None) Draw random samples. Parameters ---------- mu, lmbda, a, b : array_like Shape parameters of the distribution. See notes. seed : {None, int, np.random.RandomState, np.random.Generator}, optional Used for drawing random variates. If `seed` is `None`, the `~np.random.RandomState` singleton is used. If `seed` is an int, a new ``RandomState`` instance is used, seeded with seed. If `seed` is already a ``RandomState`` or ``Generator`` instance, then that object is used. Default is `None`. See Also -------- norm invgamma Notes ----- The probability density function of `normal_inverse_gamma` is: .. math:: f(x, \sigma^2; \mu, \lambda, \alpha, \beta) = \frac{\sqrt{\lambda}}{\sqrt{2 \pi \sigma^2}} \frac{\beta^\alpha}{\Gamma(\alpha)} \left( \frac{1}{\sigma^2} \right)^{\alpha + 1} \exp \left(- \frac{2 \beta + \lambda (x - \mu)^2} {2 \sigma^2} \right) where all parameters are real and finite, and :math:`\sigma^2 > 0`, :math:`\lambda > 0`, :math:`\alpha > 0`, and :math:`\beta > 0`. Methods ``normal_inverse_gamma.pdf`` and ``normal_inverse_gamma.logpdf`` accept `x` and `s2` for arguments :math:`x` and :math:`\sigma^2`. All methods accept `mu`, `lmbda`, `a`, and `b` for shape parameters :math:`\mu`, :math:`\lambda`, :math:`\alpha`, and :math:`\beta`, respectively. .. versionadded:: 1.15 References ---------- .. [1] Normal-inverse-gamma distribution, Wikipedia, https://en.wikipedia.org/wiki/Normal-inverse-gamma_distribution Examples -------- Suppose we wish to investigate the relationship between the normal-inverse-gamma distribution and the inverse gamma distribution. >>> import numpy as np >>> from scipy import stats >>> import matplotlib.pyplot as plt >>> rng = np.random.default_rng(527484872345) >>> mu, lmbda, a, b = 0, 1, 20, 20 >>> norm_inv_gamma = stats.normal_inverse_gamma(mu, lmbda, a, b) >>> inv_gamma = stats.invgamma(a, scale=b) One approach is to compare the distribution of the `s2` elements of random variates against the PDF of an inverse gamma distribution. >>> _, s2 = norm_inv_gamma.rvs(size=10000, random_state=rng) >>> bins = np.linspace(s2.min(), s2.max(), 50) >>> plt.hist(s2, bins=bins, density=True, label='Frequency density') >>> s2 = np.linspace(s2.min(), s2.max(), 300) >>> plt.plot(s2, inv_gamma.pdf(s2), label='PDF') >>> plt.xlabel(r'$\sigma^2$') >>> plt.ylabel('Frequency density / PMF') >>> plt.show() Similarly, we can compare the marginal distribution of `s2` against an inverse gamma distribution. >>> from scipy.integrate import quad_vec >>> from scipy import integrate >>> s2 = np.linspace(0.5, 3, 6) >>> res = quad_vec(lambda x: norm_inv_gamma.pdf(x, s2), -np.inf, np.inf)[0] >>> np.allclose(res, inv_gamma.pdf(s2)) True The sample mean is comparable to the mean of the distribution. >>> x, s2 = norm_inv_gamma.rvs(size=10000, random_state=rng) >>> x.mean(), s2.mean() (np.float64(-0.005254750127304425), np.float64(1.050438111436508)) >>> norm_inv_gamma.mean() (np.float64(0.0), np.float64(1.0526315789473684)) Similarly, for the variance: >>> x.var(ddof=1), s2.var(ddof=1) (np.float64(1.0546150578185023), np.float64(0.061829865266330754)) >>> norm_inv_gamma.var() (np.float64(1.0526315789473684), np.float64(0.061557402277623886)) Nc"|j|}t||j||}||z dz}t||j||} t j d||||} | j | |j | fS)aDraw random samples from the distribution. Parameters ---------- mu, lmbda, a, b : array_like, optional Shape parameters. `lmbda`, `a`, and `b` must be greater than zero. size : int or tuple of ints, optional Shape of samples to draw. random_state : {None, int, np.random.RandomState, np.random.Generator}, optional Used for drawing random variates. If `random_state` is `None`, the `~np.random.RandomState` singleton is used. If `random_state` is an int, a new ``RandomState`` instance is used, seeded with `random_state`. If `random_state` is already a ``RandomState`` or ``Generator`` instance, then that object is used. Default is `None`. Returns ------- x, s2 : ndarray Random variates. )rr?r )rrr)rrrrr>r;r) rgr-lmbdarrrrs2rrNr;s r3rznormal_inverse_gamma_gen.rvss2--l; aq ! % %4l % Kec! Ru % ) )t, ) OsBq!4xx % 000r5cdtj|tjdtjz|zz z}|tj|ztj|j |j z }|dz tj|z} d|z|||z dzzz d|zz } ||z| z| zSr)r>rdrr rrr; rgrNr r-r rrt1t2t3t4s r3rz normal_inverse_gamma_gen._logpdfs BFF5MBFF1ruu9r>$:: ; rvvay[7??1-44QWW= =1uXr "sUAFQ;&& '1R4 0Bw|b  r5c6|j||||||\}}|d}tjd5tj|j|} dddtj  |dk<tj | |<| dS#1swY8xYw)aLog of the probability density function. Parameters ---------- x, s2 : array_like Arguments. `s2` must be greater than zero. mu, lmbda, a, b : array_like, optional Shape parameters. `lmbda`, `a`, and `b` must be greater than zero. Returns ------- logpdf : ndarray or scalar Log of the probability density function. rrJrONrr.)_process_parameters_pdfr>rNrUrrrS) rgrNr r-r rrrKargsrs r3rznormal_inverse_gamma_gen.logpdfs"44QBq!L  !W [[X & 5ZZ  d 34F 566'rQw&&wbz  5 5s #BBcDtj|dtjz|zz }||ztj|j |j z }d|z |dzz} tjd|z|||z dzzz d|zz } ||z| z| zS)Nr,r)r>r_rr gammarr;rr s r3_pdfznormal_inverse_gamma_gen._pdfs WWUa"%%i"n- . TGMM!$++AGG4 4"fA  VVacE1r6A+--.!B$7 8Bw|b  r5c|j||||||\}}|d}tjd5tj|j|} dddd |dk<tj | |<| dS#1swY)xYw)aThe probability density function. Parameters ---------- x, s2 : array_like Arguments. `s2` must be greater than zero. mu, lmbda, a, b : array_like, optional Shape parameters. `lmbda`, `a`, and `b` must be greater than zero. Returns ------- logpdf : ndarray or scalar The probability density function. rrJrNrr.)rr>rNrUrrS) rgrNr r-r rrrKrrs r3rznormal_inverse_gamma_gen.pdfs"44QBq!L  !W [[X & /**YTYY-.C /B!G vvG 2w  / /s #BB c,|j||||\}}|\}}}}||dkDz}tj|j}tj||dz z }tj||<tj||<|d|dfS)aWThe mean of the distribution. Parameters ---------- mu, lmbda, a, b : array_like, optional Shape parameters. `lmbda` and `b` must be greater than zero, and `a` must be greater than one. Returns ------- x, s2 : ndarray The mean of the distribution. rr.)_process_shapesr>rUrrS) rgr-r rrrKrmean_xmean_s2s r3rznormal_inverse_gamma_gen.mean s,,R1= E1aQU8B$$&**Q!a%[)&&w66bz72;&&r5cT|j||||\}}|\}}}}||dkDz}||dkDz}||dz |zz } |dz|dz dz|dz zz } tj| tj| } } tj| |<tj| |<| d| dfS)a_The variance of the distribution. Parameters ---------- mu, lmbda, a, b : array_like, optional Shape parameters. `lmbda` and `b` must be greater than zero, and `a` must be greater than two. Returns ------- x, s2 : ndarray The variance of the distribution. rr,r.)rr>rUrS) rgr-r rrrKr invalid_x invalid_s2var_xvar_s2s r3rznormal_inverse_gamma_gen.var#s,,R1= E1aAh& Qx' a!eu_%A!a%!q1u-. 5)2::f+=v66iVVzRy&*$$r5ctj||||||}tjdgd|D}|D cgc]} | j|d}} |\}}}}}}|dkD|dkDz|dkDz} | |fScc} w)Nrc34K|]}|jywrvrJ.0args r3 zCnormal_inverse_gamma_gen._process_parameters_pdf..?%@Ccii%@Frrr>rr;r) rgrNr r-r rrrr;r'rKs r3rz0normal_inverse_gamma_gen._process_parameters_pdf=s""1b"eQ:sA%@4%@A9=># 5u ->>!%2r5!QQY1q5)QU34}?sA7ctj||||}tjdgd|D}|Dcgc]}|j|d}}|\}}}}|dkD|dkDz|dkDz}||fScc}w)Nrc34K|]}|jywrvrJr%s r3r(z;normal_inverse_gamma_gen._process_shapes..Gr)r*Fr+rr,) rgr-r rrrr;r'rKs r3rz(normal_inverse_gamma_gen._process_shapesEs""2ua3sA%@4%@A9=># 5u ->>E1aQY1q5)QU34}?sA3c"t|||||Sr)normal_inverse_gamma_frozenrgr-r rrrs r3rz!normal_inverse_gamma_gen.__call__Ms*2uaFFr5)rrrrNN)rrrrrrrrN)r{r|r}r~rrrrrrrrrrr.r5r3rr4s=sh1@!4!4'0%4Gr5rc4eZdZddZdZdZdZdZd dZy) r0Nc:t||_||||f|_yrv)rr_shapesr1s r3rnz$normal_inverse_gamma_frozen.__init__Vs-d3 5!Q r5cR|jj||g|jSrv)rrr5rgrNr s r3rz"normal_inverse_gamma_frozen.logpdfZs$ tzz  B666r5cR|jj||g|jSrv)rrr5r7s r3rznormal_inverse_gamma_frozen.pdf]s"tzz~~a3dll33r5cH|jj|jSrv)rrr5rys r3rz normal_inverse_gamma_frozen.mean`stzz --r5cH|jj|jSrv)rrr5rys r3rznormal_inverse_gamma_frozen.varcstzz~~t||,,r5cP|jj|j||dSr>)rrr5r$s r3rznormal_inverse_gamma_frozen.rvsfstzz~~t||$\RRr5r2r) r{r|r}rnrrrrrr.r5r3r0r0Ts!'74.-Sr5r0)rrrrrr)rrv)rr> threadingnumpyr> scipy.linalgrW scipy._libr scipy.specialrrrrrr r r r scipy._lib.array_api_extra_libarray_api_extrarscipy._lib._utilr scipy.linalg.blasrr_continuous_distnsrr_discrete_distnsrrrr_qmvntrrr _morestatsrscipy.optimizer__all__rdrrr_LOG_PILockMVN_LOCKrr4rHrOrQrrrr_mvn_doc_frozen_callparams_mvn_doc_frozen_callparams_notermvn_docdict_noparamsrrrname__dict__rV method_frozenrr~r'r(_matnorm_doc_frozen_callparams#_matnorm_doc_frozen_callparams_noter,matnorm_docdict_noparamsr*rr0ri _dirichlet_doc_frozen_callparams%_dirichlet_doc_frozen_callparams_noter}dirichlet_docdict_noparamsrmrwryr{rr_wishart_doc_default_callparams_wishart_doc_callparams_note_wishart_doc_frozen_callparams#_wishart_doc_frozen_callparams_noterwishart_docdict_noparamsrrrr r r #_multinomial_doc_default_callparams _multinomial_doc_callparams_note"_multinomial_doc_frozen_callparams'_multinomial_doc_frozen_callparams_noter5multinomial_docdict_noparamsr3r!r7rrr"rwrr#rrr$rrr%rrr_mvt_doc_frozen_callparams_notermvt_docdict_noparamsrrr&_mhg_doc_default_callparams_mhg_doc_callparams_note_mhg_doc_frozen_callparams_mhg_doc_frozen_callparams_notermhg_docdict_noparamsrr'rrAr(rF_ctab_doc_row_col _ctab_doc_x_ctab_doc_row_col_note_ctab_doc_mean_params_ctab_doc_row_col_note_frozen _ctab_docdictr_ctab_docdict_frozenupdaterrr)rrr#_dirichlet_mn_doc_frozen_callparams(_dirichlet_mn_doc_frozen_callparams_noterdirichlet_mn_docdict_noparamsrrrrrr*rrr+r0r.r5r3rws  ***((/2.#!(()& #$ 266!bee)   "&&- 9>>  DK&UUp&&D < < #B$? 8*$> ?*@ .@ F./c8c8P 6JD $ - -d 3F.77=M,F,,V^^-ACM%V%%fnn6HIFN J# "$'B#(G$@*(F$G*`*(`*F "# 69?69v 0ND  ' ' -F(11$7M,F,,V^^-EGM%V%%fnn6LMFN N%! $& )B%*K* *J* ) X;*W8$W8t O >>: FPD  # #D )F$--d3M,F,,24M%V%%fnn6NOFN P# "!#'B# ?8* >?*a  "a  H -5J_5Jt GND  ! !$ 'F"++D1M,F,,02M%V%%fnn6LMFN N]5[]5@  9J9J| <ND  $ $T *F"++D1M,F,,02M%V%%fnn6LMFN N'#$ &("+B' C<* BC* Q4&Q4h  +B+B` 4BD  % %d +F&//5M,F,,46M%V%%fnn&@BFN Bl.l\./<<M,F,,V^^-ACM%V%%fnn6HIFN Jr5