15 #include <shogun/lib/external/libqp.h>
48 libqp_state_T qp_exitflag={0, 0, 0, 0}, qp_exitflag_good={0, 0, 0, 0};
49 float64_t *b, *b2, *beta, *beta_good, *beta_start, *diag_H, *diag_H2;
50 float64_t R, *subgrad, *A, QPSolverTolRel, C=1.0;
51 float64_t *prevW, *wt, alpha, alpha_start, alpha_good=0.0, Fd_alpha0=0.0;
53 floatmax_t rsum, sq_norm_W, sq_norm_Wdiff, sq_norm_prevW, eps;
54 uint32_t *I, *I2, *I_start, *I_good;
60 bmrm_ll *CPList_head, *CPList_tail, *cp_ptr, *cp_ptr2, *cp_list=NULL;
62 bool *map=NULL, tuneAlpha=
true, flag=
true, alphaChanged=
false, isThereGoodSolution=
false;
98 "overflow: %u * %u > %u -- biggest possible BufSize=%u or nDim=%u\n",
128 if (H==NULL || A==NULL || b==NULL || beta==NULL || subgrad==NULL ||
129 diag_H==NULL || I==NULL || icp_stats.
ICPcounter==NULL ||
130 icp_stats.
ICPs==NULL || icp_stats.
ACPs==NULL ||
131 cp_list==NULL || prevW==NULL || wt==NULL)
145 memset( (
bool*) map,
true, BufSize);
150 if (icp_stats.
H_buff==NULL)
173 if (beta_start==NULL || beta_good==NULL || b2==NULL || diag_H2==NULL ||
174 I_start==NULL || I_good==NULL || I2==NULL || H2==NULL)
185 R = machine->
risk(subgrad, W);
208 for (uint32_t j=0; j<nDim; ++j)
210 sq_norm_Wdiff+=(W[j]-prevW[j])*(W[j]-prevW[j]);
213 ppbmrm.
Fp=R+0.5*_lambda*sq_norm_W + alpha*sq_norm_Wdiff;
218 K = (sq_norm_W == 0.0) ? 0.4 : 0.01*
CMath::sqrt(sq_norm_W);
232 SG_SDEBUG(
"%4d: tim=%.3lf, Fp=%lf, Fd=%lf, R=%lf, K=%lf\n",
233 ppbmrm.
nIter, tstop-tstart, ppbmrm.
Fp, ppbmrm.
Fd, R, K);
252 for (uint32_t i=0; i<ppbmrm.
nCP; ++i)
272 beta[ppbmrm.
nCP]=0.0;
279 isThereGoodSolution=
false;
287 alpha_start=alpha; alpha=0.0;
288 beta[ppbmrm.
nCP]=0.0;
295 for (uint32_t i=0; i<ppbmrm.
nCP; ++i)
302 b2[i]=b[i]-((2*alpha)/(_lambda+2*alpha))*rsum;
303 diag_H2[i]=diag_H[i]/(_lambda+2*alpha);
305 for (uint32_t j=0; j<ppbmrm.
nCP; ++j)
311 qp_exitflag=libqp_splx_solver(&
get_col, diag_H2, b2, &C, I2, &S, beta,
315 Fd_alpha0=-qp_exitflag.QP;
318 for (uint32_t i=0; i<nDim; ++i)
323 for (uint32_t j=0; j<ppbmrm.
nCP; ++j)
327 rsum+=A_1[i]*beta[j];
330 wt[i]=(2*alpha*prevW[i] - rsum)/(_lambda+2*alpha);
335 for (uint32_t i=0; i<nDim; ++i)
336 sq_norm_Wdiff+=(wt[i]-prevW[i])*(wt[i]-prevW[i]);
342 if (alpha!=alpha_start)
355 beta[ppbmrm.
nCP]=0.0;
360 for (uint32_t i=0; i<ppbmrm.
nCP; ++i)
367 b2[i]=b[i]-((2*alpha)/(_lambda+2*alpha))*rsum;
368 diag_H2[i]=diag_H[i]/(_lambda+2*alpha);
370 for (uint32_t j=0; j<ppbmrm.
nCP; ++j)
375 qp_exitflag=libqp_splx_solver(&
get_col, diag_H2, b2, &C, I2, &S, beta,
381 for (uint32_t i=0; i<nDim; ++i)
386 for (uint32_t j=0; j<ppbmrm.
nCP; ++j)
390 rsum+=A_1[i]*beta[j];
393 wt[i]=(2*alpha*prevW[i] - rsum)/(_lambda+2*alpha);
397 for (uint32_t i=0; i<nDim; ++i)
398 sq_norm_Wdiff+=(wt[i]-prevW[i])*(wt[i]-prevW[i]);
405 if (isThereGoodSolution)
410 qp_exitflag=qp_exitflag_good;
435 qp_exitflag_good=qp_exitflag;
436 isThereGoodSolution=
true;
465 for (uint32_t i=0; i<ppbmrm.
nCP; ++i)
472 b2[i]=b[i]-((2*alpha)/(_lambda+2*alpha))*rsum;
473 diag_H2[i]=diag_H[i]/(_lambda+2*alpha);
475 for (uint32_t j=0; j<ppbmrm.
nCP; ++j)
480 qp_exitflag=libqp_splx_solver(&
get_col, diag_H2, b2, &C, I2, &S, beta,
491 for (uint32_t aaa=0; aaa<ppbmrm.
nCP; ++aaa)
493 if (beta[aaa]>epsilon)
505 for (uint32_t i=0; i<nDim; ++i)
510 for (uint32_t j=0; j<ppbmrm.
nCP; ++j)
514 rsum+=A_1[i]*beta[j];
517 W[i]=(2*alpha*prevW[i]-rsum)/(_lambda+2*alpha);
521 R = machine->
risk(subgrad, W);
530 for (uint32_t j=0; j<nDim; ++j)
532 sq_norm_Wdiff+=(W[j]-prevW[j])*(W[j]-prevW[j]);
536 ppbmrm.
Fp=R+0.5*_lambda*sq_norm_W + alpha*sq_norm_Wdiff;
537 ppbmrm.
Fd=-qp_exitflag.QP+((alpha*_lambda)/(_lambda + 2*alpha))*sq_norm_prevW;
542 eps=1.0-(ppbmrm.
Fd/ppbmrm.
Fp);
543 gamma=(lastFp*(1-eps)-Fd_alpha0)/(Tmax*(1-eps));
546 if ((lastFp-ppbmrm.
Fp) <= gamma)
561 if (ppbmrm.
Fp-ppbmrm.
Fd<=TolAbs)
565 if (ppbmrm.
nCP>=BufSize)
573 for (uint32_t i=0; i<nDim; ++i)
575 sq_norm_Wdiff+=(W[i]-prevW[i])*(W[i]-prevW[i]);
587 SG_SDEBUG(
"%4d: tim=%.3lf, Fp=%lf, Fd=%lf, (Fp-Fd)=%lf, (Fp-Fd)/Fp=%lf, R=%lf, nCP=%d, nzA=%d, wdist=%lf, alpha=%lf, qp_cnt=%d, gamma=%lf, tuneAlpha=%d\n",
588 ppbmrm.
nIter, tstop-tstart, ppbmrm.
Fp, ppbmrm.
Fd, ppbmrm.
Fp-ppbmrm.
Fd,
589 (ppbmrm.
Fp-ppbmrm.
Fd)/ppbmrm.
Fp, R, ppbmrm.
nCP, ppbmrm.
nzA, wdist, alpha,
590 qp_cnt, gamma, tuneAlpha);
593 if (ppbmrm.
nCP>=BufSize)
606 clean_icp(&icp_stats, ppbmrm, &CPList_head, &CPList_tail, H, diag_H, beta, map, cleanAfter, b, I);
610 if (ppbmrm.
nCP+1 >= BufSize)
#define LIBBMRM_CALLOC(x, y)
Class Time that implements a stopwatch based on either cpu time or wall clock time.
static const double * get_col(uint32_t j)
Class DualLibQPBMSOSVM that uses Bundle Methods for Regularized Risk Minimization algorithms for stru...
float64_t * get_cutting_plane(bmrm_ll *ptr)
CSOSVMHelper * get_helper() const
SGVector< float64_t > hist_wdist
SGVector< float64_t > hist_Fd
static float64_t primal_objective(SGVector< float64_t > w, CStructuredModel *model, float64_t lbda)
virtual int32_t get_dim() const =0
uint32_t find_free_idx(bool *map, uint32_t size)
static const float64_t epsilon
float64_t cur_time_diff(bool verbose=false)
static const uint32_t QPSolverMaxIter
BmrmStatistics svm_ppbm_solver(CDualLibQPBMSOSVM *machine, float64_t *W, float64_t TolRel, float64_t TolAbs, float64_t _lambda, uint32_t _BufSize, bool cleanICP, uint32_t cleanAfter, float64_t K, uint32_t Tmax, bool verbose)
class CSOSVMHelper contains helper functions to compute primal objectives, dual objectives, average training losses, duality gaps etc. These values will be recorded to check convergence. This class is inspired by the matlab implementation of the block coordinate Frank-Wolfe SOSVM solver [1].
virtual float64_t risk(float64_t *subgrad, float64_t *W, TMultipleCPinfo *info=0, EStructRiskType rtype=N_SLACK_MARGIN_RESCALING)
SGVector< float64_t > hist_Fp
static float64_t dot(const bool *v1, const bool *v2, int32_t n)
Compute dot product between v1 and v2 (blas optimized)
#define LIBBMRM_MEMCPY(x, y, z)
static float64_t average_loss(SGVector< float64_t > w, CStructuredModel *model, bool is_ub=false)
Class CStructuredModel that represents the application specific model and contains most of the applic...
#define LIBBMRM_INDEX(ROW, COL, NUM_ROWS)
all of classes and functions are contained in the shogun namespace
virtual void add_debug_info(float64_t primal, float64_t eff_pass, float64_t train_error, float64_t dual=-1, float64_t dgap=-1)
void add_cutting_plane(bmrm_ll **tail, bool *map, float64_t *A, uint32_t free_idx, float64_t *cp_data, uint32_t dim)
CStructuredModel * get_model() const
void resize_vector(int32_t n)
Matrix::Scalar max(Matrix m)
static float32_t sqrt(float32_t x)
void clean_icp(ICP_stats *icp_stats, BmrmStatistics &bmrm, bmrm_ll **head, bmrm_ll **tail, float64_t *&Hmat, float64_t *&diag_H, float64_t *&beta, bool *&map, uint32_t cleanAfter, float64_t *&b, uint32_t *&I, uint32_t cp_models)