void HouseMatrix(Matrix H,Vector v, int start, int end) { int i,j; double a; a = 2.0/xty(v,v,start,end); MakeID(H); for (i=start;i<=end;i++) for (j=start;j<=end;j++) H[i][j] -= a*v[i]*v[j]; }
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; }
int main() { auto b = genRandomVector(kDim); Matrix xtx(kDim); Vector xty(kDim); { Timer tGen("Generate"); constexpr u32 kVectorPoints = 4000 * kDim; for (u32 iVectorPoint = 0; iVectorPoint < kVectorPoints; ++iVectorPoint) { auto p = getRandomVectorPoint(b); for (size_t i = 0; i < p.dimension(); ++i) { for (size_t j = 0; j < p.dimension(); ++j) { xtx.data_[i][j] += p.a_[i] * p.a_[j]; } } for (size_t i = 0; i < p.dimension(); ++i) { xty[i] += p.a_[i] * p.b_; } } } { Timer tSolve("Invert"); auto inv = xtx.invert(); tSolve.finish(); Vector bPrime = inv * xty; LOG(INFO) << OUT(b) << OUT(length(b)); LOG(INFO) << OUT(bPrime) << OUT(length(bPrime)); auto err = b - bPrime; LOG(INFO) << OUT(err) << OUT(length(err)); } { Timer tSolve("Cholesky"); auto chol = xtx.cholesky(); tSolve.finish(); Matrix xtx2 = chol*chol.transpose(); LOG(INFO) << OUT(xtx.norm2()) << OUT(xtx2.norm2()) << OUT((xtx - xtx2).norm2()); } return 0; }
DoubleVector linearRegression(const VectorPoints& points, double rigid) { assert(!points.empty()); Matrix xtx(points[0].dimension()); Vector xty(points[0].dimension()); for (u32 iVectorPoint = 0; iVectorPoint < points.size(); ++iVectorPoint) { const auto& p = points[iVectorPoint]; assert(p.dimension() == xty.size()); for (size_t i = 0; i < p.dimension(); ++i) { for (size_t j = 0; j < p.dimension(); ++j) { xtx.data_[i][j] += p.a_[i] * p.a_[j]; } } for (size_t i = 0; i < p.dimension(); ++i) { xty[i] += p.a_[i] * p.b_; } } for (size_t i = 0; i < xtx.dimension(); ++i) { xtx.data_[i][i] += rigid; } xtx /= points.size(); for (auto& x : xty) { x /= points.size(); } auto b = xtx.invert() * xty; // cout << OUT((xtx.invert() * xtx - Matrix::one(xtx.dimension())).norm2()) << endl; /* for (size_t i = 0; i < points.size(); ++i) { const auto& p = points[i]; cout << OUT(p.b_) << OUT(dot(p.a_, b)) << OUT(p.a_[p.a_.size() - 2]) << endl; } */ return b; }
SpdMatrix MvRegSuf::SSE(const Matrix &B) const { SpdMatrix ans = yty(); ans.add_inner2(B, xty(), -1); ans += sandwich(B.transpose(), xtx()); return ans; }
Vector RM::xty()const{ return xty( coef().inc() ) ;}
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(); }
Vector QrRegSuf::xty(const Selector &inc)const{ // if(!current) refresh_qr(); return inc.select(xty()); }
//====================================================================== ostream & RegSuf::print(ostream &out)const{ out << "sample size: " << n() << endl << "xty: " << xty() << endl << "xtx: " << endl << xtx(); return out; }