15 #include <shogun/lib/external/libqp.h>
29 return (&HMatrix[maxCPs*i]);
71 float64_t d1 = g_lo+g_hi - 3*(f_lo-f_hi)/(a_lo-a_hi);
73 float64_t a_j = a_hi -(a_hi-a_lo)*(g_hi+d2-d1)/(g_hi-g_lo+2*d2);
77 if ((a_j < a_lo) || (a_j > a_hi))
79 a_j = 0.5*(a_lo+a_hi);
84 if ((a_j > a_lo) || (a_j < a_hi))
86 a_j = 0.5*(a_lo+a_hi);
90 cur_solution.
add(cur_solution.
vector, 1.0,
91 initial_solution.
vector, a_j,
104 (cur_fval > (initial_fval+wolfe_c1*a_j*init_lgrad))
118 if (
CMath::abs(cur_lgrad) < -wolfe_c2*init_lgrad)
121 ls_res.
fval = cur_fval;
122 ls_res.
reg = cur_reg;
129 if (cur_lgrad*(a_hi - a_lo) >= 0)
148 ls_res.
fval = cur_fval;
149 ls_res.
reg = cur_reg;
193 std::vector<line_search_res> ret;
208 initial_step.
fval = cur_fval;
209 initial_step.
reg = cur_reg;
210 initial_step.
gradient = cur_subgrad;
212 ret.push_back(initial_step);
220 (cur_fval > initial_val+wolfe_c1*cur_a*initial_lgrad)
222 (cur_fval >= prev_fval && iter > 0)
226 zoom(machine, lambda, prev_a, cur_a, initial_val,
227 initial_solution, search_dir, wolfe_c1, wolfe_c2,
228 initial_lgrad, prev_fval, prev_lgrad, cur_fval, cur_lgrad)
233 if (
CMath::abs(cur_lgrad) <= -wolfe_c2*initial_lgrad)
237 ls_res.
fval = cur_fval;
238 ls_res.
reg = cur_reg;
241 ret.push_back(ls_res);
248 zoom(machine, lambda, cur_a, prev_a, initial_val,
249 initial_solution, search_dir, wolfe_c1, wolfe_c2,
250 initial_lgrad, cur_fval, cur_lgrad, prev_fval, prev_lgrad)
255 if ((
CMath::abs(cur_a - amax) <= 0.01*amax) || (iter >= max_iter))
259 ls_res.
fval = cur_fval;
260 ls_res.
reg = cur_reg;
263 ret.push_back(ls_res);
268 prev_fval = cur_fval;
269 prev_lgrad = cur_lgrad;
271 cur_a = (cur_a + amax)*0.5;
287 for (uint32_t i=0; i < ncbm.
nCP; ++i)
324 libqp_state_T qp_exitflag={0, 0, 0, 0};
327 int32_t w_dim = model->
get_dim();
384 || icp_stats.
ACPs == NULL || icp_stats.
H_buff == NULL
411 best_risk = cur_risk;
416 bmrm_ll *CPList_head, *CPList_tail, *cp_ptr, *cp_list=NULL;
433 update_H(ncbm, CPList_head, CPList_tail, H, diag_H, _lambda, maxCPs, w_dim);
436 SG_SPRINT(
"%4d: tim=%.3lf, Fp=%lf, Fd=%lf, R=%lf\n",
437 ncbm.
nIter, tstop-tstart, ncbm.
Fp, ncbm.
Fd, cur_risk);
457 ncbm.
Fd = -qp_exitflag.QP;
465 for (uint32_t i=0; i < ncbm.
nCP; ++i)
482 clean_icp(&icp_stats, ncbm, &CPList_head, &CPList_tail,
492 for (uint32_t i=0; i < ncbm.
nCP; ++i)
499 bool calc_gap =
false;
505 for (uint32_t i=0; i < ncbm.
nCP; ++i)
508 cp_ptr = cp_ptr->
next;
517 SG_SPRINT(
"%4d: primal:%f dual:%f QP_gap:%f\n", ncbm.
nIter, PO, ncbm.
Fd, QP_gap)
524 if ((best_Fp - ncbm.
Fd) <= TolAbs)
527 if (ncbm.
nCP >= maxCPs)
531 if (ncbm.
nCP+3 >= maxCPs)
538 SG_SPRINT(
"%4d: tim=%.3lf, Fp=%lf, Fd=%lf, (Fp-Fd)=%lf, (Fp-Fd)/Fp=%lf, R=%lf, nCP=%d, nzA=%d, QPexitflag=%d, best_fp=%f, gap=%f\n",
540 (ncbm.
Fp-ncbm.
Fd)/ncbm.
Fp, cur_risk, ncbm.
nCP, ncbm.
nzA, qp_exitflag.exitflag, best_Fp, (best_Fp-ncbm.
Fd)/best_Fp);
545 std::vector<line_search_res> wbest_candidates;
555 update_H(ncbm, CPList_head, CPList_tail, H, diag_H, _lambda, maxCPs, w_dim);
563 wbest_candidates.push_back(ls);
574 uint32_t cp_min_approx = 0;
575 if (cp_min_approx || (ncbm.
nIter == 1))
587 std::vector<line_search_res> ls_res
590 if (ls_res[0].fval != ls_res[1].fval)
592 ls_res[0].gradient.vec1_plus_scalar_times_vec2(ls_res[0].gradient.vector, -_lambda, ls_res[0].solution.vector, w_dim);
598 =
CMath::dot(ls_res[0].solution.vector, ls_res[0].gradient, w_dim)
599 - (ls_res[0].fval - ls_res[0].reg);
601 update_H(ncbm, CPList_head, CPList_tail, H, diag_H, _lambda, maxCPs, w_dim);
603 wbest_candidates.push_back(ls_res[0]);
606 ls_res[1].gradient.vec1_plus_scalar_times_vec2(ls_res[1].gradient.vector, -_lambda, ls_res[1].solution.vector, w_dim);
609 find_free_idx(map, maxCPs), ls_res[1].gradient.vector, w_dim);
612 =
CMath::dot(ls_res[1].solution.vector, ls_res[1].gradient.vector, w_dim)
613 - (ls_res[1].fval - ls_res[1].reg);
615 update_H(ncbm, CPList_head, CPList_tail, H, diag_H, _lambda, maxCPs, w_dim);
617 wbest_candidates.push_back(ls_res[1]);
619 if ((best_Fp <= ls_res[1].fval) && (astart != 1))
629 update_H(ncbm, CPList_head, CPList_tail, H, diag_H, _lambda, maxCPs, w_dim);
638 wbest_candidates.push_back(ls);
641 astar = ls_res[1].a * norm_dir;
644 SG_SPRINT(
"\t\tline search time: %.5lf\n", tstop-tstart)
649 SG_SPRINT(
"\t searching for the best Fp:\n")
650 for (
size_t i = 0; i < wbest_candidates.size(); i++)
653 SG_SPRINT(
"\t\t %d fcurrent: %.16lf\n", i, wbest_candidates[i].fval)
655 if (wbest_candidates[i].fval < best_Fp)
657 best_Fp = wbest_candidates[i].fval;
658 best_risk = wbest_candidates[i].fval - wbest_candidates[i].reg;
659 memcpy(best_w, wbest_candidates[i].solution.
vector,
sizeof(
float64_t)*w_dim);
660 memcpy(best_subgrad.
vector, wbest_candidates[i].gradient.vector,
sizeof(
float64_t)*w_dim);
671 index_t cp_idx = ncbm.
nCP-(wbest_candidates.size()-i);
676 wbest_candidates[i].gradient.vector, w_dim)
677 + (-1.0*bias[cp_idx]);
678 if (score > best_risk)
683 wbest_candidates[i].gradient.vector, w_dim);
686 = best_Fp - wbest_candidates[i].reg
687 -
CMath::dot(wbest_candidates[i].solution.vector,
688 wbest_candidates[i].gradient.vector, w_dim);
691 SG_SPRINT(
"CONFLICT Rbest=%.6lg score=%g L=%.6lg U=%.6lg\n", best_risk, score, L, U)
695 SG_SPRINT(
"%.6lf < %.6lf => changing bias[%d]=%g\n", L, U, cp_idx, L)
700 wbest_candidates[i].gradient.
zero();
703 cp_ptr = CPList_tail;
704 for (
size_t j = wbest_candidates.size()-1; i < j; --j)
706 cp_ptr = cp_ptr->
prev;
714 cp_ptr = CPList_head;
715 for (uint32_t j = 0; j < ncbm.
nCP-1; ++j)
718 cp_ptr = cp_ptr->
next;
720 =
CMath::dot(a, wbest_candidates[i].gradient.vector, w_dim);
728 =
CMath::dot(wbest_candidates[i].gradient.vector,
729 wbest_candidates[i].gradient.vector, w_dim);
733 = best_Fp - wbest_candidates[i].reg
734 -
CMath::dot(wbest_candidates[i].solution.vector,
735 wbest_candidates[i].gradient.vector, w_dim);
738 SG_SPRINT(
"solved by changing nCP=%d bias:%g (%g)\n", cp_idx, bias[cp_idx], L)
#define LIBBMRM_CALLOC(x, y)
static T twonorm(const T *x, int32_t len)
|| x ||_2
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)
static const float64_t INFTY
infinity
void update_H(BmrmStatistics &ncbm, bmrm_ll *head, bmrm_ll *tail, SGMatrix< float64_t > &H, SGVector< float64_t > &diag_H, float64_t lambda, uint32_t maxCP, int32_t w_dim)
virtual int32_t get_dim() const =0
uint32_t find_free_idx(bool *map, uint32_t size)
static line_search_res zoom(CDualLibQPBMSOSVM *machine, float64_t lambda, float64_t a_lo, float64_t a_hi, float64_t initial_fval, SGVector< float64_t > &initial_solution, SGVector< float64_t > &search_dir, float64_t wolfe_c1, float64_t wolfe_c2, float64_t init_lgrad, float64_t f_lo, float64_t g_lo, float64_t f_hi, float64_t g_hi)
SGVector< float64_t > solution
static const float64_t epsilon
float64_t cur_time_diff(bool verbose=false)
static const uint32_t QPSolverMaxIter
static float64_t * HMatrix
virtual float64_t risk(float64_t *subgrad, float64_t *W, TMultipleCPinfo *info=0, EStructRiskType rtype=N_SLACK_MARGIN_RESCALING)
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 void vec1_plus_scalar_times_vec2(T *vec1, const T scalar, const T *vec2, int32_t n)
x=x+alpha*y
std::vector< line_search_res > line_search_with_strong_wolfe(CDualLibQPBMSOSVM *machine, float64_t lambda, float64_t initial_val, SGVector< float64_t > &initial_solution, SGVector< float64_t > &initial_grad, SGVector< float64_t > &search_dir, float64_t astart, float64_t amax=1.1, float64_t wolfe_c1=1E-4, float64_t wolfe_c2=0.9, float64_t max_iter=5)
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
#define IGNORE_IN_CLASSLIST
void add_cutting_plane(bmrm_ll **tail, bool *map, float64_t *A, uint32_t free_idx, float64_t *cp_data, uint32_t dim)
BmrmStatistics svm_ncbm_solver(CDualLibQPBMSOSVM *machine, float64_t *w, float64_t TolRel, float64_t TolAbs, float64_t _lambda, uint32_t _BufSize, bool cleanICP, uint32_t cleanAfter, bool is_convex, bool line_search, bool verbose)
CStructuredModel * get_model() const
SGVector< float64_t > gradient
void resize_vector(int32_t n)
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)
void set_const(T const_elem)
void add(const SGVector< T > x)