diff --git a/dlib/optimization/optimization_oca.h b/dlib/optimization/optimization_oca.h index a3ae248a6a1f9d82c81a300ed7372078878da729..98a9aab4c967f6372ca42f9b6725670fca342eb1 100644 --- a/dlib/optimization/optimization_oca.h +++ b/dlib/optimization/optimization_oca.h @@ -111,7 +111,8 @@ namespace dlib typename matrix_type::type operator() ( const oca_problem<matrix_type>& problem, matrix_type& w, - unsigned long num_nonnegative = 0 + unsigned long num_nonnegative = 0, + unsigned long force_weight_to_1 = std::numeric_limits<unsigned long>::max() ) const { const unsigned long num_dims = problem.get_num_dimensions(); @@ -176,7 +177,23 @@ namespace dlib // add the next cutting plane scalar_type cur_risk; + if (force_weight_to_1 < (unsigned long)w.size()) + w(force_weight_to_1) = 1; + problem.get_risk(w, cur_risk, new_plane); + + if (force_weight_to_1 < (unsigned long)w.size()) + { + // We basically arrange for the w(force_weight_to_1) element and all + // subsequent elements of w to not be involved in the optimization at + // all. An easy way to do this is to just make sure the elements of w + // corresponding elements in the subgradient are always set to zero + // while we run the cutting plane algorithm. The only time + // w(force_weight_to_1) is 1 is when we pass it to the oca_problem. + set_rowm(w, range(force_weight_to_1, w.size()-1)) = 0; + set_rowm(new_plane, range(force_weight_to_1, new_plane.size()-1)) = 0; + } + if (planes.size() != 0) planes = join_rows(planes, new_plane); else @@ -263,6 +280,9 @@ namespace dlib ++counter; } + if (force_weight_to_1 < (unsigned long)w.size()) + w(force_weight_to_1) = 1; + return cur_obj; } diff --git a/dlib/optimization/optimization_oca_abstract.h b/dlib/optimization/optimization_oca_abstract.h index ad3e1d0ddf16e051620e5af46cd8b4a7fea591ae..31ae5fa2b558cb1a1b03a00d804611d019f4d26a 100644 --- a/dlib/optimization/optimization_oca_abstract.h +++ b/dlib/optimization/optimization_oca_abstract.h @@ -154,7 +154,8 @@ namespace dlib typename matrix_type::type operator() ( const oca_problem<matrix_type>& problem, matrix_type& w, - unsigned long num_nonnegative = 0 + unsigned long num_nonnegative = 0, + unsigned long force_weight_to_1 = std::numeric_limits<unsigned long>::max() ) const; /*! requires @@ -171,6 +172,15 @@ namespace dlib non-negative. This includes the copies of w passed to get_risk() in the form of the current_solution vector as well as the final output of this function. + - if (force_weight_to_1 < problem.get_num_dimensions()) then + - The optimizer enforces the following constraints: + - #w(force_weight_to_1) == 1 + - for all i > force_weight_to_1: + - #w(i) == 0 + - That is, the element in the weight vector at the index indicated + by force_weight_to_1 will have a value of 1 upon completion of + this function, while all subsequent elements of w will have + values of 0. !*/ void set_subproblem_epsilon (