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 (