code: def dlogpdf_dlink(self, link_f, y, Y_metadata=None):
          
          assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape
          c = np.zeros_like(y)
          if Y_metadata is not None and 'censored' in Y_metadata.keys():
              c = Y_metadata['censored']
  
          val = np.log(y) - link_f
          val_scaled = val/np.sqrt(self.variance)
          val_scaled2 = val/self.variance
          uncensored = (1-c)*(val_scaled2)
          a = (1- stats.norm.cdf(val_scaled))
          # llg(z) = 1. / (1 - norm_cdf(r / sqrt(s2))). * (1 / sqrt(2 * pi * s2). * exp(-1 / (2. * s2). * r. ^ 2));
          censored = c*( 1./a) * (np.exp(-1.* val**2 /(2*self.variance)) / np.sqrt(2*np.pi*self.variance))
          # censored = c * (1. / (1 - stats.norm.cdf(val_scaled))) * (stats.norm.pdf(val_scaled))
          gradient = uncensored + censored
          return gradient
docs: derivative of logpdf wrt link_f param
          .. 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