@@ -2155,75 +2155,59 @@ static int solve_l1r_lr(const problem *prob_col, const parameter *param, double
21552155 return newton_iter;
21562156}
21572157
2158- struct heap {
2159- enum HEAP_TYPE { MIN, MAX };
2160- int _size;
2161- HEAP_TYPE _type;
2162- feature_node* a;
2158+ static int compare_feature_node (const void *a, const void *b)
2159+ {
2160+ double a_value = (*(feature_node *)a).value ;
2161+ double b_value = (*(feature_node *)b).value ;
2162+ int a_index = (*(feature_node *)a).index ;
2163+ int b_index = (*(feature_node *)b).index ;
21632164
2164- heap (int max_size, HEAP_TYPE type)
2165- {
2166- _size = 0 ;
2167- a = new feature_node[max_size];
2168- _type = type;
2169- }
2170- ~heap ()
2171- {
2172- delete [] a;
2173- }
2174- bool cmp (const feature_node& left, const feature_node& right)
2175- {
2176- if (_type == MIN)
2177- return left.value > right.value ;
2178- else
2179- return left.value < right.value ;
2180- }
2181- int size ()
2182- {
2183- return _size;
2184- }
2185- void push (feature_node node)
2165+ if (a_value < b_value)
2166+ return -1 ;
2167+ else if (a_value == b_value)
21862168 {
2187- a[_size] = node;
2188- _size++;
2189- int i = _size-1 ;
2190- while (i)
2191- {
2192- int p = (i-1 )/2 ;
2193- if (cmp (a[p], a[i]))
2194- {
2195- swap (a[i], a[p]);
2196- i = p;
2197- }
2198- else
2199- break ;
2200- }
2169+ if (a_index < b_index)
2170+ return -1 ;
2171+ else if (a_index == b_index)
2172+ return 0 ;
22012173 }
2202- void pop ()
2203- {
2204- _size--;
2205- a[0 ] = a[_size];
2206- int i = 0 ;
2207- while (i*2 +1 < _size)
2174+ return 1 ;
2175+ }
2176+
2177+ // elements before the returned index are < pivot, while those after are >= pivot
2178+ static int partition (feature_node *nodes, int low, int high)
2179+ {
2180+ int i;
2181+ int index;
2182+
2183+ swap (nodes[low + rand ()%(high-low+1 )], nodes[high]); // select and move pivot to the end
2184+
2185+ index = low;
2186+ for (i = low; i < high; i++)
2187+ if (compare_feature_node (&nodes[i], &nodes[high]) == -1 )
22082188 {
2209- int l = i*2 +1 ;
2210- int r = i*2 +2 ;
2211- if (r < _size && cmp (a[l], a[r]))
2212- l = r;
2213- if (cmp (a[i], a[l]))
2214- {
2215- swap (a[i], a[l]);
2216- i = l;
2217- }
2218- else
2219- break ;
2189+ swap (nodes[index], nodes[i]);
2190+ index++;
22202191 }
2221- }
2222- feature_node top ()
2223- {
2224- return a[0 ];
2225- }
2226- };
2192+
2193+ swap (nodes[high], nodes[index]);
2194+ return index;
2195+ }
2196+
2197+ // rearrange nodes so that nodes[:k] contains nodes with the k smallest values.
2198+ static void quick_select_min_k (feature_node *nodes, int low, int high, int k)
2199+ {
2200+ int pivot;
2201+ if (low == high)
2202+ return ;
2203+ pivot = partition (nodes, low, high);
2204+ if (pivot == k)
2205+ return ;
2206+ else if (k-1 < pivot)
2207+ return quick_select_min_k (nodes, low, pivot-1 , k);
2208+ else
2209+ return quick_select_min_k (nodes, pivot+1 , high, k);
2210+ }
22272211
22282212// A two-level coordinate descent algorithm for
22292213// a scaled one-class SVM dual problem
@@ -2262,11 +2246,12 @@ static int solve_oneclass_svm(const problem *prob, const parameter *param, doubl
22622246 int max_iter = 1000 ;
22632247 int active_size = l;
22642248
2265- double negGmax; // max { -grad(f)_i | alpha_i < 1 }
2266- double negGmin; // min { -grad(f)_i | alpha_i > 0 }
2267-
2268- int *most_violating_i = new int [l];
2269- int *most_violating_j = new int [l];
2249+ double negGmax; // max { -grad(f)_i | i in Iup }
2250+ double negGmin; // min { -grad(f)_i | i in Ilow }
2251+ // Iup = { i | alpha_i < 1 }, Ilow = { i | alpha_i > 0 }
2252+ feature_node *max_negG_of_Iup = new feature_node[l];
2253+ feature_node *min_negG_of_Ilow = new feature_node[l];
2254+ feature_node node;
22702255
22712256 int n = (int )(nu*l); // # of alpha's at upper bound
22722257 for (i=0 ; i<n; i++)
@@ -2328,9 +2313,8 @@ static int solve_oneclass_svm(const problem *prob, const parameter *param, doubl
23282313 }
23292314
23302315 max_inner_iter = max (active_size/10 , 1 );
2331- struct heap min_heap = heap (max_inner_iter, heap::MIN);
2332- struct heap max_heap = heap (max_inner_iter, heap::MAX);
2333- struct feature_node node;
2316+ int len_Iup = 0 ;
2317+ int len_Ilow = 0 ;
23342318 for (s=0 ; s<active_size; s++)
23352319 {
23362320 i = index[s];
@@ -2339,44 +2323,28 @@ static int solve_oneclass_svm(const problem *prob, const parameter *param, doubl
23392323
23402324 if (alpha[i] < 1 )
23412325 {
2342- if (min_heap.size () < max_inner_iter)
2343- min_heap.push (node);
2344- else if (min_heap.top ().value < node.value )
2345- {
2346- min_heap.pop ();
2347- min_heap.push (node);
2348- }
2326+ max_negG_of_Iup[len_Iup] = node;
2327+ len_Iup++;
23492328 }
23502329
23512330 if (alpha[i] > 0 )
23522331 {
2353- if (max_heap.size () < max_inner_iter)
2354- max_heap.push (node);
2355- else if (max_heap.top ().value > node.value )
2356- {
2357- max_heap.pop ();
2358- max_heap.push (node);
2359- }
2332+ min_negG_of_Ilow[len_Ilow] = node;
2333+ len_Ilow++;
23602334 }
23612335 }
2362- max_inner_iter = min (min_heap.size (), max_heap.size ());
2363- while (max_heap.size () > max_inner_iter)
2364- max_heap.pop ();
2365- while (min_heap.size () > max_inner_iter)
2366- min_heap.pop ();
2336+ max_inner_iter = min (max_inner_iter, min (len_Iup, len_Ilow));
23672337
2368- for (s=max_inner_iter-1 ; s>=0 ; s--)
2369- {
2370- most_violating_i[s] = min_heap.top ().index ;
2371- most_violating_j[s] = max_heap.top ().index ;
2372- min_heap.pop ();
2373- max_heap.pop ();
2374- }
2338+ quick_select_min_k (max_negG_of_Iup, 0 , len_Iup-1 , len_Iup-max_inner_iter);
2339+ qsort (&(max_negG_of_Iup[len_Iup-max_inner_iter]), max_inner_iter, sizeof (struct feature_node ), compare_feature_node);
2340+
2341+ quick_select_min_k (min_negG_of_Ilow, 0 , len_Ilow-1 , max_inner_iter);
2342+ qsort (min_negG_of_Ilow, max_inner_iter, sizeof (struct feature_node ), compare_feature_node);
23752343
23762344 for (s=0 ; s<max_inner_iter; s++)
23772345 {
2378- i = most_violating_i[s] ;
2379- j = most_violating_j [s];
2346+ i = max_negG_of_Iup[len_Iup-s- 1 ]. index ;
2347+ j = min_negG_of_Ilow [s]. index ;
23802348
23812349 if ((alpha[i] == 0 && alpha[j] == 0 ) ||
23822350 (alpha[i] == 1 && alpha[j] == 1 ))
@@ -2484,15 +2452,14 @@ static int solve_oneclass_svm(const problem *prob, const parameter *param, doubl
24842452 *rho = sum_free/nr_free;
24852453 else
24862454 *rho = (ub + lb)/2 ;
2487-
24882455 info (" rho = %lf\n " , *rho);
24892456
24902457 delete [] QD;
24912458 delete [] G;
24922459 delete [] index;
24932460 delete [] alpha;
2494- delete [] most_violating_i ;
2495- delete [] most_violating_j ;
2461+ delete [] max_negG_of_Iup ;
2462+ delete [] min_negG_of_Ilow ;
24962463
24972464 return iter;
24982465}
@@ -3678,10 +3645,10 @@ double get_decfun_rho(const struct model *model_)
36783645
36793646void free_model_content (struct model *model_ptr)
36803647{
3681- if (model_ptr->w != NULL )
3682- free ( model_ptr->w ) ;
3683- if (model_ptr->label != NULL )
3684- free ( model_ptr->label ) ;
3648+ free (model_ptr->w );
3649+ model_ptr->w = NULL ;
3650+ free (model_ptr->label );
3651+ model_ptr->label = NULL ;
36853652}
36863653
36873654void free_and_destroy_model (struct model **model_ptr_ptr)
@@ -3691,17 +3658,18 @@ void free_and_destroy_model(struct model **model_ptr_ptr)
36913658 {
36923659 free_model_content (model_ptr);
36933660 free (model_ptr);
3661+ *model_ptr_ptr = NULL ;
36943662 }
36953663}
36963664
36973665void destroy_param (parameter* param)
36983666{
3699- if (param->weight_label != NULL )
3700- free ( param->weight_label ) ;
3701- if (param->weight != NULL )
3702- free ( param->weight ) ;
3703- if (param->init_sol != NULL )
3704- free ( param->init_sol ) ;
3667+ free (param->weight_label );
3668+ param->weight_label = NULL ;
3669+ free (param->weight );
3670+ param->weight = NULL ;
3671+ free (param->init_sol );
3672+ param->init_sol = NULL ;
37053673}
37063674
37073675const char *check_parameter (const problem *prob, const parameter *param)
0 commit comments