We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] TDistribution pdf does not consider location/scale
**Describe the bug**
The location/scale (mu/sigma) are not considered at all in methods: pdf, log_pdf, cdf or ppf

For example, the case pdf:

```    
def pdf(self, x):
        """Probability density function."""
        d = self.loc[x.index, x.columns]
        pdf_arr = gamma((d._df + 1) / 2)
        pdf_arr = pdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))
        pdf_arr = pdf_arr * (1 + x**2 / d._df) ** (-(d._df + 1) / 2)
        return pd.DataFrame(pdf_arr, index=x.index, columns=x.columns)
```

Here, in line 6, instead of x**2 one should use ((x - d._mu)/d._sigma)**2


sktime version 0.25.1


[BUG] TDistribution computes incorrectly variance 
**Describe the bug**

TDistribution does not use scale (sigma) for variance computation

```    
def var(self):
...
        df_arr = self._df.copy()
        df_arr = df_arr.astype(np.float32)
        df_arr[df_arr <= 2] = np.inf
        mask = (df_arr > 2) & (df_arr != np.inf)
        df_arr[mask] = df_arr[mask] / (df_arr[mask] - 2)
        return pd.DataFrame(df_arr, index=self.index, columns=self.columns)
```

one should correct the previous to last line to:

```
df_arr[mask] = self._sigma** 2 * df_arr[mask] / (df_arr[mask] - 2)
```

sktime version 0.25.1

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sktime/proba/t.py`
Content:
```
1 # copyright: sktime developers, BSD-3-Clause License (see LICENSE file)
2 """Student's t-distribution."""
3 
4 __author__ = ["Alex-JG3"]
5 
6 import numpy as np
7 import pandas as pd
8 from scipy.special import betaincinv, gamma, hyp2f1, loggamma
9 
10 from sktime.proba.base import BaseDistribution
11 
12 
13 class TDistribution(BaseDistribution):
14     """Student's t-distribution (sktime native).
15 
16     Parameters
17     ----------
18     mean : float or array of float (1D or 2D)
19         mean of the t-distribution distribution
20     sd : float or array of float (1D or 2D), must be positive
21         standard deviation of the t-distribution distribution
22     df : float or array of float (1D or 2D), must be positive
23         Degrees of freedom of the t-distribution
24     index : pd.Index, optional, default = RangeIndex
25     columns : pd.Index, optional, default = RangeIndex
26 
27     Example
28     -------
29     >>> from sktime.proba.t import TDistribution
30 
31     >>> n = TDistribution(mu=[[0, 1], [2, 3], [4, 5]], sigma=1, df=10)
32     """
33 
34     _tags = {
35         "authors": ["Alex-JG3"],
36         "maintainers": ["Alex-JG3"],
37         "capabilities:approx": ["pdfnorm", "energy"],
38         "capabilities:exact": ["mean", "var", "pdf", "log_pdf", "cdf", "ppf"],
39         "distr:measuretype": "continuous",
40     }
41 
42     def __init__(self, mu, sigma, df=1, index=None, columns=None):
43         self.mu = mu
44         self.sigma = sigma
45         self.df = df
46         self.index = index
47         self.columns = columns
48 
49         self._mu, self._sigma, self._df = self._get_bc_params(
50             self.mu, self.sigma, self.df
51         )
52         shape = self._mu.shape
53 
54         if index is None:
55             index = pd.RangeIndex(shape[0])
56 
57         if columns is None:
58             columns = pd.RangeIndex(shape[1])
59 
60         super().__init__(index=index, columns=columns)
61 
62     def mean(self):
63         r"""Return expected value of the distribution.
64 
65         Let :math:`X` be a random variable with the distribution of `self`.
66         Returns the expectation :math:`\mathbb{E}[X]`. The expectation,
67         :math:`\mathbb{E}[X]`, as infinite if :math:`\nu \le 1`.
68 
69         Returns
70         -------
71         pd.DataFrame with same rows, columns as `self`
72         expected value of distribution (entry-wise)
73         """
74         mean_arr = self._mu.copy()
75         if (self._df <= 1).any():
76             mean_arr = mean_arr.astype(np.float32)
77             mean_arr[self._df <= 1] = np.inf
78         return pd.DataFrame(mean_arr, index=self.index, columns=self.columns)
79 
80     def var(self):
81         r"""Return element/entry-wise variance of the distribution.
82 
83         Let :math:`X` be a random variable with the distribution of `self`.
84         Returns,
85 
86         .. math::
87             \mathbb{V}[X] = \begin{cases}
88                 \frac{\nu}{\nu - 2} & \text{if} \nu > 2, \\
89                 \infty              & \text{if} \nu \le 2, \\
90             \begin{cases}
91 
92         Where :math:`\nu` is the degrees of freedom of the t-distribution.
93 
94         Returns
95         -------
96         pd.DataFrame with same rows, columns as `self`
97         variance of distribution (entry-wise)
98         """
99         df_arr = self._df.copy()
100         df_arr = df_arr.astype(np.float32)
101         df_arr[df_arr <= 2] = np.inf
102         mask = (df_arr > 2) & (df_arr != np.inf)
103         df_arr[mask] = df_arr[mask] / (df_arr[mask] - 2)
104         return pd.DataFrame(df_arr, index=self.index, columns=self.columns)
105 
106     def pdf(self, x):
107         """Probability density function."""
108         d = self.loc[x.index, x.columns]
109         pdf_arr = gamma((d._df + 1) / 2)
110         pdf_arr = pdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))
111         pdf_arr = pdf_arr * (1 + x**2 / d._df) ** (-(d._df + 1) / 2)
112         return pd.DataFrame(pdf_arr, index=x.index, columns=x.columns)
113 
114     def log_pdf(self, x):
115         """Logarithmic probability density function."""
116         d = self.loc[x.index, x.columns]
117         lpdf_arr = loggamma((d._df + 1) / 2)
118         lpdf_arr = lpdf_arr - 0.5 * np.log(d._df * np.pi)
119         lpdf_arr = lpdf_arr - loggamma(d._df / 2)
120         lpdf_arr = lpdf_arr - ((d._df + 1) / 2) * np.log(1 + x**2 / d._df)
121         return pd.DataFrame(lpdf_arr, index=x.index, columns=x.columns)
122 
123     def cdf(self, x):
124         """Cumulative distribution function."""
125         d = self.loc[x.index, x.columns]
126         cdf_arr = x * gamma((d._df + 1) / 2)
127         cdf_arr = cdf_arr * hyp2f1(0.5, (d._df + 1) / 2, 3 / 2, -(x**2) / d._df)
128         cdf_arr = 0.5 + cdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))
129         return pd.DataFrame(cdf_arr, index=x.index, columns=x.columns)
130 
131     def ppf(self, p):
132         """Quantile function = percent point function = inverse cdf."""
133         d = self.loc[p.index, p.columns]
134         ppf_arr = p.to_numpy(copy=True)
135         ppf_arr[p.values == 0.5] = 0.0
136         ppf_arr[p.values <= 0] = -np.inf
137         ppf_arr[p.values >= 1] = np.inf
138 
139         mask1 = (p.values < 0.5) & (p.values > 0)
140         mask2 = (p.values < 1) & (p.values > 0.5)
141         ppf_arr[mask1] = 1 / betaincinv(0.5 * d._df[mask1], 0.5, 2 * ppf_arr[mask1])
142         ppf_arr[mask2] = 1 / betaincinv(
143             0.5 * d._df[mask2], 0.5, 2 * (1 - ppf_arr[mask2])
144         )
145         ppf_arr[mask1 | mask2] = np.sqrt(ppf_arr[mask1 | mask2] - 1)
146         ppf_arr[mask1 | mask2] = np.sqrt(d._df[mask1 | mask2]) * ppf_arr[mask1 | mask2]
147         ppf_arr[mask1] = -ppf_arr[mask1]
148         return pd.DataFrame(ppf_arr, index=p.index, columns=p.columns)
149 
150     @classmethod
151     def get_test_params(cls, parameter_set="default"):
152         """Return testing parameter settings for the estimator."""
153         params1 = {"mu": [[0, 1], [2, 3], [4, 5]], "sigma": 1}
154         params2 = {
155             "mu": 0,
156             "sigma": 1,
157             "index": pd.Index([1, 2, 5]),
158             "columns": pd.Index(["a", "b"]),
159         }
160         return [params1, params2]
161
```
--- 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/sktime/proba/t.py b/sktime/proba/t.py
--- a/sktime/proba/t.py
+++ b/sktime/proba/t.py
@@ -100,7 +100,7 @@
         df_arr = df_arr.astype(np.float32)
         df_arr[df_arr <= 2] = np.inf
         mask = (df_arr > 2) & (df_arr != np.inf)
-        df_arr[mask] = df_arr[mask] / (df_arr[mask] - 2)
+        df_arr[mask] = self._sigma[mask] ** 2 * df_arr[mask] / (df_arr[mask] - 2)
         return pd.DataFrame(df_arr, index=self.index, columns=self.columns)
 
     def pdf(self, x):
@@ -108,7 +108,10 @@
         d = self.loc[x.index, x.columns]
         pdf_arr = gamma((d._df + 1) / 2)
         pdf_arr = pdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))
-        pdf_arr = pdf_arr * (1 + x**2 / d._df) ** (-(d._df + 1) / 2)
+        pdf_arr = pdf_arr * (1 + ((x - d._mu) / d._sigma) ** 2 / d._df) ** (
+            -(d._df + 1) / 2
+        )
+        pdf_arr = pdf_arr / d._sigma
         return pd.DataFrame(pdf_arr, index=x.index, columns=x.columns)
 
     def log_pdf(self, x):
@@ -117,14 +120,18 @@
         lpdf_arr = loggamma((d._df + 1) / 2)
         lpdf_arr = lpdf_arr - 0.5 * np.log(d._df * np.pi)
         lpdf_arr = lpdf_arr - loggamma(d._df / 2)
-        lpdf_arr = lpdf_arr - ((d._df + 1) / 2) * np.log(1 + x**2 / d._df)
+        lpdf_arr = lpdf_arr - ((d._df + 1) / 2) * np.log(
+            1 + ((x - d._mu) / d._sigma) ** 2 / d._df
+        )
+        lpdf_arr = lpdf_arr - np.log(d._sigma)
         return pd.DataFrame(lpdf_arr, index=x.index, columns=x.columns)
 
     def cdf(self, x):
         """Cumulative distribution function."""
         d = self.loc[x.index, x.columns]
-        cdf_arr = x * gamma((d._df + 1) / 2)
-        cdf_arr = cdf_arr * hyp2f1(0.5, (d._df + 1) / 2, 3 / 2, -(x**2) / d._df)
+        x_ = (x - d._mu) / d._sigma
+        cdf_arr = x_ * gamma((d._df + 1) / 2)
+        cdf_arr = cdf_arr * hyp2f1(0.5, (d._df + 1) / 2, 3 / 2, -(x_**2) / d._df)
         cdf_arr = 0.5 + cdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))
         return pd.DataFrame(cdf_arr, index=x.index, columns=x.columns)
 
@@ -145,6 +152,7 @@
         ppf_arr[mask1 | mask2] = np.sqrt(ppf_arr[mask1 | mask2] - 1)
         ppf_arr[mask1 | mask2] = np.sqrt(d._df[mask1 | mask2]) * ppf_arr[mask1 | mask2]
         ppf_arr[mask1] = -ppf_arr[mask1]
+        ppf_arr = d._sigma * ppf_arr + d._mu
         return pd.DataFrame(ppf_arr, index=p.index, columns=p.columns)
 
     @classmethod

{"golden_diff": "diff --git a/sktime/proba/t.py b/sktime/proba/t.py\n--- a/sktime/proba/t.py\n+++ b/sktime/proba/t.py\n@@ -100,7 +100,7 @@\n         df_arr = df_arr.astype(np.float32)\n         df_arr[df_arr <= 2] = np.inf\n         mask = (df_arr > 2) & (df_arr != np.inf)\n-        df_arr[mask] = df_arr[mask] / (df_arr[mask] - 2)\n+        df_arr[mask] = self._sigma[mask] ** 2 * df_arr[mask] / (df_arr[mask] - 2)\n         return pd.DataFrame(df_arr, index=self.index, columns=self.columns)\n \n     def pdf(self, x):\n@@ -108,7 +108,10 @@\n         d = self.loc[x.index, x.columns]\n         pdf_arr = gamma((d._df + 1) / 2)\n         pdf_arr = pdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))\n-        pdf_arr = pdf_arr * (1 + x**2 / d._df) ** (-(d._df + 1) / 2)\n+        pdf_arr = pdf_arr * (1 + ((x - d._mu) / d._sigma) ** 2 / d._df) ** (\n+            -(d._df + 1) / 2\n+        )\n+        pdf_arr = pdf_arr / d._sigma\n         return pd.DataFrame(pdf_arr, index=x.index, columns=x.columns)\n \n     def log_pdf(self, x):\n@@ -117,14 +120,18 @@\n         lpdf_arr = loggamma((d._df + 1) / 2)\n         lpdf_arr = lpdf_arr - 0.5 * np.log(d._df * np.pi)\n         lpdf_arr = lpdf_arr - loggamma(d._df / 2)\n-        lpdf_arr = lpdf_arr - ((d._df + 1) / 2) * np.log(1 + x**2 / d._df)\n+        lpdf_arr = lpdf_arr - ((d._df + 1) / 2) * np.log(\n+            1 + ((x - d._mu) / d._sigma) ** 2 / d._df\n+        )\n+        lpdf_arr = lpdf_arr - np.log(d._sigma)\n         return pd.DataFrame(lpdf_arr, index=x.index, columns=x.columns)\n \n     def cdf(self, x):\n         \"\"\"Cumulative distribution function.\"\"\"\n         d = self.loc[x.index, x.columns]\n-        cdf_arr = x * gamma((d._df + 1) / 2)\n-        cdf_arr = cdf_arr * hyp2f1(0.5, (d._df + 1) / 2, 3 / 2, -(x**2) / d._df)\n+        x_ = (x - d._mu) / d._sigma\n+        cdf_arr = x_ * gamma((d._df + 1) / 2)\n+        cdf_arr = cdf_arr * hyp2f1(0.5, (d._df + 1) / 2, 3 / 2, -(x_**2) / d._df)\n         cdf_arr = 0.5 + cdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))\n         return pd.DataFrame(cdf_arr, index=x.index, columns=x.columns)\n \n@@ -145,6 +152,7 @@\n         ppf_arr[mask1 | mask2] = np.sqrt(ppf_arr[mask1 | mask2] - 1)\n         ppf_arr[mask1 | mask2] = np.sqrt(d._df[mask1 | mask2]) * ppf_arr[mask1 | mask2]\n         ppf_arr[mask1] = -ppf_arr[mask1]\n+        ppf_arr = d._sigma * ppf_arr + d._mu\n         return pd.DataFrame(ppf_arr, index=p.index, columns=p.columns)\n \n     @classmethod\n", "issue": "[BUG] TDistribution pdf does not consider location/scale\n**Describe the bug**\r\nThe location/scale (mu/sigma) are not considered at all in methods: pdf, log_pdf, cdf or ppf\r\n\r\nFor example, the case pdf:\r\n\r\n```    \r\ndef pdf(self, x):\r\n        \"\"\"Probability density function.\"\"\"\r\n        d = self.loc[x.index, x.columns]\r\n        pdf_arr = gamma((d._df + 1) / 2)\r\n        pdf_arr = pdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))\r\n        pdf_arr = pdf_arr * (1 + x**2 / d._df) ** (-(d._df + 1) / 2)\r\n        return pd.DataFrame(pdf_arr, index=x.index, columns=x.columns)\r\n```\r\n\r\nHere, in line 6, instead of x**2 one should use ((x - d._mu)/d._sigma)**2\r\n\r\n\r\nsktime version 0.25.1\r\n\r\n\n[BUG] TDistribution computes incorrectly variance \n**Describe the bug**\r\n\r\nTDistribution does not use scale (sigma) for variance computation\r\n\r\n```    \r\ndef var(self):\r\n...\r\n        df_arr = self._df.copy()\r\n        df_arr = df_arr.astype(np.float32)\r\n        df_arr[df_arr <= 2] = np.inf\r\n        mask = (df_arr > 2) & (df_arr != np.inf)\r\n        df_arr[mask] = df_arr[mask] / (df_arr[mask] - 2)\r\n        return pd.DataFrame(df_arr, index=self.index, columns=self.columns)\r\n```\r\n\r\none should correct the previous to last line to:\r\n\r\n```\r\ndf_arr[mask] = self._sigma** 2 * df_arr[mask] / (df_arr[mask] - 2)\r\n```\r\n\r\nsktime version 0.25.1\n", "before_files": [{"content": "# copyright: sktime developers, BSD-3-Clause License (see LICENSE file)\n\"\"\"Student's t-distribution.\"\"\"\n\n__author__ = [\"Alex-JG3\"]\n\nimport numpy as np\nimport pandas as pd\nfrom scipy.special import betaincinv, gamma, hyp2f1, loggamma\n\nfrom sktime.proba.base import BaseDistribution\n\n\nclass TDistribution(BaseDistribution):\n    \"\"\"Student's t-distribution (sktime native).\n\n    Parameters\n    ----------\n    mean : float or array of float (1D or 2D)\n        mean of the t-distribution distribution\n    sd : float or array of float (1D or 2D), must be positive\n        standard deviation of the t-distribution distribution\n    df : float or array of float (1D or 2D), must be positive\n        Degrees of freedom of the t-distribution\n    index : pd.Index, optional, default = RangeIndex\n    columns : pd.Index, optional, default = RangeIndex\n\n    Example\n    -------\n    >>> from sktime.proba.t import TDistribution\n\n    >>> n = TDistribution(mu=[[0, 1], [2, 3], [4, 5]], sigma=1, df=10)\n    \"\"\"\n\n    _tags = {\n        \"authors\": [\"Alex-JG3\"],\n        \"maintainers\": [\"Alex-JG3\"],\n        \"capabilities:approx\": [\"pdfnorm\", \"energy\"],\n        \"capabilities:exact\": [\"mean\", \"var\", \"pdf\", \"log_pdf\", \"cdf\", \"ppf\"],\n        \"distr:measuretype\": \"continuous\",\n    }\n\n    def __init__(self, mu, sigma, df=1, index=None, columns=None):\n        self.mu = mu\n        self.sigma = sigma\n        self.df = df\n        self.index = index\n        self.columns = columns\n\n        self._mu, self._sigma, self._df = self._get_bc_params(\n            self.mu, self.sigma, self.df\n        )\n        shape = self._mu.shape\n\n        if index is None:\n            index = pd.RangeIndex(shape[0])\n\n        if columns is None:\n            columns = pd.RangeIndex(shape[1])\n\n        super().__init__(index=index, columns=columns)\n\n    def mean(self):\n        r\"\"\"Return expected value of the distribution.\n\n        Let :math:`X` be a random variable with the distribution of `self`.\n        Returns the expectation :math:`\\mathbb{E}[X]`. The expectation,\n        :math:`\\mathbb{E}[X]`, as infinite if :math:`\\nu \\le 1`.\n\n        Returns\n        -------\n        pd.DataFrame with same rows, columns as `self`\n        expected value of distribution (entry-wise)\n        \"\"\"\n        mean_arr = self._mu.copy()\n        if (self._df <= 1).any():\n            mean_arr = mean_arr.astype(np.float32)\n            mean_arr[self._df <= 1] = np.inf\n        return pd.DataFrame(mean_arr, index=self.index, columns=self.columns)\n\n    def var(self):\n        r\"\"\"Return element/entry-wise variance of the distribution.\n\n        Let :math:`X` be a random variable with the distribution of `self`.\n        Returns,\n\n        .. math::\n            \\mathbb{V}[X] = \\begin{cases}\n                \\frac{\\nu}{\\nu - 2} & \\text{if} \\nu > 2, \\\\\n                \\infty              & \\text{if} \\nu \\le 2, \\\\\n            \\begin{cases}\n\n        Where :math:`\\nu` is the degrees of freedom of the t-distribution.\n\n        Returns\n        -------\n        pd.DataFrame with same rows, columns as `self`\n        variance of distribution (entry-wise)\n        \"\"\"\n        df_arr = self._df.copy()\n        df_arr = df_arr.astype(np.float32)\n        df_arr[df_arr <= 2] = np.inf\n        mask = (df_arr > 2) & (df_arr != np.inf)\n        df_arr[mask] = df_arr[mask] / (df_arr[mask] - 2)\n        return pd.DataFrame(df_arr, index=self.index, columns=self.columns)\n\n    def pdf(self, x):\n        \"\"\"Probability density function.\"\"\"\n        d = self.loc[x.index, x.columns]\n        pdf_arr = gamma((d._df + 1) / 2)\n        pdf_arr = pdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))\n        pdf_arr = pdf_arr * (1 + x**2 / d._df) ** (-(d._df + 1) / 2)\n        return pd.DataFrame(pdf_arr, index=x.index, columns=x.columns)\n\n    def log_pdf(self, x):\n        \"\"\"Logarithmic probability density function.\"\"\"\n        d = self.loc[x.index, x.columns]\n        lpdf_arr = loggamma((d._df + 1) / 2)\n        lpdf_arr = lpdf_arr - 0.5 * np.log(d._df * np.pi)\n        lpdf_arr = lpdf_arr - loggamma(d._df / 2)\n        lpdf_arr = lpdf_arr - ((d._df + 1) / 2) * np.log(1 + x**2 / d._df)\n        return pd.DataFrame(lpdf_arr, index=x.index, columns=x.columns)\n\n    def cdf(self, x):\n        \"\"\"Cumulative distribution function.\"\"\"\n        d = self.loc[x.index, x.columns]\n        cdf_arr = x * gamma((d._df + 1) / 2)\n        cdf_arr = cdf_arr * hyp2f1(0.5, (d._df + 1) / 2, 3 / 2, -(x**2) / d._df)\n        cdf_arr = 0.5 + cdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))\n        return pd.DataFrame(cdf_arr, index=x.index, columns=x.columns)\n\n    def ppf(self, p):\n        \"\"\"Quantile function = percent point function = inverse cdf.\"\"\"\n        d = self.loc[p.index, p.columns]\n        ppf_arr = p.to_numpy(copy=True)\n        ppf_arr[p.values == 0.5] = 0.0\n        ppf_arr[p.values <= 0] = -np.inf\n        ppf_arr[p.values >= 1] = np.inf\n\n        mask1 = (p.values < 0.5) & (p.values > 0)\n        mask2 = (p.values < 1) & (p.values > 0.5)\n        ppf_arr[mask1] = 1 / betaincinv(0.5 * d._df[mask1], 0.5, 2 * ppf_arr[mask1])\n        ppf_arr[mask2] = 1 / betaincinv(\n            0.5 * d._df[mask2], 0.5, 2 * (1 - ppf_arr[mask2])\n        )\n        ppf_arr[mask1 | mask2] = np.sqrt(ppf_arr[mask1 | mask2] - 1)\n        ppf_arr[mask1 | mask2] = np.sqrt(d._df[mask1 | mask2]) * ppf_arr[mask1 | mask2]\n        ppf_arr[mask1] = -ppf_arr[mask1]\n        return pd.DataFrame(ppf_arr, index=p.index, columns=p.columns)\n\n    @classmethod\n    def get_test_params(cls, parameter_set=\"default\"):\n        \"\"\"Return testing parameter settings for the estimator.\"\"\"\n        params1 = {\"mu\": [[0, 1], [2, 3], [4, 5]], \"sigma\": 1}\n        params2 = {\n            \"mu\": 0,\n            \"sigma\": 1,\n            \"index\": pd.Index([1, 2, 5]),\n            \"columns\": pd.Index([\"a\", \"b\"]),\n        }\n        return [params1, params2]\n", "path": "sktime/proba/t.py"}], "after_files": [{"content": "# copyright: sktime developers, BSD-3-Clause License (see LICENSE file)\n\"\"\"Student's t-distribution.\"\"\"\n\n__author__ = [\"Alex-JG3\"]\n\nimport numpy as np\nimport pandas as pd\nfrom scipy.special import betaincinv, gamma, hyp2f1, loggamma\n\nfrom sktime.proba.base import BaseDistribution\n\n\nclass TDistribution(BaseDistribution):\n    \"\"\"Student's t-distribution (sktime native).\n\n    Parameters\n    ----------\n    mean : float or array of float (1D or 2D)\n        mean of the t-distribution distribution\n    sd : float or array of float (1D or 2D), must be positive\n        standard deviation of the t-distribution distribution\n    df : float or array of float (1D or 2D), must be positive\n        Degrees of freedom of the t-distribution\n    index : pd.Index, optional, default = RangeIndex\n    columns : pd.Index, optional, default = RangeIndex\n\n    Example\n    -------\n    >>> from sktime.proba.t import TDistribution\n\n    >>> n = TDistribution(mu=[[0, 1], [2, 3], [4, 5]], sigma=1, df=10)\n    \"\"\"\n\n    _tags = {\n        \"authors\": [\"Alex-JG3\"],\n        \"maintainers\": [\"Alex-JG3\"],\n        \"capabilities:approx\": [\"pdfnorm\", \"energy\"],\n        \"capabilities:exact\": [\"mean\", \"var\", \"pdf\", \"log_pdf\", \"cdf\", \"ppf\"],\n        \"distr:measuretype\": \"continuous\",\n    }\n\n    def __init__(self, mu, sigma, df=1, index=None, columns=None):\n        self.mu = mu\n        self.sigma = sigma\n        self.df = df\n        self.index = index\n        self.columns = columns\n\n        self._mu, self._sigma, self._df = self._get_bc_params(\n            self.mu, self.sigma, self.df\n        )\n        shape = self._mu.shape\n\n        if index is None:\n            index = pd.RangeIndex(shape[0])\n\n        if columns is None:\n            columns = pd.RangeIndex(shape[1])\n\n        super().__init__(index=index, columns=columns)\n\n    def mean(self):\n        r\"\"\"Return expected value of the distribution.\n\n        Let :math:`X` be a random variable with the distribution of `self`.\n        Returns the expectation :math:`\\mathbb{E}[X]`. The expectation,\n        :math:`\\mathbb{E}[X]`, as infinite if :math:`\\nu \\le 1`.\n\n        Returns\n        -------\n        pd.DataFrame with same rows, columns as `self`\n        expected value of distribution (entry-wise)\n        \"\"\"\n        mean_arr = self._mu.copy()\n        if (self._df <= 1).any():\n            mean_arr = mean_arr.astype(np.float32)\n            mean_arr[self._df <= 1] = np.inf\n        return pd.DataFrame(mean_arr, index=self.index, columns=self.columns)\n\n    def var(self):\n        r\"\"\"Return element/entry-wise variance of the distribution.\n\n        Let :math:`X` be a random variable with the distribution of `self`.\n        Returns,\n\n        .. math::\n            \\mathbb{V}[X] = \\begin{cases}\n                \\frac{\\nu}{\\nu - 2} & \\text{if} \\nu > 2, \\\\\n                \\infty              & \\text{if} \\nu \\le 2, \\\\\n            \\begin{cases}\n\n        Where :math:`\\nu` is the degrees of freedom of the t-distribution.\n\n        Returns\n        -------\n        pd.DataFrame with same rows, columns as `self`\n        variance of distribution (entry-wise)\n        \"\"\"\n        df_arr = self._df.copy()\n        df_arr = df_arr.astype(np.float32)\n        df_arr[df_arr <= 2] = np.inf\n        mask = (df_arr > 2) & (df_arr != np.inf)\n        df_arr[mask] = self._sigma[mask] ** 2 * df_arr[mask] / (df_arr[mask] - 2)\n        return pd.DataFrame(df_arr, index=self.index, columns=self.columns)\n\n    def pdf(self, x):\n        \"\"\"Probability density function.\"\"\"\n        d = self.loc[x.index, x.columns]\n        pdf_arr = gamma((d._df + 1) / 2)\n        pdf_arr = pdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))\n        pdf_arr = pdf_arr * (1 + ((x - d._mu) / d._sigma) ** 2 / d._df) ** (\n            -(d._df + 1) / 2\n        )\n        pdf_arr = pdf_arr / d._sigma\n        return pd.DataFrame(pdf_arr, index=x.index, columns=x.columns)\n\n    def log_pdf(self, x):\n        \"\"\"Logarithmic probability density function.\"\"\"\n        d = self.loc[x.index, x.columns]\n        lpdf_arr = loggamma((d._df + 1) / 2)\n        lpdf_arr = lpdf_arr - 0.5 * np.log(d._df * np.pi)\n        lpdf_arr = lpdf_arr - loggamma(d._df / 2)\n        lpdf_arr = lpdf_arr - ((d._df + 1) / 2) * np.log(\n            1 + ((x - d._mu) / d._sigma) ** 2 / d._df\n        )\n        lpdf_arr = lpdf_arr - np.log(d._sigma)\n        return pd.DataFrame(lpdf_arr, index=x.index, columns=x.columns)\n\n    def cdf(self, x):\n        \"\"\"Cumulative distribution function.\"\"\"\n        d = self.loc[x.index, x.columns]\n        x_ = (x - d._mu) / d._sigma\n        cdf_arr = x_ * gamma((d._df + 1) / 2)\n        cdf_arr = cdf_arr * hyp2f1(0.5, (d._df + 1) / 2, 3 / 2, -(x_**2) / d._df)\n        cdf_arr = 0.5 + cdf_arr / (np.sqrt(np.pi * d._df) * gamma(d._df / 2))\n        return pd.DataFrame(cdf_arr, index=x.index, columns=x.columns)\n\n    def ppf(self, p):\n        \"\"\"Quantile function = percent point function = inverse cdf.\"\"\"\n        d = self.loc[p.index, p.columns]\n        ppf_arr = p.to_numpy(copy=True)\n        ppf_arr[p.values == 0.5] = 0.0\n        ppf_arr[p.values <= 0] = -np.inf\n        ppf_arr[p.values >= 1] = np.inf\n\n        mask1 = (p.values < 0.5) & (p.values > 0)\n        mask2 = (p.values < 1) & (p.values > 0.5)\n        ppf_arr[mask1] = 1 / betaincinv(0.5 * d._df[mask1], 0.5, 2 * ppf_arr[mask1])\n        ppf_arr[mask2] = 1 / betaincinv(\n            0.5 * d._df[mask2], 0.5, 2 * (1 - ppf_arr[mask2])\n        )\n        ppf_arr[mask1 | mask2] = np.sqrt(ppf_arr[mask1 | mask2] - 1)\n        ppf_arr[mask1 | mask2] = np.sqrt(d._df[mask1 | mask2]) * ppf_arr[mask1 | mask2]\n        ppf_arr[mask1] = -ppf_arr[mask1]\n        ppf_arr = d._sigma * ppf_arr + d._mu\n        return pd.DataFrame(ppf_arr, index=p.index, columns=p.columns)\n\n    @classmethod\n    def get_test_params(cls, parameter_set=\"default\"):\n        \"\"\"Return testing parameter settings for the estimator.\"\"\"\n        params1 = {\"mu\": [[0, 1], [2, 3], [4, 5]], \"sigma\": 1}\n        params2 = {\n            \"mu\": 0,\n            \"sigma\": 1,\n            \"index\": pd.Index([1, 2, 5]),\n            \"columns\": pd.Index([\"a\", \"b\"]),\n        }\n        return [params1, params2]\n", "path": "sktime/proba/t.py"}]}