diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 00000000..fb90c2c7
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+joe.py
\ No newline at end of file
diff --git a/.idea/Copulas.iml b/.idea/Copulas.iml
new file mode 100644
index 00000000..3ed51aed
--- /dev/null
+++ b/.idea/Copulas.iml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 00000000..105ce2da
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..55d79d65
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..0cc68576
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..35eb1ddf
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/copulas/bivariate/__init__.py b/copulas/bivariate/__init__.py
index dafbc821..70a65724 100644
--- a/copulas/bivariate/__init__.py
+++ b/copulas/bivariate/__init__.py
@@ -8,6 +8,7 @@
from copulas.bivariate.clayton import Clayton
from copulas.bivariate.frank import Frank
from copulas.bivariate.gumbel import Gumbel
+from copulas.bivariate.joe import Joe
from copulas.bivariate.utils import split_matrix
__all__ = (
@@ -16,6 +17,7 @@
'CopulaTypes',
'Frank',
'Gumbel',
+ 'Joe'
)
@@ -96,8 +98,13 @@ def _compute_candidates(copulas, left_tail, right_tail):
X_right = np.column_stack((right_tail, right_tail))
for copula in copulas:
- left.append(copula.cumulative_distribution(X_left) / np.power(left_tail, 2))
- right.append(_compute_tail(copula.cumulative_distribution(X_right), right_tail))
+ if isinstance(copula, Joe):
+ # Compute dependencies for Joe copula
+ left.append(...)
+ right.append(...)
+ else:
+ left.append(copula.cumulative_distribution(X_left) / np.power(left_tail, 2))
+ right.append(_compute_tail(copula.cumulative_distribution(X_right), right_tail))
return left, right
@@ -140,7 +147,7 @@ def select_copula(X):
copula_candidates = [frank]
# append copulas into the candidate list
- for copula_class in [Clayton, Gumbel]:
+ for copula_class in [Clayton, Gumbel, Joe]:
try:
copula = copula_class()
copula.tau = frank.tau
diff --git a/copulas/bivariate/joe.py b/copulas/bivariate/joe.py
new file mode 100644
index 00000000..387e7a88
--- /dev/null
+++ b/copulas/bivariate/joe.py
@@ -0,0 +1,87 @@
+import numpy as np
+from copulas.bivariate.base import Bivariate, CopulaTypes
+from copulas.bivariate.utils import split_matrix
+
+class Joe(Bivariate):
+ """Class for Joe copula model."""
+
+ copula_type = CopulaTypes.JOE
+ theta_interval = [0, float('inf')]
+ invalid_thetas = [0]
+
+ def __init__(self, theta=1):
+ """
+ Initialize a Joe copula.
+
+ Parameters:
+ - theta (float): The theta parameter of the Joe copula. Default is 1.
+ """
+ self.theta = theta
+
+ def generator(self, t):
+ """
+ Compute the generator function of the Joe copula.
+
+ The generator function of the Joe copula is defined as:
+
+ .. math:: G(t) = -((1 - t^(-theta))^(-1/theta))
+
+ Parameters:
+ - t (float or np.array): The value(s) at which to evaluate the generator.
+
+ Returns:
+ - float or np.array: The value(s) of the generator function at t.
+ """
+ return -((1 - t ** (-self.theta)) ** (1 / self.theta))
+
+ def pdf(self, X):
+ """
+ Compute the probability density function for the Joe copula.
+
+ The probability density function (PDF) for the Joe copula is given by:
+
+ .. math:: c(u, v) = (theta - 1) * (u^(-theta) + v^(-theta) - 1)^(theta - 2) * u^(-theta - 1) * v^(-theta - 1)
+
+ Parameters:
+ - X (np.array): The input array of shape (n, 2) containing pairs of values (u, v).
+
+ Returns:
+ - np.array: The probability density values for each pair in X.
+ """
+ U, V = split_matrix(X)
+ return (self.theta - 1) * (U ** (-self.theta) + V ** (-self.theta) - 1) ** (self.theta - 2) * U ** (-self.theta - 1) * V ** (-self.theta - 1)
+
+ def cdf(self, X):
+ """
+ Compute the cumulative distribution function for the Joe copula.
+
+ The cumulative distribution function (CDF) for the Joe copula is given by:
+
+ .. math:: C(u, v) = (u^(-theta) + v^(-theta) - 1)^theta
+
+ Parameters:
+ - X (np.array): The input array of shape (n, 2) containing pairs of values (u, v).
+
+ Returns:
+ - np.array: The cumulative distribution values for each pair in X.
+ """
+ U, V = split_matrix(X)
+ return (U ** (-self.theta) + V ** (-self.theta) - 1) ** self.theta
+
+ def percent_point(self, y, V):
+ """
+ Compute the inverse of conditional cumulative distribution :math:`C(u|v)^{-1}`.
+
+ The inverse of conditional cumulative distribution :math:`C(u|v)^{-1}` for the Joe copula
+ is given by:
+
+ .. math:: (y^(1/theta) + v^(-theta) - 1)^(-1/theta)
+
+ Parameters:
+ - y (float or np.array): The value(s) of :math:`C(u|v)`.
+ - V (float or np.array): The given value(s) of v.
+
+ Returns:
+ - float or np.array: The inverse of conditional cumulative distribution values.
+ """
+ return (y ** (1 / self.theta) + V ** (-self.theta) - 1) ** (-1 / self.theta)