code: def build_penalties(self):
          
          P = sp.sparse.csc_matrix(np.zeros((self.n_coefs, self.n_coefs)))
          for i in range(len(self._terms)):
              P += self._build_marginal_penalties(i)
  
          return sp.sparse.csc_matrix(P)
docs: builds the GAM block-diagonal penalty matrix in quadratic form
          out of penalty matrices specified for each feature.
  
          each feature penalty matrix is multiplied by a lambda for that feature.
  
          so for m features:
          P = block_diag[lam0 * P0, lam1 * P1, lam2 * P2, ... , lamm * Pm]
  
          Parameters
          ----------
          None
  
          Returns
          -------
          P : sparse CSC matrix containing the model penalties in quadratic form