# Path: bambi/families/link.py
# class Link:
#     """Representation of link function.
# 
#     This object contains two main functions. One is the link function itself, the function
#     that maps values in the response scale to the linear predictor, and the other is the inverse
#     of the link function, that maps values of the linear predictor to the response scale.
# 
#     The great majority of users will never interact with this class unless they want to create
#     a custom ``Family`` with a custom ``Link``. This is automatically handled for all the built-in
#     families.
# 
#     Parameters
#     ----------
#     name: str
#         The name of the link function. If it is a known name, it's not necessary to pass any
#         other arguments because functions are already defined internally. If not known, all of
#         ``link``, ``linkinv`` and ``linkinv_backend`` must be specified.
#     link: function
#         A function that maps the response to the linear predictor. Known as the :math:`g` function
#         in GLM jargon. Does not need to be specified when ``name`` is a known name.
#     linkinv: function
#         A function that maps the linear predictor to the response. Known as the :math:`g^{-1}`
#         function in GLM jargon. Does not need to be specified when ``name`` is a known name.
#     linkinv_backend: function
#         Same than ``linkinv`` but must be something that works with PyMC3 backend (i.e. it must
#         work with Theano tensors). Does not need to be specified when ``name`` is a known
#         name.
# 
#     """
# 
#     def __init__(self, name, link=None, linkinv=None, linkinv_backend=None):
#         self.name = name
#         self.link = link
#         self.linkinv = linkinv
#         self.linkinv_backend = linkinv_backend
# 
#         if name in LINKS:
#             self.link = LINKS[name]["link"]
#             self.linkinv = LINKS[name]["linkinv"]
#         else:
#             if not link or not linkinv or not linkinv_backend:
#                 raise ValueError(
#                     f"Link name '{name}' is not supported and at least one of 'link', "
#                     "'linkinv' or 'linkinv_backend' are unespecified."
#                 )
# 
#     def __str__(self):
#         args = [f"name: {self.name}", f"link: {self.link}", f"linkinv: {self.linkinv}"]
#         return f"{self.__class__.__name__}({spacify(multilinify(args))}\n)"
# 
#     def __repr__(self):
#         return self.__str__()


from statsmodels.genmod import families as sm_families
from bambi.families.link import Link

    SUPPORTED_LINKS = [
        "cloglog",
        "identity",
        "inverse_squared",
        "inverse",
        "log",
        "logit",
        "probit",
        "softmax",
        "tan_2",
    ]

    def __init__(self, name, likelihood, link):
        self.name = name
        self.likelihood = likelihood
        self.link = link
        self.smfamily = STATSMODELS_FAMILIES.get(name, None)
        self.aliases = {}

    @property
    def link(self):
        return self._link

    @link.setter
    def link(self, x):
        if isinstance(x, str):
            self.check_string_link(x)
            self._link = Link(x)
            self.smlink = STATSMODELS_LINKS.get(x, None)

# Path: bambi/families/link.py
# class Link:
#     """Representation of link function.
# 
#     This object contains two main functions. One is the link function itself, the function
#     that maps values in the response scale to the linear predictor, and the other is the inverse
#     of the link function, that maps values of the linear predictor to the response scale.
# 
#     The great majority of users will never interact with this class unless they want to create
#     a custom ``Family`` with a custom ``Link``. This is automatically handled for all the built-in
#     families.
# 
#     Parameters
#     ----------
#     name: str
#         The name of the link function. If it is a known name, it's not necessary to pass any
#         other arguments because functions are already defined internally. If not known, all of
#         ``link``, ``linkinv`` and ``linkinv_backend`` must be specified.
#     link: function
#         A function that maps the response to the linear predictor. Known as the :math:`g` function
#         in GLM jargon. Does not need to be specified when ``name`` is a known name.
#     linkinv: function
#         A function that maps the linear predictor to the response. Known as the :math:`g^{-1}`
#         function in GLM jargon. Does not need to be specified when ``name`` is a known name.
#     linkinv_backend: function
#         Same than ``linkinv`` but must be something that works with PyMC3 backend (i.e. it must
#         work with Theano tensors). Does not need to be specified when ``name`` is a known
#         name.
# 
#     """
# 
#     def __init__(self, name, link=None, linkinv=None, linkinv_backend=None):
#         self.name = name
#         self.link = link
#         self.linkinv = linkinv
#         self.linkinv_backend = linkinv_backend
# 
#         if name in LINKS:
#             self.link = LINKS[name]["link"]
#             self.linkinv = LINKS[name]["linkinv"]
#         else:
#             if not link or not linkinv or not linkinv_backend:
#                 raise ValueError(
#                     f"Link name '{name}' is not supported and at least one of 'link', "
#                     "'linkinv' or 'linkinv_backend' are unespecified."
#                 )
# 
#     def __str__(self):
#         args = [f"name: {self.name}", f"link: {self.link}", f"linkinv: {self.linkinv}"]
#         return f"{self.__class__.__name__}({spacify(multilinify(args))}\n)"
# 
#     def __repr__(self):
#         return self.__str__()


# Path: bambi/families/family.py
from statsmodels.genmod import families as sm_families
from bambi.families.link import Link


    SUPPORTED_LINKS = [
        "cloglog",
        "identity",
        "inverse_squared",
        "inverse",
        "log",
        "logit",
        "probit",
        "softmax",
        "tan_2",
    ]

    def __init__(self, name, likelihood, link):
        self.name = name
        self.likelihood = likelihood
        self.link = link
        self.smfamily = STATSMODELS_FAMILIES.get(name, None)
        self.aliases = {}

    @property
    def link(self):
        return self._link

    @link.setter
    def link(self, x):
        if isinstance(x, str):
            self.check_string_link(x)
            self._link = Link(x)
            self.smlink = STATSMODELS_LINKS.get(x, None)

        elif isinstance(x, Link):