numo-liblinear 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbd4a8fc87f4ae430183e396e9977337f31b0f3abe565045f7216cd49c30857d
4
- data.tar.gz: 03b97573731e979cda4d3e4d71b6647a6e16b3133fb9227be366292b80135986
3
+ metadata.gz: e365bea9ec3f7879a2eb5ca59356a5687b5f9991d850838e1667f3eff4177727
4
+ data.tar.gz: e6943a95893d8ecbe8e7d1b690829e20c20820148f120ed3f6c6e0c5892043ad
5
5
  SHA512:
6
- metadata.gz: 139cacb7349ebf5bee31b2292aa1de97eefbdc565affd44390359bf25a91e806d402c7d4104015fd1d6eba9b030b9fda5a7307f00923eaf259e90737559f1391
7
- data.tar.gz: cc50ab17ba43f8d59f83c97daa50d0da5750473fd0b65913b51223b253157b058464b17c7b499e240496c2065eb2f7ef12cb161575bfbce53eb2ceb117967b22
6
+ metadata.gz: 4ec40f71737aa4bbea21726b7c38c2f66c1c8e98967c4098b6bb910bf54010becb48218fd1bee441a2d8fe5290d1a7114ecf06426ef2826c7b473186e757185a
7
+ data.tar.gz: 133e1114abeccd511a38c785afeac8122d12cfa00e082e7384df067b13cec42050740b8d1f9a7669cadd9934985d7786f8bc7d13c6a56342a40b440474cb57d9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ # 2.3.0
2
+ - Update bundled LIBLINEAR to 2.46
3
+
1
4
  # 2.2.1
2
5
  - Fix build failure with Xcode 14 and Ruby 3.1.x.
3
6
 
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2019-2022 Atsushi Tatsuma
1
+ Copyright (c) 2019-2023 Atsushi Tatsuma
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) 2019-2022 Atsushi Tatsuma
2
+ * Copyright (c) 2019-2023 Atsushi Tatsuma
3
3
  * All rights reserved.
4
4
  *
5
5
  * Redistribution and use in source and binary forms, with or without
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) 2019-2022 Atsushi Tatsuma
2
+ * Copyright (c) 2019-2023 Atsushi Tatsuma
3
3
  * All rights reserved.
4
4
  *
5
5
  * Redistribution and use in source and binary forms, with or without
@@ -1,5 +1,5 @@
1
1
 
2
- Copyright (c) 2007-2022 The LIBLINEAR Project.
2
+ Copyright (c) 2007-2023 The LIBLINEAR Project.
3
3
  All rights reserved.
4
4
 
5
5
  Redistribution and use in source and binary forms, with or without
@@ -2155,75 +2155,59 @@ static int solve_l1r_lr(const problem *prob_col, const parameter *param, double
2155
2155
  return newton_iter;
2156
2156
  }
2157
2157
 
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;
2163
2164
 
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)
2186
2168
  {
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;
2201
2173
  }
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)
2208
2188
  {
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++;
2220
2191
  }
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
+ }
2227
2211
 
2228
2212
  // A two-level coordinate descent algorithm for
2229
2213
  // a scaled one-class SVM dual problem
@@ -2262,11 +2246,12 @@ static int solve_oneclass_svm(const problem *prob, const parameter *param, doubl
2262
2246
  int max_iter = 1000;
2263
2247
  int active_size = l;
2264
2248
 
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;
2270
2255
 
2271
2256
  int n = (int)(nu*l); // # of alpha's at upper bound
2272
2257
  for(i=0; i<n; i++)
@@ -2328,9 +2313,8 @@ static int solve_oneclass_svm(const problem *prob, const parameter *param, doubl
2328
2313
  }
2329
2314
 
2330
2315
  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;
2334
2318
  for(s=0; s<active_size; s++)
2335
2319
  {
2336
2320
  i = index[s];
@@ -2339,44 +2323,28 @@ static int solve_oneclass_svm(const problem *prob, const parameter *param, doubl
2339
2323
 
2340
2324
  if (alpha[i] < 1)
2341
2325
  {
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++;
2349
2328
  }
2350
2329
 
2351
2330
  if (alpha[i] > 0)
2352
2331
  {
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++;
2360
2334
  }
2361
2335
  }
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));
2367
2337
 
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);
2375
2343
 
2376
2344
  for (s=0; s<max_inner_iter; s++)
2377
2345
  {
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;
2380
2348
 
2381
2349
  if ((alpha[i] == 0 && alpha[j] == 0) ||
2382
2350
  (alpha[i] == 1 && alpha[j] == 1))
@@ -2484,15 +2452,14 @@ static int solve_oneclass_svm(const problem *prob, const parameter *param, doubl
2484
2452
  *rho = sum_free/nr_free;
2485
2453
  else
2486
2454
  *rho = (ub + lb)/2;
2487
-
2488
2455
  info("rho = %lf\n", *rho);
2489
2456
 
2490
2457
  delete [] QD;
2491
2458
  delete [] G;
2492
2459
  delete [] index;
2493
2460
  delete [] alpha;
2494
- delete [] most_violating_i;
2495
- delete [] most_violating_j;
2461
+ delete [] max_negG_of_Iup;
2462
+ delete [] min_negG_of_Ilow;
2496
2463
 
2497
2464
  return iter;
2498
2465
  }
@@ -3678,10 +3645,10 @@ double get_decfun_rho(const struct model *model_)
3678
3645
 
3679
3646
  void free_model_content(struct model *model_ptr)
3680
3647
  {
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;
3685
3652
  }
3686
3653
 
3687
3654
  void free_and_destroy_model(struct model **model_ptr_ptr)
@@ -3691,17 +3658,18 @@ void free_and_destroy_model(struct model **model_ptr_ptr)
3691
3658
  {
3692
3659
  free_model_content(model_ptr);
3693
3660
  free(model_ptr);
3661
+ *model_ptr_ptr = NULL;
3694
3662
  }
3695
3663
  }
3696
3664
 
3697
3665
  void destroy_param(parameter* param)
3698
3666
  {
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;
3705
3673
  }
3706
3674
 
3707
3675
  const char *check_parameter(const problem *prob, const parameter *param)
@@ -1,7 +1,7 @@
1
1
  #ifndef _LIBLINEAR_H
2
2
  #define _LIBLINEAR_H
3
3
 
4
- #define LIBLINEAR_VERSION 245
4
+ #define LIBLINEAR_VERSION 246
5
5
 
6
6
  #ifdef __cplusplus
7
7
  extern "C" {
@@ -3,6 +3,6 @@
3
3
  module Numo
4
4
  module Liblinear
5
5
  # The version of Numo::Liblienar you are using.
6
- VERSION = '2.2.1'
6
+ VERSION = '2.3.0'
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: numo-liblinear
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-27 00:00:00.000000000 Z
11
+ date: 2023-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numo-narray