U
    Kvf9E                     @   sV   d Z ddlmZmZ ddlZddlmZ ddlm	Z	 G dd dZ
G dd	 d	eZdS )
z

Which Archimedean is Best?
Extreme Value copulas formulas are based on Genest 2009

References
----------

Genest, C., 2009. Rank-based inference for bivariate extreme-value
copulas. The Annals of Statistics, 37(5), pp.2990-3022.

    )ABCabstractmethodN)stats)utilsc                   @   sB   e Zd ZdZdddZdddZdd	d
ZdddZdddZdS )CopulaDistributiona  Multivariate copula distribution

    Parameters
    ----------
    copula : :class:`Copula` instance
        An instance of :class:`Copula`, e.g. :class:`GaussianCopula`,
        :class:`FrankCopula`, etc.
    marginals : list of distribution instances
        Marginal distributions.
    copargs : tuple
        Parameters for copula

    Notes
    -----
    Status: experimental, argument handling may still change

     c                 C   s    || _ || _|| _t|| _d S N)copula	marginalscop_argslenk_vars)selfr	   r
   r   r   r   L/tmp/pip-unpacked-wheel-2v6byqio/statsmodels/distributions/copula/copulas.py__init__'   s    zCopulaDistribution.__init__   Nc                 C   s   |dkr| j }|dkr"dg| j }| jj|||d}t| jD ]@\}}|jdd|dd|f d   f||  |dd|f< q>|S )a6  Draw `n` in the half-open interval ``[0, 1)``.

        Sample the joint distribution.

        Parameters
        ----------
        nobs : int, optional
            Number of samples to generate in the parameter space.
            Default is 1.
        cop_args : tuple
            Copula parameters. If None, then the copula parameters will be
            taken from the ``cop_args`` attribute created when initiializing
            the instance.
        marg_args : list of tuples
            Parameters for the marginal distributions. It can be None if none
            of the marginal distributions have parameters, otherwise it needs
            to be a list of tuples with the same length has the number of
            marginal distributions. The list can contain empty tuples for
            marginal distributions that do not take parameter arguments.
        random_state : {None, int, numpy.random.Generator}, optional
            If `seed` is None then the legacy singleton NumPy generator.
            This will change after 0.13 to use a fresh NumPy ``Generator``,
            so you should explicitly pass a seeded ``Generator`` if you
            need reproducible results.
            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.

        Returns
        -------
        sample : array_like (n, d)
            Sample from the joint distribution.

        Notes
        -----
        The random samples are generated by creating a sample with uniform
        margins from the copula, and using ``ppf`` to convert uniform margins
        to the one specified by the marginal distribution.

        See Also
        --------
        statsmodels.tools.rng_qrng.check_random_state
        Nr   )nobsargsrandom_stateg      ?gA?)r   r   r	   rvs	enumerater
   Zppf)r   r   r   	marg_argsr   sampleidistr   r   r   r   0   s    -
 zCopulaDistribution.rvsc                 C   s   t |}|dkr| j}|dkr0dg|jd  }g }t| jD ],}|| j| j|d|f f||   q>t 	|}|j
dkr| }| j||S )a  CDF of copula distribution.

        Parameters
        ----------
        y : array_like
            Values of random variable at which to evaluate cdf.
            If 2-dimensional, then components of multivariate random variable
            need to be in columns
        cop_args : tuple
            Copula parameters. If None, then the copula parameters will be
            taken from the ``cop_args`` attribute created when initiializing
            the instance.
        marg_args : list of tuples
            Parameters for the marginal distributions. It can be None if none
            of the marginal distributions have parameters, otherwise it needs
            to be a list of tuples with the same length has the number of
            marginal distributions. The list can contain empty tuples for
            marginal distributions that do not take parameter arguments.

        Returns
        -------
        cdf values

        Nr   .r   )npasarrayr   shaperanger   appendr
   cdfcolumn_stackndimsqueezer	   )r   yr   r   cdf_margr   ur   r   r   r!   j   s    
*

zCopulaDistribution.cdfc                 C   s   t | j|||dS )a  PDF of copula distribution.

        Parameters
        ----------
        y : array_like
            Values of random variable at which to evaluate cdf.
            If 2-dimensional, then components of multivariate random variable
            need to be in columns
        cop_args : tuple
            Copula parameters. If None, then the copula parameters will be
            taken from the ``cop_args`` attribute created when initiializing
            the instance.
        marg_args : list of tuples
            Parameters for the marginal distributions. It can be None if none
            of the marginal distributions have parameters, otherwise it needs
            to be a list of tuples with the same length has the number of
            marginal distributions. The list can contain empty tuples for
            marginal distributions that do not take parameter arguments.

        Returns
        -------
        pdf values
        )r   r   )r   explogpdf)r   r%   r   r   r   r   r   pdf   s    zCopulaDistribution.pdfc                 C   s   t |}|dkr| j}|dkr4tdg|jd  }d}g }t| jD ]R}|| j| j|d|f f||  7 }|	| j| j
|d|f f||   qFt |}|jdkr| }|| j||7 }|S )a  Log-pdf of copula distribution.

        Parameters
        ----------
        y : array_like
            Values of random variable at which to evaluate cdf.
            If 2-dimensional, then components of multivariate random variable
            need to be in columns
        cop_args : tuple
            Copula parameters. If None, then the copula parameters will be
            taken from the ``cop_args`` attribute creating when initiializing
            the instance.
        marg_args : list of tuples
            Parameters for the marginal distributions. It can be None if none
            of the marginal distributions have parameters, otherwise it needs
            to be a list of tuples with the same length has the number of
            marginal distributions. The list can contain empty tuples for
            marginal distributions that do not take parameter arguments.

        Returns
        -------
        log-pdf values

        Nr   r   g        .r   )r   r   r   tupler   r   r   r
   r)   r    r!   r"   r#   r$   r	   )r   r%   r   r   Zlpdfr&   r   r'   r   r   r   r)      s    
&*

zCopulaDistribution.logpdf)r   )r   NNN)NN)NN)NN)	__name__
__module____qualname____doc__r   r   r!   r*   r)   r   r   r   r   r      s   
	
:
(
r   c                   @   sx   e Zd ZdZdddZddd	Zedd
dZd ddZed!ddZ	d"ddZ
d#ddZd$ddZdd Zdd ZdS )%Copulau_  A generic Copula class meant for subclassing.

    Notes
    -----
    A function :math:`\phi` on :math:`[0, \infty]` is the Laplace-Stieltjes
    transform of a distribution function if and only if :math:`\phi` is
    completely monotone and :math:`\phi(0) = 1` [2]_.

    The following algorithm for sampling a ``d``-dimensional exchangeable
    Archimedean copula with generator :math:`\phi` is due to Marshall, Olkin
    (1988) [1]_, where :math:`LS^{−1}(\phi)` denotes the inverse
    Laplace-Stieltjes transform of :math:`\phi`.

    From a mixture representation with respect to :math:`F`, the following
    algorithm may be derived for sampling Archimedean copulas, see [1]_.

    1. Sample :math:`V \sim F = LS^{−1}(\phi)`.
    2. Sample i.i.d. :math:`X_i \sim U[0,1], i \in \{1,...,d\}`.
    3. Return:math:`(U_1,..., U_d)`, where :math:`U_i = \phi(−\log(X_i)/V), i
       \in \{1, ...,d\}`.

    Detailed properties of each copula can be found in [3]_.

    Instances of the class can access the attributes: ``rng`` for the random
    number generator (used for the ``seed``).

    **Subclassing**

    When subclassing `Copula` to create a new copula, ``__init__`` and
    ``random`` must be redefined.

    * ``__init__(theta)``: If the copula
      does not take advantage of a ``theta``, this parameter can be omitted.
    * ``random(n, random_state)``: draw ``n`` from the copula.
    * ``pdf(x)``: PDF from the copula.
    * ``cdf(x)``: CDF from the copula.

    References
    ----------
    .. [1] Marshall AW, Olkin I. “Families of Multivariate Distributions”,
      Journal of the American Statistical Association, 83, 834–841, 1988.
    .. [2] Marius Hofert. "Sampling Archimedean copulas",
      Universität Ulm, 2008.
    .. rvs[3] Harry Joe. "Dependence Modeling with Copulas", Monographs on
      Statistics and Applied Probability 134, 2015.

       c                 C   s
   || _ d S r   )k_dim)r   r2   r   r   r   r   
  s    zCopula.__init__r   r   Nc                 C   s   t dS )aE  Draw `n` in the half-open interval ``[0, 1)``.

        Marginals are uniformly distributed.

        Parameters
        ----------
        nobs : int, optional
            Number of samples to generate from the copula. Default is 1.
        args : tuple
            Arguments for copula parameters. The number of arguments depends
            on the copula.
        random_state : {None, int, numpy.random.Generator}, optional
            If `seed` is None then the legacy singleton NumPy generator.
            This will change after 0.13 to use a fresh NumPy ``Generator``,
            so you should explicitly pass a seeded ``Generator`` if you
            need reproducible results.
            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.

        Returns
        -------
        sample : array_like (nobs, d)
            Sample from the copula.

        See Also
        --------
        statsmodels.tools.rng_qrng.check_random_state
        NNotImplementedError)r   r   r   r   r   r   r   r     s    z
Copula.rvsc                 C   s   dS )a[  Probability density function of copula.

        Parameters
        ----------
        u : array_like, 2-D
            Points of random variables in unit hypercube at which method is
            evaluated.
            The second (or last) dimension should be the same as the dimension
            of the random variable, e.g. 2 for bivariate copula.
        args : tuple
            Arguments for copula parameters. The number of arguments depends
            on the copula.

        Returns
        -------
        pdf : ndarray, (nobs, k_dim)
            Copula pdf evaluated at points ``u``.
        Nr   r   r'   r   r   r   r   r*   .  s    z
Copula.pdfc                 C   s   t | j|f| S )aY  Log of copula pdf, loglikelihood.

        Parameters
        ----------
        u : array_like, 2-D
            Points of random variables in unit hypercube at which method is
            evaluated.
            The second (or last) dimension should be the same as the dimension
            of the random variable, e.g. 2 for bivariate copula.
        args : tuple
            Arguments for copula parameters. The number of arguments depends
            on the copula.

        Returns
        -------
        cdf : ndarray, (nobs, k_dim)
            Copula log-pdf evaluated at points ``u``.
        )r   logr*   r5   r   r   r   r)   C  s    zCopula.logpdfc                 C   s   dS )ak  Cumulative distribution function evaluated at points u.

        Parameters
        ----------
        u : array_like, 2-D
            Points of random variables in unit hypercube at which method is
            evaluated.
            The second (or last) dimension should be the same as the dimension
            of the random variable, e.g. 2 for bivariate copula.
        args : tuple
            Arguments for copula parameters. The number of arguments depends
            on the copula.

        Returns
        -------
        cdf : ndarray, (nobs, k_dim)
            Copula cdf evaluated at points ``u``.
        Nr   r5   r   r   r   r!   X  s    z
Copula.cdf  c                 C   sv   | j dkrtd|dkr(| j||d}t|\}}||dddf |dddf  |d |d ||fS )	a  Sample the copula and plot.

        Parameters
        ----------
        sample : array-like, optional
            The sample to plot.  If not provided (the default), a sample
            is generated.
        nobs : int, optional
            Number of samples to generate from the copula.
        random_state : {None, int, numpy.random.Generator}, optional
            If `seed` is None then the legacy singleton NumPy generator.
            This will change after 0.13 to use a fresh NumPy ``Generator``,
            so you should explicitly pass a seeded ``Generator`` if you
            need reproducible results.
            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.
        ax : AxesSubplot, optional
            If given, this subplot is used to plot in instead of a new figure
            being created.

        Returns
        -------
        fig : Figure
            If `ax` is None, the created figure.  Otherwise the figure to which
            `ax` is connected.
        sample : array_like (n, d)
            Sample from the copula.

        See Also
        --------
        statsmodels.tools.rng_qrng.check_random_state
        r1   z#Can only plot 2-dimensional Copula.N)r   r   r   r   r'   v)r2   
ValueErrorr   r   create_mpl_axZscatter
set_xlabel
set_ylabel)r   r   r   r   axfigr   r   r   plot_scatterm  s    #
$

zCopula.plot_scatter
   c              	   C   s@  ddl m} | jdkr(ddl}|d d}d}tt|d| |t|d| |\}}t|	 |	 gj
}	| |	j
|j}
t|
d	}t|
d
}t|\}}tj|||d}||g}|j|||
|d|d |d d}|d |d |dd |dd |d |j||d}|d |  |S )a  Plot the PDF.

        Parameters
        ----------
        ticks_nbr : int, optional
            Number of color isolines for the PDF. Default is 10.
        ax : AxesSubplot, optional
            If given, this subplot is used to plot in instead of a new figure
            being created.

        Returns
        -------
        fig : Figure
            If `ax` is None, the created figure.  Otherwise the figure to which
            `ax` is connected.

        r   )pyplotr1   NzPlotting 2-dimensional Copula.d   g-C6?r      _   )numT)ZantialiasedZvminZvmaxr'   r8   equal)Zticksp)Z
matplotlibrA   r2   warningswarnr   ZmeshgridZlinspaceZvstackZravelTr*   Zreshaper   Znanpercentiler   r:   Zcontourfr;   r<   Zset_xlimZset_ylimZ
set_aspectZcolorbarZ	set_labelZtight_layout)r   Z	ticks_nbrr=   ZpltrH   Z	n_samplesZepsuuvvZpointsdataZmin_Zmax_r>   ZvticksZ
range_cbarcsZcbarr   r   r   plot_pdf  s<    

 



zCopula.plot_pdf   c                 C   s6   | j ||d}t|dddf |dddf d S )zKendall's tau based on simulated samples.

        Returns
        -------
        tau : float
            Kendall's tau.

        )r   Nr   r   )r   r   
kendalltau)r   r   r   xr   r   r   tau_simulated  s    	zCopula.tau_simulatedc                    st   t |jd dkrBtdddf dddf d }n(| j  fddt D }t |}| |S )a  Copula correlation parameter using Kendall's tau of sample data.

        Parameters
        ----------
        data : array_like
            Sample data used to fit `theta` using Kendall's tau.

        Returns
        -------
        corr_param : float
            Correlation parameter of the copula, ``theta`` in Archimedean and
            pearson correlation in elliptical.
            If k_dim > 2, then average tau is used.
        r   r1   Nr   c              	      s@   g | ]8}t |d   D ]$}td|f d|f d qqS )r   .r   )r   r   rQ   ).0r   jkrR   r   r   
<listcomp>  s     z)Copula.fit_corr_param.<locals>.<listcomp>)	r   r   r   r   rQ   r2   r   Zmean_arg_from_tau)r   rM   tauZtausr   rV   r   fit_corr_param  s    
*
zCopula.fit_corr_paramc                 C   s   t dS )a@  Compute correlation parameter from tau.

        Parameters
        ----------
        tau : float
            Kendall's tau.

        Returns
        -------
        corr_param : float
            Correlation parameter of the copula, ``theta`` in Archimedean and
            pearson correlation in elliptical.

        Nr3   )r   rZ   r   r   r   rY     s    zCopula._arg_from_tau)r1   )r   r   N)r   )r   )r   )Nr7   NN)r@   N)rP   N)r,   r-   r.   r/   r   r   r   r*   r)   r!   r?   rO   rS   r[   rY   r   r   r   r   r0      s   0

!

0
5
r0   )r/   abcr   r   Znumpyr   Zscipyr   Zstatsmodels.graphicsr   r   r0   r   r   r   r   <module>   s    E