code: def update(self, w, offset=0):
          
          time = self.time
          x = self.x
          exp_xw = numpy.exp(offset + numpy.dot(x, w))
          n_samples, n_features = x.shape
  
          gradient = numpy.zeros((1, n_features), dtype=float)
          hessian = numpy.zeros((n_features, n_features), dtype=float)
  
          inv_n_samples = 1. / n_samples
          risk_set = 0
          risk_set_x = 0
          risk_set_xx = 0
          k = 0
          # iterate time in descending order
          for i in range(n_samples):
              ti = time[i]
              while k < n_samples and ti == time[k]:
                  risk_set += exp_xw[k]
  
                  # preserve 2D shape of row vector
                  xk = x[k:k + 1]
                  risk_set_x += exp_xw[k] * xk
  
                  # outer product
                  xx = numpy.dot(xk.T, xk)
                  risk_set_xx += exp_xw[k] * xx
  
                  k += 1
  
              if self.event[i]:
                  gradient -= (x[i:i + 1] - risk_set_x / risk_set) * inv_n_samples
  
                  a = risk_set_xx / risk_set
                  z = risk_set_x / risk_set
                  # outer product
                  b = numpy.dot(z.T, z)
  
                  hessian += (a - b) * inv_n_samples
  
          if self.alpha > 0:
              gradient += self.alpha * inv_n_samples * w
  
              diag_idx = numpy.diag_indices(n_features)
              hessian[diag_idx] += self.alpha * inv_n_samples
  
          self.gradient = gradient.ravel()
          self.hessian = hessian
docs: Compute gradient and Hessian matrix with respect to `w`.