We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Gaussian Copula: Add parameter allow_singular
The Gaussian Copula module is using scipy.stats package for the multivariate normal distribution. There is a parameter allow_singular=False which allows the covariance matrix to not have full rank. Unfortunately this parameter is not passed to the Copula interface.

It could be added here:
https://github.com/statsmodels/statsmodels/blob/55aff1e2268f56cc26b45ddcc1f44e5f924f8d05/statsmodels/distributions/copula/elliptical.py#L153

I currently wrote an inherited class, and singular matrixes for the copula seem to work fine.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `statsmodels/distributions/copula/elliptical.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """
3 Created on Fri Jan 29 19:19:45 2021
4 
5 Author: Josef Perktold
6 Author: Pamphile Roy
7 License: BSD-3
8 
9 """
10 import numpy as np
11 from scipy import stats
12 # scipy compat:
13 from statsmodels.compat.scipy import multivariate_t
14 
15 from statsmodels.distributions.copula.copulas import Copula
16 
17 
18 class EllipticalCopula(Copula):
19     """Base class for elliptical copula
20 
21     This class requires subclassing and currently does not have generic
22     methods based on an elliptical generator.
23 
24     Notes
25     -----
26     Elliptical copulas require that copula parameters are set when the
27     instance is created. Those parameters currently cannot be provided in the
28     call to methods. (This will most likely change in future versions.)
29     If non-empty ``args`` are provided in methods, then a ValueError is raised.
30     The ``args`` keyword is provided for a consistent interface across
31     copulas.
32 
33     """
34     def _handle_args(self, args):
35         if args != () and args is not None:
36             msg = ("Methods in elliptical copulas use copula parameters in"
37                    " attributes. `arg` in the method is ignored")
38             raise ValueError(msg)
39         else:
40             return args
41 
42     def rvs(self, nobs=1, args=(), random_state=None):
43         self._handle_args(args)
44         x = self.distr_mv.rvs(size=nobs, random_state=random_state)
45         return self.distr_uv.cdf(x)
46 
47     def pdf(self, u, args=()):
48         self._handle_args(args)
49         ppf = self.distr_uv.ppf(u)
50         mv_pdf_ppf = self.distr_mv.pdf(ppf)
51 
52         return mv_pdf_ppf / np.prod(self.distr_uv.pdf(ppf), axis=-1)
53 
54     def cdf(self, u, args=()):
55         self._handle_args(args)
56         ppf = self.distr_uv.ppf(u)
57         return self.distr_mv.cdf(ppf)
58 
59     def tau(self, corr=None):
60         """Bivariate kendall's tau based on correlation coefficient.
61 
62         Parameters
63         ----------
64         corr : None or float
65             Pearson correlation. If corr is None, then the correlation will be
66             taken from the copula attribute.
67 
68         Returns
69         -------
70         Kendall's tau that corresponds to pearson correlation in the
71         elliptical copula.
72         """
73         if corr is None:
74             corr = self.corr
75         if corr.shape == (2, 2):
76             corr = corr[0, 1]
77         rho = 2 * np.arcsin(corr) / np.pi
78         return rho
79 
80     def corr_from_tau(self, tau):
81         """Pearson correlation from kendall's tau.
82 
83         Parameters
84         ----------
85         tau : array_like
86             Kendall's tau correlation coefficient.
87 
88         Returns
89         -------
90         Pearson correlation coefficient for given tau in elliptical
91         copula. This can be used as parameter for an elliptical copula.
92         """
93         corr = np.sin(tau * np.pi / 2)
94         return corr
95 
96 
97 class GaussianCopula(EllipticalCopula):
98     r"""Gaussian copula.
99 
100     It is constructed from a multivariate normal distribution over
101     :math:`\mathbb{R}^d` by using the probability integral transform.
102 
103     For a given correlation matrix :math:`R \in[-1, 1]^{d \times d}`,
104     the Gaussian copula with parameter matrix :math:`R` can be written
105     as:
106 
107     .. math::
108 
109         C_R^{\text{Gauss}}(u) = \Phi_R\left(\Phi^{-1}(u_1),\dots,
110         \Phi^{-1}(u_d) \right),
111 
112     where :math:`\Phi^{-1}` is the inverse cumulative distribution function
113     of a standard normal and :math:`\Phi_R` is the joint cumulative
114     distribution function of a multivariate normal distribution with mean
115     vector zero and covariance matrix equal to the correlation
116     matrix :math:`R`.
117 
118     Parameters
119     ----------
120     corr : scalar or array_like
121         Correlation or scatter matrix for the elliptical copula. In the
122         bivariate case, ``corr` can be a scalar and is then considered as
123         the correlation coefficient. If ``corr`` is None, then the scatter
124         matrix is the identity matrix.
125     k_dim : int
126         Dimension, number of components in the multivariate random variable.
127 
128     Notes
129     -----
130     Elliptical copulas require that copula parameters are set when the
131     instance is created. Those parameters currently cannot be provided in the
132     call to methods. (This will most likely change in future versions.)
133     If non-empty ``args`` are provided in methods, then a ValueError is raised.
134     The ``args`` keyword is provided for a consistent interface across
135     copulas.
136 
137     References
138     ----------
139     .. [1] Joe, Harry, 2014, Dependence modeling with copulas. CRC press.
140         p. 163
141 
142     """
143 
144     def __init__(self, corr=None, k_dim=2):
145         super().__init__(k_dim=k_dim)
146         if corr is None:
147             corr = np.eye(k_dim)
148         elif k_dim == 2 and np.size(corr) == 1:
149             corr = np.array([[1., corr], [corr, 1.]])
150 
151         self.corr = np.asarray(corr)
152         self.distr_uv = stats.norm
153         self.distr_mv = stats.multivariate_normal(cov=corr)
154 
155     def dependence_tail(self, corr=None):
156         """
157         Bivariate tail dependence parameter.
158 
159         Joe (2014) p. 182
160 
161         Parameters
162         ----------
163         corr : any
164             Tail dependence for Gaussian copulas is always zero.
165             Argument will be ignored
166 
167         Returns
168         -------
169         Lower and upper tail dependence coefficients of the copula with given
170         Pearson correlation coefficient.
171         """
172 
173         return 0, 0
174 
175     def _arg_from_tau(self, tau):
176         # for generic compat
177         return self.corr_from_tau(tau)
178 
179 
180 class StudentTCopula(EllipticalCopula):
181     """Student t copula.
182 
183     Parameters
184     ----------
185     corr : scalar or array_like
186         Correlation or scatter matrix for the elliptical copula. In the
187         bivariate case, ``corr` can be a scalar and is then considered as
188         the correlation coefficient. If ``corr`` is None, then the scatter
189         matrix is the identity matrix.
190     df : float (optional)
191         Degrees of freedom of the multivariate t distribution.
192     k_dim : int
193         Dimension, number of components in the multivariate random variable.
194 
195     Notes
196     -----
197     Elliptical copulas require that copula parameters are set when the
198     instance is created. Those parameters currently cannot be provided in the
199     call to methods. (This will most likely change in future versions.)
200     If non-empty ``args`` are provided in methods, then a ValueError is raised.
201     The ``args`` keyword is provided for a consistent interface across
202     copulas.
203 
204     References
205     ----------
206     .. [1] Joe, Harry, 2014, Dependence modeling with copulas. CRC press.
207         p. 181
208     """
209 
210     def __init__(self, corr=None, df=None, k_dim=2):
211         super().__init__(k_dim=k_dim)
212         if corr is None:
213             corr = np.eye(k_dim)
214         elif k_dim == 2 and np.size(corr) == 1:
215             corr = np.array([[1., corr], [corr, 1.]])
216 
217         self.df = df
218         self.corr = np.asarray(corr)
219         # both uv and mv are frozen distributions
220         self.distr_uv = stats.t(df=df)
221         self.distr_mv = multivariate_t(shape=corr, df=df)
222 
223     def cdf(self, u, args=()):
224         raise NotImplementedError("CDF not available in closed form.")
225         # ppf = self.distr_uv.ppf(u)
226         # mvt = MVT([0, 0], self.corr, self.df)
227         # return mvt.cdf(ppf)
228 
229     def spearmans_rho(self, corr=None):
230         """
231         Bivariate Spearman's rho based on correlation coefficient.
232 
233         Joe (2014) p. 182
234 
235         Parameters
236         ----------
237         corr : None or float
238             Pearson correlation. If corr is None, then the correlation will be
239             taken from the copula attribute.
240 
241         Returns
242         -------
243         Spearman's rho that corresponds to pearson correlation in the
244         elliptical copula.
245         """
246         if corr is None:
247             corr = self.corr
248         if corr.shape == (2, 2):
249             corr = corr[0, 1]
250 
251         tau = 6 * np.arcsin(corr / 2) / np.pi
252         return tau
253 
254     def dependence_tail(self, corr=None):
255         """
256         Bivariate tail dependence parameter.
257 
258         Joe (2014) p. 182
259 
260         Parameters
261         ----------
262         corr : None or float
263             Pearson correlation. If corr is None, then the correlation will be
264             taken from the copula attribute.
265 
266         Returns
267         -------
268         Lower and upper tail dependence coefficients of the copula with given
269         Pearson correlation coefficient.
270         """
271         if corr is None:
272             corr = self.corr
273         if corr.shape == (2, 2):
274             corr = corr[0, 1]
275 
276         df = self.df
277         t = - np.sqrt((df + 1) * (1 - corr) / 1 + corr)
278         # Note self.distr_uv is frozen, df cannot change, use stats.t instead
279         lam = 2 * stats.t.cdf(t, df + 1)
280         return lam, lam
281 
282     def _arg_from_tau(self, tau):
283         # for generic compat
284         # this does not provide an estimate of df
285         return self.corr_from_tau(tau)
286
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/statsmodels/distributions/copula/elliptical.py b/statsmodels/distributions/copula/elliptical.py
--- a/statsmodels/distributions/copula/elliptical.py
+++ b/statsmodels/distributions/copula/elliptical.py
@@ -124,6 +124,8 @@
         matrix is the identity matrix.
     k_dim : int
         Dimension, number of components in the multivariate random variable.
+    allow_singular : bool
+        Allow singular correlation matrix
 
     Notes
     -----
@@ -141,7 +143,7 @@
 
     """
 
-    def __init__(self, corr=None, k_dim=2):
+    def __init__(self, corr=None, k_dim=2, allow_singular=False):
         super().__init__(k_dim=k_dim)
         if corr is None:
             corr = np.eye(k_dim)
@@ -150,7 +152,8 @@
 
         self.corr = np.asarray(corr)
         self.distr_uv = stats.norm
-        self.distr_mv = stats.multivariate_normal(cov=corr)
+        self.distr_mv = stats.multivariate_normal(
+            cov=corr, allow_singular=allow_singular)
 
     def dependence_tail(self, corr=None):
         """

{"golden_diff": "diff --git a/statsmodels/distributions/copula/elliptical.py b/statsmodels/distributions/copula/elliptical.py\n--- a/statsmodels/distributions/copula/elliptical.py\n+++ b/statsmodels/distributions/copula/elliptical.py\n@@ -124,6 +124,8 @@\n         matrix is the identity matrix.\n     k_dim : int\n         Dimension, number of components in the multivariate random variable.\n+    allow_singular : bool\n+        Allow singular correlation matrix\n \n     Notes\n     -----\n@@ -141,7 +143,7 @@\n \n     \"\"\"\n \n-    def __init__(self, corr=None, k_dim=2):\n+    def __init__(self, corr=None, k_dim=2, allow_singular=False):\n         super().__init__(k_dim=k_dim)\n         if corr is None:\n             corr = np.eye(k_dim)\n@@ -150,7 +152,8 @@\n \n         self.corr = np.asarray(corr)\n         self.distr_uv = stats.norm\n-        self.distr_mv = stats.multivariate_normal(cov=corr)\n+        self.distr_mv = stats.multivariate_normal(\n+            cov=corr, allow_singular=allow_singular)\n \n     def dependence_tail(self, corr=None):\n         \"\"\"\n", "issue": "Gaussian Copula: Add parameter allow_singular\nThe Gaussian Copula module is using scipy.stats package for the multivariate normal distribution. There is a parameter allow_singular=False which allows the covariance matrix to not have full rank. Unfortunately this parameter is not passed to the Copula interface.\r\n\r\nIt could be added here:\r\nhttps://github.com/statsmodels/statsmodels/blob/55aff1e2268f56cc26b45ddcc1f44e5f924f8d05/statsmodels/distributions/copula/elliptical.py#L153\r\n\r\nI currently wrote an inherited class, and singular matrixes for the copula seem to work fine.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\nCreated on Fri Jan 29 19:19:45 2021\n\nAuthor: Josef Perktold\nAuthor: Pamphile Roy\nLicense: BSD-3\n\n\"\"\"\nimport numpy as np\nfrom scipy import stats\n# scipy compat:\nfrom statsmodels.compat.scipy import multivariate_t\n\nfrom statsmodels.distributions.copula.copulas import Copula\n\n\nclass EllipticalCopula(Copula):\n    \"\"\"Base class for elliptical copula\n\n    This class requires subclassing and currently does not have generic\n    methods based on an elliptical generator.\n\n    Notes\n    -----\n    Elliptical copulas require that copula parameters are set when the\n    instance is created. Those parameters currently cannot be provided in the\n    call to methods. (This will most likely change in future versions.)\n    If non-empty ``args`` are provided in methods, then a ValueError is raised.\n    The ``args`` keyword is provided for a consistent interface across\n    copulas.\n\n    \"\"\"\n    def _handle_args(self, args):\n        if args != () and args is not None:\n            msg = (\"Methods in elliptical copulas use copula parameters in\"\n                   \" attributes. `arg` in the method is ignored\")\n            raise ValueError(msg)\n        else:\n            return args\n\n    def rvs(self, nobs=1, args=(), random_state=None):\n        self._handle_args(args)\n        x = self.distr_mv.rvs(size=nobs, random_state=random_state)\n        return self.distr_uv.cdf(x)\n\n    def pdf(self, u, args=()):\n        self._handle_args(args)\n        ppf = self.distr_uv.ppf(u)\n        mv_pdf_ppf = self.distr_mv.pdf(ppf)\n\n        return mv_pdf_ppf / np.prod(self.distr_uv.pdf(ppf), axis=-1)\n\n    def cdf(self, u, args=()):\n        self._handle_args(args)\n        ppf = self.distr_uv.ppf(u)\n        return self.distr_mv.cdf(ppf)\n\n    def tau(self, corr=None):\n        \"\"\"Bivariate kendall's tau based on correlation coefficient.\n\n        Parameters\n        ----------\n        corr : None or float\n            Pearson correlation. If corr is None, then the correlation will be\n            taken from the copula attribute.\n\n        Returns\n        -------\n        Kendall's tau that corresponds to pearson correlation in the\n        elliptical copula.\n        \"\"\"\n        if corr is None:\n            corr = self.corr\n        if corr.shape == (2, 2):\n            corr = corr[0, 1]\n        rho = 2 * np.arcsin(corr) / np.pi\n        return rho\n\n    def corr_from_tau(self, tau):\n        \"\"\"Pearson correlation from kendall's tau.\n\n        Parameters\n        ----------\n        tau : array_like\n            Kendall's tau correlation coefficient.\n\n        Returns\n        -------\n        Pearson correlation coefficient for given tau in elliptical\n        copula. This can be used as parameter for an elliptical copula.\n        \"\"\"\n        corr = np.sin(tau * np.pi / 2)\n        return corr\n\n\nclass GaussianCopula(EllipticalCopula):\n    r\"\"\"Gaussian copula.\n\n    It is constructed from a multivariate normal distribution over\n    :math:`\\mathbb{R}^d` by using the probability integral transform.\n\n    For a given correlation matrix :math:`R \\in[-1, 1]^{d \\times d}`,\n    the Gaussian copula with parameter matrix :math:`R` can be written\n    as:\n\n    .. math::\n\n        C_R^{\\text{Gauss}}(u) = \\Phi_R\\left(\\Phi^{-1}(u_1),\\dots,\n        \\Phi^{-1}(u_d) \\right),\n\n    where :math:`\\Phi^{-1}` is the inverse cumulative distribution function\n    of a standard normal and :math:`\\Phi_R` is the joint cumulative\n    distribution function of a multivariate normal distribution with mean\n    vector zero and covariance matrix equal to the correlation\n    matrix :math:`R`.\n\n    Parameters\n    ----------\n    corr : scalar or array_like\n        Correlation or scatter matrix for the elliptical copula. In the\n        bivariate case, ``corr` can be a scalar and is then considered as\n        the correlation coefficient. If ``corr`` is None, then the scatter\n        matrix is the identity matrix.\n    k_dim : int\n        Dimension, number of components in the multivariate random variable.\n\n    Notes\n    -----\n    Elliptical copulas require that copula parameters are set when the\n    instance is created. Those parameters currently cannot be provided in the\n    call to methods. (This will most likely change in future versions.)\n    If non-empty ``args`` are provided in methods, then a ValueError is raised.\n    The ``args`` keyword is provided for a consistent interface across\n    copulas.\n\n    References\n    ----------\n    .. [1] Joe, Harry, 2014, Dependence modeling with copulas. CRC press.\n        p. 163\n\n    \"\"\"\n\n    def __init__(self, corr=None, k_dim=2):\n        super().__init__(k_dim=k_dim)\n        if corr is None:\n            corr = np.eye(k_dim)\n        elif k_dim == 2 and np.size(corr) == 1:\n            corr = np.array([[1., corr], [corr, 1.]])\n\n        self.corr = np.asarray(corr)\n        self.distr_uv = stats.norm\n        self.distr_mv = stats.multivariate_normal(cov=corr)\n\n    def dependence_tail(self, corr=None):\n        \"\"\"\n        Bivariate tail dependence parameter.\n\n        Joe (2014) p. 182\n\n        Parameters\n        ----------\n        corr : any\n            Tail dependence for Gaussian copulas is always zero.\n            Argument will be ignored\n\n        Returns\n        -------\n        Lower and upper tail dependence coefficients of the copula with given\n        Pearson correlation coefficient.\n        \"\"\"\n\n        return 0, 0\n\n    def _arg_from_tau(self, tau):\n        # for generic compat\n        return self.corr_from_tau(tau)\n\n\nclass StudentTCopula(EllipticalCopula):\n    \"\"\"Student t copula.\n\n    Parameters\n    ----------\n    corr : scalar or array_like\n        Correlation or scatter matrix for the elliptical copula. In the\n        bivariate case, ``corr` can be a scalar and is then considered as\n        the correlation coefficient. If ``corr`` is None, then the scatter\n        matrix is the identity matrix.\n    df : float (optional)\n        Degrees of freedom of the multivariate t distribution.\n    k_dim : int\n        Dimension, number of components in the multivariate random variable.\n\n    Notes\n    -----\n    Elliptical copulas require that copula parameters are set when the\n    instance is created. Those parameters currently cannot be provided in the\n    call to methods. (This will most likely change in future versions.)\n    If non-empty ``args`` are provided in methods, then a ValueError is raised.\n    The ``args`` keyword is provided for a consistent interface across\n    copulas.\n\n    References\n    ----------\n    .. [1] Joe, Harry, 2014, Dependence modeling with copulas. CRC press.\n        p. 181\n    \"\"\"\n\n    def __init__(self, corr=None, df=None, k_dim=2):\n        super().__init__(k_dim=k_dim)\n        if corr is None:\n            corr = np.eye(k_dim)\n        elif k_dim == 2 and np.size(corr) == 1:\n            corr = np.array([[1., corr], [corr, 1.]])\n\n        self.df = df\n        self.corr = np.asarray(corr)\n        # both uv and mv are frozen distributions\n        self.distr_uv = stats.t(df=df)\n        self.distr_mv = multivariate_t(shape=corr, df=df)\n\n    def cdf(self, u, args=()):\n        raise NotImplementedError(\"CDF not available in closed form.\")\n        # ppf = self.distr_uv.ppf(u)\n        # mvt = MVT([0, 0], self.corr, self.df)\n        # return mvt.cdf(ppf)\n\n    def spearmans_rho(self, corr=None):\n        \"\"\"\n        Bivariate Spearman's rho based on correlation coefficient.\n\n        Joe (2014) p. 182\n\n        Parameters\n        ----------\n        corr : None or float\n            Pearson correlation. If corr is None, then the correlation will be\n            taken from the copula attribute.\n\n        Returns\n        -------\n        Spearman's rho that corresponds to pearson correlation in the\n        elliptical copula.\n        \"\"\"\n        if corr is None:\n            corr = self.corr\n        if corr.shape == (2, 2):\n            corr = corr[0, 1]\n\n        tau = 6 * np.arcsin(corr / 2) / np.pi\n        return tau\n\n    def dependence_tail(self, corr=None):\n        \"\"\"\n        Bivariate tail dependence parameter.\n\n        Joe (2014) p. 182\n\n        Parameters\n        ----------\n        corr : None or float\n            Pearson correlation. If corr is None, then the correlation will be\n            taken from the copula attribute.\n\n        Returns\n        -------\n        Lower and upper tail dependence coefficients of the copula with given\n        Pearson correlation coefficient.\n        \"\"\"\n        if corr is None:\n            corr = self.corr\n        if corr.shape == (2, 2):\n            corr = corr[0, 1]\n\n        df = self.df\n        t = - np.sqrt((df + 1) * (1 - corr) / 1 + corr)\n        # Note self.distr_uv is frozen, df cannot change, use stats.t instead\n        lam = 2 * stats.t.cdf(t, df + 1)\n        return lam, lam\n\n    def _arg_from_tau(self, tau):\n        # for generic compat\n        # this does not provide an estimate of df\n        return self.corr_from_tau(tau)\n", "path": "statsmodels/distributions/copula/elliptical.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\nCreated on Fri Jan 29 19:19:45 2021\n\nAuthor: Josef Perktold\nAuthor: Pamphile Roy\nLicense: BSD-3\n\n\"\"\"\nimport numpy as np\nfrom scipy import stats\n# scipy compat:\nfrom statsmodels.compat.scipy import multivariate_t\n\nfrom statsmodels.distributions.copula.copulas import Copula\n\n\nclass EllipticalCopula(Copula):\n    \"\"\"Base class for elliptical copula\n\n    This class requires subclassing and currently does not have generic\n    methods based on an elliptical generator.\n\n    Notes\n    -----\n    Elliptical copulas require that copula parameters are set when the\n    instance is created. Those parameters currently cannot be provided in the\n    call to methods. (This will most likely change in future versions.)\n    If non-empty ``args`` are provided in methods, then a ValueError is raised.\n    The ``args`` keyword is provided for a consistent interface across\n    copulas.\n\n    \"\"\"\n    def _handle_args(self, args):\n        if args != () and args is not None:\n            msg = (\"Methods in elliptical copulas use copula parameters in\"\n                   \" attributes. `arg` in the method is ignored\")\n            raise ValueError(msg)\n        else:\n            return args\n\n    def rvs(self, nobs=1, args=(), random_state=None):\n        self._handle_args(args)\n        x = self.distr_mv.rvs(size=nobs, random_state=random_state)\n        return self.distr_uv.cdf(x)\n\n    def pdf(self, u, args=()):\n        self._handle_args(args)\n        ppf = self.distr_uv.ppf(u)\n        mv_pdf_ppf = self.distr_mv.pdf(ppf)\n\n        return mv_pdf_ppf / np.prod(self.distr_uv.pdf(ppf), axis=-1)\n\n    def cdf(self, u, args=()):\n        self._handle_args(args)\n        ppf = self.distr_uv.ppf(u)\n        return self.distr_mv.cdf(ppf)\n\n    def tau(self, corr=None):\n        \"\"\"Bivariate kendall's tau based on correlation coefficient.\n\n        Parameters\n        ----------\n        corr : None or float\n            Pearson correlation. If corr is None, then the correlation will be\n            taken from the copula attribute.\n\n        Returns\n        -------\n        Kendall's tau that corresponds to pearson correlation in the\n        elliptical copula.\n        \"\"\"\n        if corr is None:\n            corr = self.corr\n        if corr.shape == (2, 2):\n            corr = corr[0, 1]\n        rho = 2 * np.arcsin(corr) / np.pi\n        return rho\n\n    def corr_from_tau(self, tau):\n        \"\"\"Pearson correlation from kendall's tau.\n\n        Parameters\n        ----------\n        tau : array_like\n            Kendall's tau correlation coefficient.\n\n        Returns\n        -------\n        Pearson correlation coefficient for given tau in elliptical\n        copula. This can be used as parameter for an elliptical copula.\n        \"\"\"\n        corr = np.sin(tau * np.pi / 2)\n        return corr\n\n\nclass GaussianCopula(EllipticalCopula):\n    r\"\"\"Gaussian copula.\n\n    It is constructed from a multivariate normal distribution over\n    :math:`\\mathbb{R}^d` by using the probability integral transform.\n\n    For a given correlation matrix :math:`R \\in[-1, 1]^{d \\times d}`,\n    the Gaussian copula with parameter matrix :math:`R` can be written\n    as:\n\n    .. math::\n\n        C_R^{\\text{Gauss}}(u) = \\Phi_R\\left(\\Phi^{-1}(u_1),\\dots,\n        \\Phi^{-1}(u_d) \\right),\n\n    where :math:`\\Phi^{-1}` is the inverse cumulative distribution function\n    of a standard normal and :math:`\\Phi_R` is the joint cumulative\n    distribution function of a multivariate normal distribution with mean\n    vector zero and covariance matrix equal to the correlation\n    matrix :math:`R`.\n\n    Parameters\n    ----------\n    corr : scalar or array_like\n        Correlation or scatter matrix for the elliptical copula. In the\n        bivariate case, ``corr` can be a scalar and is then considered as\n        the correlation coefficient. If ``corr`` is None, then the scatter\n        matrix is the identity matrix.\n    k_dim : int\n        Dimension, number of components in the multivariate random variable.\n    allow_singular : bool\n        Allow singular correlation matrix\n\n    Notes\n    -----\n    Elliptical copulas require that copula parameters are set when the\n    instance is created. Those parameters currently cannot be provided in the\n    call to methods. (This will most likely change in future versions.)\n    If non-empty ``args`` are provided in methods, then a ValueError is raised.\n    The ``args`` keyword is provided for a consistent interface across\n    copulas.\n\n    References\n    ----------\n    .. [1] Joe, Harry, 2014, Dependence modeling with copulas. CRC press.\n        p. 163\n\n    \"\"\"\n\n    def __init__(self, corr=None, k_dim=2, allow_singular=False):\n        super().__init__(k_dim=k_dim)\n        if corr is None:\n            corr = np.eye(k_dim)\n        elif k_dim == 2 and np.size(corr) == 1:\n            corr = np.array([[1., corr], [corr, 1.]])\n\n        self.corr = np.asarray(corr)\n        self.distr_uv = stats.norm\n        self.distr_mv = stats.multivariate_normal(\n            cov=corr, allow_singular=allow_singular)\n\n    def dependence_tail(self, corr=None):\n        \"\"\"\n        Bivariate tail dependence parameter.\n\n        Joe (2014) p. 182\n\n        Parameters\n        ----------\n        corr : any\n            Tail dependence for Gaussian copulas is always zero.\n            Argument will be ignored\n\n        Returns\n        -------\n        Lower and upper tail dependence coefficients of the copula with given\n        Pearson correlation coefficient.\n        \"\"\"\n\n        return 0, 0\n\n    def _arg_from_tau(self, tau):\n        # for generic compat\n        return self.corr_from_tau(tau)\n\n\nclass StudentTCopula(EllipticalCopula):\n    \"\"\"Student t copula.\n\n    Parameters\n    ----------\n    corr : scalar or array_like\n        Correlation or scatter matrix for the elliptical copula. In the\n        bivariate case, ``corr` can be a scalar and is then considered as\n        the correlation coefficient. If ``corr`` is None, then the scatter\n        matrix is the identity matrix.\n    df : float (optional)\n        Degrees of freedom of the multivariate t distribution.\n    k_dim : int\n        Dimension, number of components in the multivariate random variable.\n\n    Notes\n    -----\n    Elliptical copulas require that copula parameters are set when the\n    instance is created. Those parameters currently cannot be provided in the\n    call to methods. (This will most likely change in future versions.)\n    If non-empty ``args`` are provided in methods, then a ValueError is raised.\n    The ``args`` keyword is provided for a consistent interface across\n    copulas.\n\n    References\n    ----------\n    .. [1] Joe, Harry, 2014, Dependence modeling with copulas. CRC press.\n        p. 181\n    \"\"\"\n\n    def __init__(self, corr=None, df=None, k_dim=2):\n        super().__init__(k_dim=k_dim)\n        if corr is None:\n            corr = np.eye(k_dim)\n        elif k_dim == 2 and np.size(corr) == 1:\n            corr = np.array([[1., corr], [corr, 1.]])\n\n        self.df = df\n        self.corr = np.asarray(corr)\n        # both uv and mv are frozen distributions\n        self.distr_uv = stats.t(df=df)\n        self.distr_mv = multivariate_t(shape=corr, df=df)\n\n    def cdf(self, u, args=()):\n        raise NotImplementedError(\"CDF not available in closed form.\")\n        # ppf = self.distr_uv.ppf(u)\n        # mvt = MVT([0, 0], self.corr, self.df)\n        # return mvt.cdf(ppf)\n\n    def spearmans_rho(self, corr=None):\n        \"\"\"\n        Bivariate Spearman's rho based on correlation coefficient.\n\n        Joe (2014) p. 182\n\n        Parameters\n        ----------\n        corr : None or float\n            Pearson correlation. If corr is None, then the correlation will be\n            taken from the copula attribute.\n\n        Returns\n        -------\n        Spearman's rho that corresponds to pearson correlation in the\n        elliptical copula.\n        \"\"\"\n        if corr is None:\n            corr = self.corr\n        if corr.shape == (2, 2):\n            corr = corr[0, 1]\n\n        tau = 6 * np.arcsin(corr / 2) / np.pi\n        return tau\n\n    def dependence_tail(self, corr=None):\n        \"\"\"\n        Bivariate tail dependence parameter.\n\n        Joe (2014) p. 182\n\n        Parameters\n        ----------\n        corr : None or float\n            Pearson correlation. If corr is None, then the correlation will be\n            taken from the copula attribute.\n\n        Returns\n        -------\n        Lower and upper tail dependence coefficients of the copula with given\n        Pearson correlation coefficient.\n        \"\"\"\n        if corr is None:\n            corr = self.corr\n        if corr.shape == (2, 2):\n            corr = corr[0, 1]\n\n        df = self.df\n        t = - np.sqrt((df + 1) * (1 - corr) / 1 + corr)\n        # Note self.distr_uv is frozen, df cannot change, use stats.t instead\n        lam = 2 * stats.t.cdf(t, df + 1)\n        return lam, lam\n\n    def _arg_from_tau(self, tau):\n        # for generic compat\n        # this does not provide an estimate of df\n        return self.corr_from_tau(tau)\n", "path": "statsmodels/distributions/copula/elliptical.py"}]}