U
    md                     @   sv   d Z ddlZddlmZ ddlmZ ddlmZm	Z	m
Z
mZmZmZ G dd dZG dd	 d	eZG d
d deZdS )zM
Created on Wed Feb 17 15:35:23 2021

Author: Josef Perktold
License: BSD-3

    N)stats)cache_readonly)_Gridcdf2prob_gridprob2cdf_grid_eval_bernstein_dd_eval_bernstein_2d_eval_bernstein_1dc                   @   sP   e Zd ZdZdd Zedd Zedd Zdd	 Z	d
d Z
dd Zdd ZdS )BernsteinDistributiona  Distribution based on Bernstein Polynomials on unit hypercube.

    Parameters
    ----------
    cdf_grid : array_like
        cdf values on a equal spaced grid of the unit hypercube [0, 1]^d.
        The dimension of the arrays define how many random variables are
        included in the multivariate distribution.

    Attributes
    ----------
    cdf_grid : grid of cdf values
    prob_grid : grid of cell or bin probabilities
    k_dim : (int) number of components, dimension of random variable
    k_grid : (tuple) shape of cdf_grid
    k_grid_product : (int) total number of bins in grid
    _grid : Grid instance with helper methods and attributes
    c                 C   sH   t | | _}|j| _|j| _t dd | jD | _t	| j| _
d S )Nc                 S   s   g | ]}|d  qS )    ).0ir   r   \/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/statsmodels/distributions/bernstein.py
<listcomp>+   s     z2BernsteinDistribution.__init__.<locals>.<listcomp>)npasarraycdf_gridndimk_dimshapek_gridprodk_grid_productr   _grid)selfr   r   r   r   __init__'   s
    zBernsteinDistribution.__init__c                 C   s   t |}t |dk s&t |dkr.td|jdkrH|dddf }|jd }t |dkrj|g| }dd |D }t j||dd\}}td	d |D st	|t
| }t|}| |S )
ao  Create distribution instance from data using histogram binning.

        Classmethod to construct a distribution instance.

        Parameters
        ----------
        data : array_like
            Data with observation in rows and random variables in columns.
            Data can be 1-dimensional in the univariate case.
        k_bins : int or list
            Number or edges of bins to be used in numpy histogramdd.
            If k_bins is a scalar int, then the number of bins of each
            component will be equal to it.

        Returns
        -------
        Instance of a Bernstein distribution
        r   r   zdata needs to be in [0, 1]Nc                 S   s"   g | ]}t d | d|d qS )r      )r   Zlinspace)r   nir   r   r   r   L   s     z3BernsteinDistribution.from_data.<locals>.<listcomp>F)binsZdensityc                 S   s   g | ]}|d  dkqS )r   r   r   )r   eir   r   r   r   P   s     )r   r   any
ValueErrorr   r   sizeZhistogramddallAssertionErrorlenr   )clsdataZk_binsr   r    cer   r   r   r   	from_data.   s    



zBernsteinDistribution.from_datac                 C   s   t | jd dS )N)prepend)r   r   )r   r   r   r   	prob_gridV   s    zBernsteinDistribution.prob_gridc                 C   s>   t |}|jdkr.| jdkr.|dddf }t|| j}|S )a  cdf values evaluated at x.

        Parameters
        ----------
        x : array_like
            Points of multivariate random variable at which cdf is evaluated.
            This can be a single point with length equal to the dimension of
            the random variable, or two dimensional with points (observations)
            in rows and random variables in columns.
            In the univariate case, a 1-dimensional x will be interpreted as
            different points for evaluation.

        Returns
        -------
        pdf values

        Notes
        -----
        Warning: 2-dim x with many points can be memory intensive because
        currently the bernstein polynomials will be evaluated in a fully
        vectorized computation.
        r   N)r   r   r   r   r   r   r   xcdf_r   r   r   cdfZ   s
    
zBernsteinDistribution.cdfc                 C   sD   t |}|jdkr.| jdkr.|dddf }| jt|| j }|S )a  pdf values evaluated at x.

        Parameters
        ----------
        x : array_like
            Points of multivariate random variable at which pdf is evaluated.
            This can be a single point with length equal to the dimension of
            the random variable, or two dimensional with points (observations)
            in rows and random variables in columns.
            In the univariate case, a 1-dimensional x will be interpreted as
            different points for evaluation.

        Returns
        -------
        cdf values

        Notes
        -----
        Warning: 2-dim x with many points can be memory intensive because
        currently the bernstein polynomials will be evaluated in a fully
        vectorized computation.
        r   N)r   r   r   r   r   r   r.   r   r0   pdf_r   r   r   pdfw   s
    
zBernsteinDistribution.pdfc                 C   sb   | j dkr| S dg| j  }t|dkr.|g}|D ]}tddd||< q2| jt| }t|}|S )aF  Get marginal BernsteinDistribution.

        Parameters
        ----------
        idx : int or list of int
            Index or indices of the component for which the marginal
            distribution is returned.

        Returns
        -------
        BernsteinDistribution instance for the marginal distribution.
        r   r   r   N)r   r   r   slicer   tupler
   )r   idxsliiZcdf_mZbpd_marginalr   r   r   get_marginal   s    
z"BernsteinDistribution.get_marginalc              	   C   s   t j|| j }| j}g }tt|D ]}|| dkr*t || jj	}g }t|D ]R}| j
| }	| jj| ||  }
|tjj|	|
 d |	d|
  d || d qV|t | q*t |}|S )zGenerate random numbers from distribution.

        Parameters
        ----------
        nobs : int
            Number of random observations to generate.
        r   r   )r$   )r   randomZmultinomialr.   flattenr   ranger'   Zunravel_indexr   r   r   Z
x_marginalappendr   betarvsZcolumn_stackZconcatenate)r   ZnobsZrvs_mnlZk_compZrvs_mr   r8   ZrvsijnZxgiZrvsmr   r   r   rA      s     
"

zBernsteinDistribution.rvsN)__name__
__module____qualname____doc__r   classmethodr,   r   r.   r2   r5   r;   rA   r   r   r   r   r
      s   
'
r
   c                   @   s   e Zd Zdd Zdd ZdS )BernsteinDistributionBVc                 C   s   t || j}|S N)r   r   r/   r   r   r   r2      s    zBernsteinDistributionBV.cdfc                 C   s   | j t|| j }|S rJ   )r   r   r.   r3   r   r   r   r5      s    zBernsteinDistributionBV.pdfNrD   rE   rF   r2   r5   r   r   r   r   rI      s   rI   c                   @   s    e Zd ZdddZdddZdS )	BernsteinDistributionUVbinomc                 C   s   t || j|d}|S N)method)r	   r   )r   r0   rO   r1   r   r   r   r2      s    zBernsteinDistributionUV.cdfc                 C   s   | j t|| j|d }|S rN   )r   r	   r.   )r   r0   rO   r4   r   r   r   r5      s    zBernsteinDistributionUV.pdfN)rM   )rM   rK   r   r   r   r   rL      s   
rL   )rG   numpyr   Zscipyr   Zstatsmodels.tools.decoratorsr   Zstatsmodels.distributions.toolsr   r   r   r   r   r	   r
   rI   rL   r   r   r   r   <module>   s     :