Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 47 additions & 42 deletions pycopula/archimedean_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,75 @@
# -*- coding: utf-8 -*-

"""
This file contains the generators and their inverses for common archimedean copulas.
This file contains the generators and their inverses for common archimedean copulas.
"""

import numpy as np

def boundsConditions(x):
if x < 0 or x > 1:
raise ValueError("Unable to compute generator for x equals to {}".format(x))
if x < 0 or x > 1:
raise ValueError("Unable to compute generator for x equals to {}".format(x))

def claytonGenerator(x, theta):
boundsConditions(x)
if theta == 0:
raise ValueError("The parameter of a Clayton copula must not be equal to 0.")
if theta < -1:
raise ValueError("The parameter of a Clayton copula must be greater than -1 and different from 0.")
return (1. / theta) * (x**(-theta) - 1.)
boundsConditions(x)
if theta == 0:
raise ValueError("The parameter of a Clayton copula must not be equal to 0.")
if theta < -1:
raise ValueError("The parameter of a Clayton copula must be greater than -1 and different from 0.")
return (1. / theta) * (x**(-theta) - 1.)

def claytonGeneratorInvert(x, theta):
if theta == 0:
raise ValueError("The parameter of a Clayton copula must not be equal to 0.")
if theta < -1:
raise ValueError("The parameter of a Clayton copula must be greater than -1 and different from 0.")
return (1. + theta * x)**(-1. / theta)
if theta == 0:
raise ValueError("The parameter of a Clayton copula must not be equal to 0.")
if theta < -1:
raise ValueError("The parameter of a Clayton copula must be greater than -1 and different from 0.")
return (1. + theta * x)**(-1. / max(theta,1e-6))

def gumbelGenerator(x, theta):
boundsConditions(x)
if theta < 1:
raise ValueError("The parameter of a Gumbel copula must be greater than 1.")
return (-np.log(x))**theta
boundsConditions(x)
if theta < 1:
raise ValueError("The parameter of a Gumbel copula must be greater than 1.")
return (-np.log(x))**theta

def gumbelGeneratorInvert(x, theta):
if theta < 1:
raise ValueError("The parameter of a Gumbel copula must be greater than 1.")
return np.exp(-x**(1. / theta))
if len(theta) > 1:
theta = theta[0]
if theta < 1:
raise ValueError("The parameter of a Gumbel copula must be greater than 1.")
if (x < 1 and theta != 1):
raise(ValueError("The inverse Gumbel generator cannot be evaluated for negative input and theta > 1"))
return np.exp(-np.power(x,np.divide(1, theta)))


def frankGenerator(x, theta):
boundsConditions(x)
if theta == 0:
raise ValueError("The parameter of a Frank copula must not be equal to 0.")
return -np.log((np.exp(-theta * x) - 1.) / (np.exp(-theta) - 1.))
boundsConditions(x)
if theta == 0:
raise ValueError("The parameter of a Frank copula must not be equal to 0.")
return -np.log((np.exp(-theta[0] * x) - 1) / (np.exp(-theta[0]) - 1))

def frankGeneratorInvert(x, theta):
if theta == 0:
raise ValueError("The parameter of a Frank copula must not be equal to 0.")
return -1. / theta * np.log(1. + np.exp(-x) * (np.exp(-theta) - 1.))
if theta == 0:
raise ValueError("The parameter of a Frank copula must not be equal to 0.")
return -1. / theta * np.log(1. + np.exp(-x) * (np.exp(-theta) - 1.))

def joeGenerator(x, theta):
boundsConditions(x)
if theta < 1:
raise ValueError("The parameter of a Joe copula must be greater than 1.")
return -np.log(1. - (1. - x)**theta)
boundsConditions(x)
if theta < 1:
raise ValueError("The parameter of a Joe copula must be greater than 1.")
return -np.log(1. - (1. - x)**theta)

def joeGeneratorInvert(x, theta):
if theta < 1:
raise ValueError("The parameter of a Joe copula must be greater than 1.")
return 1. - (1. - np.exp(-x))**(1. / theta)
if theta < 1:
raise ValueError("The parameter of a Joe copula must be greater than 1.")
return 1. - (1. - np.exp(-x))**(1. / max(theta,1e-6))

def aliMikhailHaqGenerator(x, theta):
boundsConditions(x)
if theta < -1 or theta >= 1:
raise ValueError("The parameter of an Ali-Mikhail-Haq copula must be between -1 included and 1 excluded.")
return np.log((1. - theta * (1. - x)) / x)
boundsConditions(x)
if theta < -1 or theta >= 1:
raise ValueError("The parameter of an Ali-Mikhail-Haq copula must be between -1 included and 1 excluded.")
return np.log((1. - theta * (1. - x)) / x)

def aliMikhailHaqGeneratorInvert(x, theta):
if theta < -1 or theta >= 1:
raise ValueError("The parameter of an Ali-Mikhail-Haq copula must be between -1 included and 1 excluded.")
return (1. - theta) / (np.exp(x) - theta)
if theta < -1 or theta >= 1:
raise ValueError("The parameter of an Ali-Mikhail-Haq copula must be between -1 included and 1 excluded.")
return (1. - theta) / (np.exp(x) - theta)
Loading