def build_penalties(self):
        """
        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
        """
        P = []
        for term in self._terms:
            P.append(term.build_penalties())
        return sp.sparse.block_diag(P)
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