24 using namespace shogun;
25 using namespace Eigen;
40 void CFITCInferenceMethod::init()
42 SG_ADD((
CSGObject**)&m_latent_features,
"latent_features",
"Latent features",
45 m_latent_features=NULL;
60 SG_SERROR(
"Provided inference is not of type CFITCInferenceMethod!\n")
79 "FITC inference method can only use Gaussian likelihood function\n")
81 "of CRegressionLabels\n")
82 REQUIRE(m_latent_features,
"Latent features should not be NULL\n")
84 "Number of latent features must be greater than zero\n")
110 Map<MatrixXd> eigen_chol_utr(m_chol_utr.
matrix, m_chol_utr.
num_rows,
112 Map<VectorXd> eigen_dg(m_dg.
vector, m_dg.
vlen);
114 Map<VectorXd> eigen_be(m_be.
vector, m_be.
vlen);
118 float64_t result=eigen_chol_utr.diagonal().array().log().sum()+
119 (eigen_dg.array().log().sum()+eigen_r.dot(eigen_r)-eigen_be.dot(eigen_be)+
187 LLT<MatrixXd> Luu(eigen_kuu+m_ind_noise*MatrixXd::Identity(
195 eigen_chol_uu=Luu.matrixU();
198 MatrixXd V=eigen_chol_uu.triangularView<Upper>().adjoint().solve(eigen_ktru);
199 MatrixXd sV=V.cwiseProduct(V);
204 Map<VectorXd> eigen_dg(m_dg.
vector, m_dg.
vlen);
205 VectorXd eigen_idg(m_dg.
vlen);
210 eigen_idg[i]=1.0/eigen_dg[i];
214 LLT<MatrixXd> Lu(V*eigen_idg.asDiagonal()*V.transpose()+
220 Map<MatrixXd> eigen_chol_utr(m_chol_utr.matrix, m_chol_utr.num_rows,
221 m_chol_utr.num_rows);
222 eigen_chol_utr = Lu.matrixU();
231 VectorXd sqrt_dg=eigen_dg.array().
sqrt();
237 eigen_r=(eigen_y-eigen_m).cwiseQuotient(sqrt_dg);
241 Map<VectorXd> eigen_be(m_be.
vector, m_be.
vlen);
242 eigen_be=eigen_chol_utr.triangularView<Upper>().adjoint().solve(
243 V*eigen_r.cwiseQuotient(sqrt_dg));
246 MatrixXd iKuu=Luu.solve(MatrixXd::Identity(m_kuu.
num_rows, m_kuu.
num_cols));
249 MatrixXd eigen_prod=eigen_chol_utr*eigen_chol_uu;
253 eigen_chol=eigen_prod.triangularView<Upper>().adjoint().solve(
255 eigen_chol=eigen_prod.triangularView<Upper>().solve(eigen_chol)-iKuu;
262 Map<MatrixXd> eigen_chol_utr(m_chol_utr.
matrix, m_chol_utr.
num_rows,
264 Map<VectorXd> eigen_be(m_be.
vector, m_be.
vlen);
271 eigen_alpha=eigen_chol_utr.triangularView<Upper>().solve(eigen_be);
272 eigen_alpha=eigen_chol_uu.triangularView<Upper>().solve(eigen_alpha);
283 Map<VectorXd> eigen_dg(m_dg.
vector, m_dg.
vlen);
284 Map<VectorXd> eigen_be(m_be.
vector, m_be.
vlen);
295 MatrixXd V=eigen_Luu.triangularView<Upper>().adjoint().solve(eigen_Ktru);
299 Map<VectorXd> eigen_al(m_al.
vector, m_al.
vlen);
302 eigen_al=((eigen_y-eigen_m)-(V.adjoint()*
303 eigen_Lu.triangularView<Upper>().solve(eigen_be))).cwiseQuotient(eigen_dg);
306 MatrixXd iKuu=eigen_Luu.triangularView<Upper>().adjoint().solve(
308 iKuu=eigen_Luu.triangularView<Upper>().solve(iKuu);
314 eigen_B=iKuu*eigen_Ktru;
320 eigen_w=eigen_B*eigen_al;
327 eigen_W=eigen_Lu.triangularView<Upper>().adjoint().solve(V*VectorXd::Ones(
328 m_dg.
vlen).cwiseQuotient(eigen_dg).asDiagonal());
334 REQUIRE(!strcmp(param->
m_name,
"scale"),
"Can't compute derivative of "
335 "the nagative log marginal likelihood wrt %s.%s parameter\n",
339 Map<VectorXd> eigen_dg(m_dg.
vector, m_dg.
vlen);
340 Map<VectorXd> eigen_al(m_al.
vector, m_al.
vlen);
351 Map<VectorXd> ddiagKi(deriv_trtr.
vector, deriv_trtr.
vlen);
361 MatrixXd R=2*dKui-dKuui*eigen_B;
364 VectorXd v=ddiagKi-R.cwiseProduct(eigen_B).colwise().sum().adjoint();
370 result[0]=(ddiagKi.dot(VectorXd::Ones(m_dg.
vlen).cwiseQuotient(eigen_dg))+
371 eigen_w.dot(dKuui*eigen_w-2*(dKui*eigen_al))-
372 eigen_al.dot(v.cwiseProduct(eigen_al))-
373 eigen_W.cwiseProduct(eigen_W).colwise().sum().dot(v)-
374 (R*eigen_W.adjoint()).cwiseProduct(eigen_B*eigen_W.adjoint()).sum())/2.0;
382 REQUIRE(!strcmp(param->
m_name,
"sigma"),
"Can't compute derivative of "
383 "the nagative log marginal likelihood wrt %s.%s parameter\n",
387 Map<VectorXd> eigen_dg(m_dg.
vector, m_dg.
vlen);
388 Map<VectorXd> eigen_al(m_al.
vector, m_al.
vlen);
400 result[0]=
CMath::sq(sigma)*(VectorXd::Ones(m_dg.
vlen).cwiseQuotient(
401 eigen_dg).sum()-eigen_W.cwiseProduct(eigen_W).sum()-eigen_al.dot(eigen_al));
404 MatrixXd R=-dKuui*eigen_B;
405 VectorXd v=-R.cwiseProduct(eigen_B).colwise().sum().adjoint();
407 result[0]=result[0]+((eigen_w.dot(dKuui*eigen_w))-eigen_al.dot(
408 v.cwiseProduct(eigen_al))-eigen_W.cwiseProduct(eigen_W).colwise().sum().dot(v)-
409 (R*eigen_W.adjoint()).cwiseProduct(eigen_B*eigen_W.adjoint()).sum())/2.0;
418 Map<VectorXd> eigen_dg(m_dg.
vector, m_dg.
vlen);
419 Map<VectorXd> eigen_al(m_al.
vector, m_al.
vlen);
430 "Length of the parameter %s should not be NULL\n", param->
m_name)
470 Map<VectorXd> ddiagKi(deriv_trtr.
vector, deriv_trtr.
vlen);
477 MatrixXd R=2*dKui-dKuui*eigen_B;
480 VectorXd v=ddiagKi-R.cwiseProduct(eigen_B).colwise().sum().adjoint();
484 result[i]=(ddiagKi.dot(VectorXd::Ones(m_dg.
vlen).cwiseQuotient(eigen_dg))+
485 eigen_w.dot(dKuui*eigen_w-2*(dKui*eigen_al))-
486 eigen_al.dot(v.cwiseProduct(eigen_al))-
487 eigen_W.cwiseProduct(eigen_W).colwise().sum().dot(v)-
488 (R*eigen_W.adjoint()).cwiseProduct(eigen_B*eigen_W.adjoint()).sum())/2.0;
498 Map<VectorXd> eigen_al(m_al.
vector, m_al.
vlen);
506 "Length of the parameter %s should not be NULL\n", param->
m_name)
524 Map<VectorXd> eigen_dmu(dmu.
vector, dmu.
vlen);
527 result[i]=-eigen_dmu.
dot(eigen_al);