47 #include <shogun/lib/external/brent.h>
50 using namespace Eigen;
55 #ifndef DOXYGEN_SHOULD_SKIP_THIS
58 class CMultiPsiLine :
public func_base
72 virtual double operator() (
double x)
80 (*alpha)=start_alpha+x*dalpha;
85 eigen_f.block(bl*n,0,n,1)=K*alpha->block(bl*n,0,n,1)*
CMath::exp(log_scale*2.0);
86 result+=alpha->block(bl*n,0,n,1).dot(eigen_f.block(bl*n,0,n,1))/2.0;
87 eigen_f.block(bl*n,0,n,1)+=eigen_m;
113 void CMultiLaplaceInferenceMethod::init()
139 "Labels must be type of CMulticlassLabels\n");
141 "likelihood model should support multi-classification\n");
177 SG_SERROR(
"Provided inference is not of type CMultiLaplaceInferenceMethod!\n")
201 eigen_Sigma.block(bl*n,bl*n,n,n)=(MatrixXd::Identity(n,n)-eigen_U.block(bl*n,0,n,n))*(eigen_K*
CMath::exp(
m_log_scale*2.0));
203 MatrixXd eigen_V=eigen_M.triangularView<Upper>().adjoint().solve(eigen_U.transpose());
204 eigen_Sigma+=eigen_V.transpose()*eigen_V;
221 VectorXd max_coeff=eigen_mu_matrix.rowwise().maxCoeff();
222 eigen_dpi_matrix=eigen_mu_matrix.array().colwise()-max_coeff.array();
223 VectorXd log_sum_exp=((eigen_dpi_matrix.array().exp()).rowwise().sum()).array().log();
224 eigen_dpi_matrix=(eigen_dpi_matrix.array().colwise()-log_sum_exp.array()).exp();
243 VectorXd eigen_mean=eigen_mean_bl.replicate(C,1);
275 Psi_New=alpha.dot(eigen_mu)/2.0;
277 eigen_mu+=eigen_mean;
282 if (Psi_Def < Psi_New)
316 VectorXd eigen_sD=eigen_dpi.block(bl*n,0,n,1).cwiseSqrt();
317 LLT<MatrixXd> chol_tmp((eigen_sD*eigen_sD.transpose()).cwiseProduct(eigen_ktrtr*
CMath::exp(
m_log_scale*2.0))+
319 MatrixXd eigen_L_tmp=chol_tmp.matrixU();
320 MatrixXd eigen_E_bl=eigen_L_tmp.triangularView<Upper>().adjoint().solve(
MatrixXd(eigen_sD.asDiagonal()));
321 eigen_E_bl=eigen_E_bl.transpose()*eigen_E_bl;
322 eigen_E.block(0,bl*n,n,n)=eigen_E_bl;
327 m_nlz+=eigen_L_tmp.diagonal().array().log().sum();
330 LLT<MatrixXd> chol_tmp(eigen_M);
331 eigen_M = chol_tmp.matrixU();
332 m_nlz+=eigen_M.diagonal().array().log().sum();
334 VectorXd eigen_b=eigen_dlp;
336 tmp1=eigen_dpi.array()*(eigen_mu-eigen_mean).array();
338 VectorXd tmp2=m_tmp.array().rowwise().sum();
341 eigen_b.block(bl*n,0,n,1)+=eigen_dpi.block(bl*n,0,n,1).cwiseProduct(eigen_mu.block(bl*n,0,n,1)-eigen_mean_bl-tmp2);
345 eigen_c.block(bl*n,0,n,1)=eigen_E.block(0,bl*n,n,n)*(eigen_ktrtr*
CMath::exp(
m_log_scale*2.0)*eigen_b.block(bl*n,0,n,1));
349 VectorXd tmp3=c_tmp.array().rowwise().sum();
350 VectorXd tmp4=eigen_M.triangularView<Upper>().adjoint().solve(tmp3);
352 VectorXd &eigen_dalpha=eigen_b;
353 eigen_dalpha+=eigen_E.transpose()*(eigen_M.triangularView<Upper>().solve(tmp4))-eigen_c-eigen_alpha;
360 func.dalpha=eigen_dalpha;
361 func.start_alpha=eigen_alpha;
362 func.alpha=&eigen_alpha;
376 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);
388 eigen_U=eigen_M.triangularView<Upper>().adjoint().solve(eigen_E);
404 result+=((eigen_E.block(0,bl*n,n,n)-eigen_U.block(0,bl*n,n,n).transpose()*eigen_U.block(0,bl*n,n,n)).array()
405 *eigen_dK.array()).sum();
406 result-=(eigen_dK*eigen_alpha.block(bl*n,0,n,1)).
dot(eigen_alpha.block(bl*n,0,n,1));
415 REQUIRE(!strcmp(param->
m_name,
"log_scale"),
"Can't compute derivative of "
416 "the nagative log marginal likelihood wrt %s.%s parameter\n",
437 REQUIRE(param,
"Param not set\n");
439 int64_t len=
const_cast<TParameter *
>(param)->m_datatype.get_num_elements();
467 REQUIRE(param,
"Param not set\n");
469 int64_t len=
const_cast<TParameter *
>(param)->m_datatype.get_num_elements();
486 result[i]-=eigen_alpha.block(bl*n,0,n,1).dot(eigen_dmu);
502 VectorXd eigen_mean=eigen_mean_bl.replicate(C,1);
505 eigen_res=eigen_mu-eigen_mean;
virtual SGVector< float64_t > get_log_probability_f(const CLabels *lab, SGVector< float64_t > func) const =0
virtual ~CMultiLaplaceInferenceMethod()
virtual bool supports_multiclass() const
virtual float64_t get_derivative_helper(SGMatrix< float64_t > dK)
virtual ELabelType get_label_type() const =0
virtual void update_approx_cov()
SGVector< float64_t > m_mu
Vector::Scalar dot(Vector a, Vector b)
The class Labels models labels, i.e. class assignments of objects.
static const float64_t INFTY
infinity
virtual EInferenceType get_inference_type() const
virtual int32_t get_num_labels() const =0
The Laplace approximation inference method class for multi classification.
multi-class labels 0,1,...
virtual const char * get_name() const
virtual SGVector< float64_t > get_derivative_wrt_likelihood_model(const TParameter *param)
virtual SGVector< float64_t > get_diagonal_vector()
virtual SGVector< float64_t > get_mean_vector(const CFeatures *features) const =0
virtual SGVector< float64_t > get_posterior_mean()
SGMatrix< float64_t > m_E
An abstract class of the mean function.
virtual void check_members() const
SGMatrix< float64_t > m_ktrtr
Multiclass Labels for multi-class classification.
SGMatrix< float64_t > m_U
virtual void get_dpi_helper()
virtual SGVector< float64_t > get_derivative_wrt_inference_method(const TParameter *param)
SGVector< float64_t > m_dlp
static T sum(T *vec, int32_t len)
Return sum(vec)
SGMatrix< float64_t > m_L
Matrix< float64_t,-1,-1, 0,-1,-1 > MatrixXd
virtual void update_chol()
float64_t m_opt_tolerance
CMultiLaplaceInferenceMethod()
virtual SGVector< float64_t > get_derivative_wrt_mean(const TParameter *param)
virtual float64_t get_negative_log_marginal_likelihood()
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
The Laplace approximation inference method base class.
virtual void update_alpha()
The Inference Method base class.
SGMatrix< float64_t > m_Sigma
virtual void compute_gradient()
The class Features is the base class of all feature objects.
static float64_t exp(float64_t x)
virtual SGMatrix< float64_t > get_parameter_gradient(const TParameter *param, index_t index=-1)
virtual SGVector< float64_t > get_log_probability_derivative_f(const CLabels *lab, SGVector< float64_t > func, index_t i) const =0
SGVector< float64_t > m_W
static CMultiLaplaceInferenceMethod * obtain_from_generic(CInference *inference)
virtual void update_deriv()
virtual SGVector< float64_t > get_derivative_wrt_kernel(const TParameter *param)
CLikelihoodModel * m_model
virtual bool parameter_hash_changed()
The Likelihood model base class.
SGVector< float64_t > m_alpha
virtual void check_members() const