37 #include <shogun/lib/external/brent.h>
42 using namespace Eigen;
47 #ifndef DOXYGEN_SHOULD_SKIP_THIS
50 class CFITCPsiLine :
public func_base
65 virtual double operator() (
double x)
73 eigen_alpha=start_alpha+x*dalpha;
77 eigen_f=eigen_tmp+eigen_m;
86 float64_t result = eigen_alpha.dot(eigen_f-eigen_m)/2.0-
107 void CSingleFITCLaplacianInferenceMethod::init()
183 eigen_res=eigen_x.cwiseProduct(eigen_t)-eigen_Rvdd.transpose()*(eigen_Rvdd*eigen_x);
198 eigen_res= eigen_V.transpose()*(eigen_V*eigen_al)+eigen_dg.cwiseProduct(eigen_al);
205 REQUIRE(inference!=NULL,
"Inference should be not NULL");
208 SG_SERROR(
"Provided inference is not of type CSingleFITCLaplacianInferenceMethod!\n")
220 LLT<MatrixXd> chol(eigen_mtx.colwise().reverse().rowwise().reverse().matrix());
226 eigen_res=tmp.colwise().reverse().rowwise().reverse().matrix().triangularView<Upper>(
238 SG_WARNING(
"nlZ cannot be computed since W is too negative");
254 LLT<MatrixXd> chol(A);
261 float64_t result=eigen_alpha.dot(eigen_mu-eigen_mean)/2.0-lp+
262 A.diagonal().array().log().sum()+(eigen_W.cwiseProduct(eigen_dg)+MatrixXd::Ones(eigen_dg.rows(),1)).array().log().sum()/2.0;
297 eigen_dg=eigen_ktrtr_diag*
CMath::exp(
m_log_scale*2.0)-(eigen_V.cwiseProduct(eigen_V)).colwise().sum().adjoint();
328 eigen_mu=eigen_tmp+eigen_mean;
330 Psi_New=eigen_alpha.dot(eigen_tmp)/2.0-
336 if (Psi_Def < Psi_New)
383 if (eigen_W.minCoeff() < 0)
398 eigen_W+=(2.0/(df+1))*eigen_dlp.cwiseProduct(eigen_dlp);
402 VectorXd b=eigen_W.cwiseProduct(eigen_mu-eigen_mean)+eigen_dlp;
405 VectorXd dd=MatrixXd::Ones(b.rows(),1).cwiseQuotient(eigen_W.cwiseProduct(eigen_dg)+MatrixXd::Ones(b.rows(),1));
407 VectorXd eigen_t=eigen_W.cwiseProduct(dd);
412 eigen_tmp=eigen_V*eigen_t.asDiagonal()*eigen_V.transpose()+MatrixXd::Identity(tmp.
num_rows,tmp.
num_rows);
418 MatrixXd eigen_RV=eigen_tmp2*eigen_V;
420 VectorXd dalpha=dd.cwiseProduct(b)-eigen_t.cwiseProduct(eigen_RV.transpose()*(eigen_RV*(dd.cwiseProduct(b))))-eigen_al;
427 func.start_alpha=eigen_al;
443 SG_WARNING(
"Max iterations (%d) reached, but convergence level (%f) is not yet below tolerance (%f)\n",
m_iter, Psi_Old-Psi_New,
m_tolerance);
449 eigen_mu=eigen_tmp+eigen_mean;
455 eigen_post_alpha=eigen_R0.transpose()*(eigen_V*eigen_al);
478 VectorXd Wd0_1=eigen_W.cwiseProduct(eigen_dg)+MatrixXd::Ones(eigen_W.rows(),1);
482 if (eigen_W.minCoeff()>0)
484 eigen_sW=eigen_W.cwiseSqrt();
488 eigen_sW=((eigen_W.array().abs()+eigen_W.array())/2).sqrt()-((eigen_W.array().abs()-eigen_W.array())/2).sqrt();
490 if (!(Wd0_1.array().abs().matrix()==Wd0_1))
498 VectorXd dd=MatrixXd::Ones(Wd0_1.rows(),1).cwiseQuotient(Wd0_1);
499 eigen_t=eigen_W.cwiseProduct(dd);
505 eigen_A=eigen_V*eigen_t.asDiagonal()*eigen_V.transpose()+MatrixXd::Identity(A.
num_rows,A.
num_rows);
508 MatrixXd R0tV=eigen_R0.transpose()*eigen_V;
511 MatrixXd B=R0tV*eigen_t.asDiagonal();
518 eigen_L=-B*R0tV.transpose();
523 MatrixXd eigen_RV=eigen_tmp*eigen_V;
528 eigen_Rvdd=eigen_RV*eigen_t.asDiagonal();
533 B=B*eigen_RV.transpose();
535 eigen_L+=B*B.transpose();
540 B=B*eigen_V.transpose();
542 FullPivLU<MatrixXd> lu(eigen_A);
543 eigen_L+=B*lu.inverse()*B.transpose();
550 eigen_g=((eigen_dg.cwiseProduct(dd)).array()+
552 ).array().pow(2).colwise().sum().transpose())/2;
568 eigen_B=eigen_R0.transpose()*eigen_V;
574 eigen_w=eigen_B*eigen_al;
584 eigen_dfhat=eigen_g.cwiseProduct(eigen_d3lp);
603 eigen_dA=2*eigen_dKui-eigen_dKuui*eigen_R0tV;
610 eigen_v=eigen_ddiagKi-eigen_dA.cwiseProduct(eigen_R0tV).colwise().sum().transpose();
622 eigen_b=eigen_dA.transpose()*(eigen_R0tV*eigen_dlp)+eigen_v.cwiseProduct(eigen_dlp);
627 result-=eigen_dfhat.dot(eigen_b-eigen_KZb);
634 REQUIRE(param,
"Param not set\n");
637 && strcmp(param->
m_name,
"log_inducing_noise")
638 && strcmp(param->
m_name,
"inducing_features")),
639 "Can't compute derivative of"
640 " the nagative log marginal likelihood wrt %s.%s parameter\n",
645 if (!strcmp(param->
m_name,
"inducing_features"))
667 if (!strcmp(param->
m_name,
"log_inducing_noise"))
714 result[0]=-eigen_g.dot(eigen_d2lp_dhyp)-eigen_lp_dhyp.sum();
728 REQUIRE(param,
"Param not set\n");
730 int64_t len=
const_cast<TParameter *
>(param)->m_datatype.get_num_elements();
792 return eigen_dfhat.dot(eigen_d-eigen_tmp);
799 REQUIRE(param,
"Param not set\n");
801 int64_t len=
const_cast<TParameter *
>(param)->m_datatype.get_num_elements();
820 REQUIRE(param,
"Param not set\n");
821 SG_WARNING(
"Derivative wrt %s cannot be computed since W (the Hessian (diagonal) matrix) is too negative\n", param->
m_name);
847 eigen_q=eigen_dfhat-eigen_q;
857 eigen_neg_v-=2*eigen_dlp.cwiseProduct(eigen_q);
867 eigen_BdK=eigen_B*eigen_neg_v.asDiagonal()+eigen_w*(eigen_al.transpose())+
868 (eigen_B*eigen_Rvdd.transpose())*eigen_Rvdd+
869 (eigen_B*eigen_dlp)*eigen_q.transpose()+(eigen_B*eigen_q)*eigen_dlp.transpose();
888 VectorXd eigen_t1=eigen_B.cwiseProduct(eigen_B).colwise().sum().adjoint();
894 eigen_b=(eigen_t1.cwiseProduct(eigen_dlp)-eigen_B.transpose()*(eigen_B*eigen_dlp))*factor;
943 MatrixXd diagonal_part=eigen_dg.asDiagonal();
945 MatrixXd prior=eigen_V.transpose()*eigen_V+diagonal_part;
948 eigen_Sigma=prior-tmp.adjoint()*eigen_L*tmp;
virtual float64_t get_derivative_related_mean(SGVector< float64_t > dmu)
virtual SGVector< float64_t > get_derivative_wrt_inducing_features(const TParameter *param)
virtual bool init(CFeatures *lhs, CFeatures *rhs)
virtual SGVector< float64_t > get_log_probability_f(const CLabels *lab, SGVector< float64_t > func) const =0
virtual SGVector< float64_t > compute_mvmZ(SGVector< float64_t > x)
static CSingleFITCLaplacianInferenceMethod * obtain_from_generic(CInferenceMethod *inference)
virtual void update_chol()
virtual void update_init()
virtual void update_parameter_hash()
SGMatrix< float64_t > m_B
SGVector< float64_t > m_ktrtr_diag
virtual SGVector< float64_t > get_derivative_wrt_likelihood_model(const TParameter *param)
SGVector< float64_t > m_alpha
The Inference Method base class.
virtual SGVector< float64_t > get_derivative_wrt_mean(const TParameter *param)
virtual SGVector< float64_t > get_posterior_mean()
virtual SGVector< float64_t > derivative_helper_when_Wneg(SGVector< float64_t > res, const TParameter *param)
The class Labels models labels, i.e. class assignments of objects.
static const float64_t INFTY
infinity
virtual SGVector< float64_t > get_second_derivative(const CLabels *lab, SGVector< float64_t > func, const TParameter *param) const
virtual int32_t get_num_labels() const =0
SGVector< float64_t > m_dlp
SGMatrix< float64_t > m_Rvdd
virtual float64_t get_derivative_related_cov(SGVector< float64_t > ddiagKi, SGMatrix< float64_t > dKuui, SGMatrix< float64_t > dKui)
virtual void update_deriv()
SGVector< float64_t > m_d3lp
SGVector< float64_t > m_al
SGMatrix< float64_t > m_kuu
virtual SGVector< float64_t > get_derivative_wrt_kernel(const TParameter *param)
virtual ELikelihoodModelType get_model_type() const
SGVector< float64_t > m_g
CSingleFITCLaplacianInferenceMethod()
virtual SGVector< float64_t > get_mean_vector(const CFeatures *features) const =0
The SingleFITCLaplace approximation inference method class for regression and binary Classification...
SGVector< float64_t > m_dfhat
float64_t get_degrees_freedom() const
virtual SGVector< float64_t > get_derivative_wrt_inference_method(const TParameter *param)
SGMatrix< float64_t > m_ktru
An abstract class of the mean function.
virtual SGVector< float64_t > get_derivative_wrt_inducing_noise(const TParameter *param)
void scale(T alpha)
Scale vector inplace.
SGMatrix< float64_t > m_inducing_features
The Fully Independent Conditional Training inference base class for Laplace and regression for 1-D la...
SGVector< float64_t > m_mu
virtual SGVector< float64_t > compute_mvmK(SGVector< float64_t > al)
virtual void update_approx_cov()
virtual float64_t get_negative_log_marginal_likelihood()
SGVector< float64_t > m_d2lp
friend class CFITCPsiLine
SGMatrix< float64_t > m_L
virtual float64_t get_derivative_related_cov(SGVector< float64_t > ddiagKi, SGMatrix< float64_t > dKuui, SGMatrix< float64_t > dKui)
SGVector< float64_t > m_sW
virtual ~CSingleFITCLaplacianInferenceMethod()
SGVector< float64_t > m_dg
virtual void compute_gradient()
virtual SGVector< float64_t > get_derivative_related_cov_diagonal()
static T sum(T *vec, int32_t len)
Return sum(vec)
virtual void update_alpha()
float64_t m_opt_tolerance
SGMatrix< float64_t > m_Sigma
virtual SGVector< float64_t > get_derivative_related_inducing_features(SGMatrix< float64_t > BdK, const TParameter *param)
Class that models a Student's-t likelihood.
virtual float64_t get_derivative_related_mean(SGVector< float64_t > dmu)
virtual SGVector< float64_t > get_parameter_derivative(const CFeatures *features, const TParameter *param, index_t index=-1)
all of classes and functions are contained in the shogun namespace
virtual CFeatures * get_inducing_features()
SGMatrix< float64_t > m_chol_R0
The class Features is the base class of all feature objects.
virtual SGVector< float64_t > get_derivative_wrt_inference_method(const TParameter *param)
static float64_t exp(float64_t x)
virtual SGMatrix< float64_t > get_parameter_gradient(const TParameter *param, index_t index=-1)
SGVector< T > clone() const
virtual const char * get_name() const
virtual void compute_gradient()
SGVector< float64_t > m_t
virtual EInferenceType get_inference_type() const
virtual SGVector< float64_t > get_log_probability_derivative_f(const CLabels *lab, SGVector< float64_t > func, index_t i) const =0
virtual SGVector< float64_t > get_third_derivative(const CLabels *lab, SGVector< float64_t > func, const TParameter *param) const
virtual SGVector< float64_t > get_derivative_wrt_inducing_noise(const TParameter *param)
virtual SGVector< float64_t > get_diagonal_vector()
float64_t m_log_ind_noise
virtual SGMatrix< float64_t > get_posterior_covariance()
SGVector< float64_t > m_W
static CStudentsTLikelihood * obtain_from_generic(CLikelihoodModel *likelihood)
SGVector< float64_t > m_w
virtual SGVector< float64_t > get_first_derivative(const CLabels *lab, SGVector< float64_t > func, const TParameter *param) const
virtual SGMatrix< float64_t > get_chol_inv(SGMatrix< float64_t > mtx)
SGMatrix< float64_t > m_V
virtual bool parameter_hash_changed()
virtual SGVector< float64_t > get_parameter_gradient_diagonal(const TParameter *param, index_t index=-1)
The Likelihood model base class.
CLikelihoodModel * m_model
virtual float64_t get_derivative_implicit_term_helper(SGVector< float64_t > d)