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);