Log Likelihood Function given link(f)

        .. math::


        :param link_f: latent variables (link(f))
        :type link_f: Nx1 array
        :param y: data
        :type y: Nx1 array
        :param Y_metadata: includes censoring information in dictionary key 'censored'
        :returns: likelihood evaluated for this point
        :rtype: float

def logpdf_link(self, link_f, y, Y_metadata=None):
        """
        Log Likelihood Function given link(f)

        .. math::


        :param link_f: latent variables (link(f))
        :type link_f: Nx1 array
        :param y: data
        :type y: Nx1 array
        :param Y_metadata: includes censoring information in dictionary key 'censored'
        :returns: likelihood evaluated for this point
        :rtype: float

        """
        # c = np.zeros((y.shape[0],))
        c = np.zeros_like(link_f)
        if Y_metadata is not None and  'censored' in Y_metadata.keys():
            c = Y_metadata['censored']

        link_f = np.clip(link_f, 1e-150, 1e100)
        # y_link_f = y/link_f
        # y_link_f_r = y_link_f**self.r
        # y_link_f_r = np.clip(y**self.r, 1e-150, 1e200) / np.clip(link_f**self.r, 1e-150, 1e200)
        # y_link_f_r = np.clip((y/link_f)**self.r, 1e-150, 1e200)
        y_r = np.clip(y**self.r, 1e-150, 1e200)
        link_f_r = np.clip(link_f**self.r, 1e-150, 1e200)
        y_link_f_r = np.clip(y_r / link_f_r, 1e-150, 1e200)
        #uncensored = (1-c)*(np.log(self.r) + (self.r+1)*np.log(y) - self.r*np.log(link_f) - 2*np.log1p(y_link_f_r))
        #uncensored = (1-c)*(np.log((self.r/link_f)*y_link_f**(self.r-1)) - 2*np.log1p(y_link_f_r))

        # clever way tp break it into censored and uncensored-parts ..
        uncensored = (1-c)*(np.log(self.r) + (self.r-1)*np.log(y) - self.r*np.log(link_f) - 2*np.log1p(y_link_f_r))
        censored = (c)*(-np.log1p(y_link_f_r))
        #
        return uncensored + censored