double RegSuf::relative_sse(const GlmCoefs &coefficients) const {
   double ans = yty();
   const Selector &inc(coefficients.inc());
   if (inc.nvars() == 0) {
     return ans;
   }
   const SpdMatrix xtx(this->xtx(inc));
   const Vector xty(this->xty(inc));
   const Vector beta(coefficients.included_coefficients());
   ans += beta.dot(xtx * beta) - 2 * beta.dot(xty);
   return ans;
 }
  double RM::Loglike(const Vector &sigsq_beta,
                     Vector &g, Matrix &h, uint nd)const{
    const double log2pi = 1.83787706640935;
    const double sigsq = sigsq_beta[0];
    const Vector b(ConstVectorView(sigsq_beta, 1));
    double n = suf()->n();
    if(b.size()==0) return empty_loglike(g, h, nd);

    double SSE = yty() - 2*b.dot(xty()) + xtx().Mdist(b);
    double ans =  -.5*(n * log2pi  + n *log(sigsq)+ SSE/sigsq);

    if(nd>0){  // sigsq derivs come first in CP2 vectorization
      SpdMatrix xtx = this->xtx();
      Vector gbeta = (xty() - xtx*b)/sigsq;
      double sig4 = sigsq*sigsq;
      double gsigsq = -n/(2*sigsq) + SSE/(2*sig4);
      g = concat(gsigsq, gbeta);
      if(nd>1){
        double h11 = .5*n/sig4 - SSE/(sig4*sigsq);
        h = unpartition(h11, (-1/sigsq)*gbeta, (-1/sigsq)*xtx);}}
    return ans;
  }
 SpdMatrix MvRegSuf::SSE(const Matrix &B) const {
   SpdMatrix ans = yty();
   ans.add_inner2(B, xty(), -1);
   ans += sandwich(B.transpose(), xtx());
   return ans;
 }
 double NeRegSuf::SSE()const{
   SpdMatrix ivar = xtx().inv();
   return yty() - ivar.Mdist(xty()); }
 ostream & QrRegSuf::print(ostream &out)const{
   return out << "sumsqy = " << yty() << endl
              << "xty_ = " << xty() << endl
              << "xtx  = " << endl << xtx();
 }