code: def build_constraints(self, coef, constraint_lam, constraint_l2):
          
          C = sp.sparse.csc_matrix(np.zeros((self.n_coefs, self.n_coefs)))
          for i in range(len(self._terms)):
              C += self._build_marginal_constraints(i, coef, constraint_lam, constraint_l2)
  
          return sp.sparse.csc_matrix(C)
docs: builds the GAM block-diagonal constraint matrix in quadratic form
          out of constraint matrices specified for each feature.
  
          Parameters
          ----------
          coefs : array-like containing the coefficients of a term
  
          constraint_lam : float,
              penalty to impose on the constraint.
  
              typically this is a very large number.
  
          constraint_l2 : float,
              loading to improve the numerical conditioning of the constraint
              matrix.
  
              typically this is a very small number.
  
          Returns
          -------
          C : sparse CSC matrix containing the model constraints in quadratic form