double HierarchicalGaussianProcess::negativeTotalLogLikelihood() { /*This is the restricted version. For the unrestricted, make p=0 and remove the last term of loglik*/ const matrixd K = computeCorrMatrix(); const size_t n = K.size1(); const size_t p = mFeatM.size1(); matrixd L(n,n); utils::cholesky_decompose(K,L); matrixd KF(ublas::trans(mFeatM)); inplace_solve(L,KF,ublas::lower_tag()); matrixd FKF = prod(ublas::trans(KF),KF); matrixd L2(p,p); utils::cholesky_decompose(FKF,L2); vectord Ky(mGPY); inplace_solve(L,Ky,ublas::lower_tag()); vectord wML = prod(Ky,KF); utils::cholesky_solve(L2,wML,ublas::lower()); vectord alpha = mGPY - prod(wML,mFeatM); inplace_solve(L,alpha,ublas::lower_tag()); double sigma = ublas::inner_prod(alpha,alpha)/(n-p); double loglik = .5*(n-p)*log(ublas::inner_prod(alpha,alpha)) + utils::log_trace(L) + utils::log_trace(L2); return loglik; }
void StudentTProcessJeffreys::precomputePrediction() { size_t n = mData.getNSamples(); size_t p = mMean.nFeatures(); mKn.resize(n); mKF = trans(mMean.mFeatM); inplace_solve(mL,mKF,ublas::lower_tag()); matrixd FKF = prod(trans(mKF),mKF); mL2 = FKF; utils::cholesky_decompose(FKF,mL2); vectord Ky(mData.mY); inplace_solve(mL,Ky,ublas::lower_tag()); mWML = prod(Ky,mKF); utils::cholesky_solve(mL2,mWML,ublas::lower()); mAlphaF = mData.mY - prod(mWML,mMean.mFeatM); inplace_solve(mL,mAlphaF,ublas::lower_tag()); mSigma = inner_prod(mAlphaF,mAlphaF)/(n-p); d_->setDof(n-p); }