opener-opinion-detector-basic 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/ext/hack/Rakefile +0 -2
  4. data/lib/opener/opinion_detector_basic/version.rb +1 -1
  5. data/opener-opinion-detector-basic.gemspec +0 -1
  6. data/task/compile.rake +1 -1
  7. data/task/requirements.rake +0 -1
  8. metadata +2 -142
  9. data/core/vendor/src/crfsuite/AUTHORS +0 -1
  10. data/core/vendor/src/crfsuite/COPYING +0 -27
  11. data/core/vendor/src/crfsuite/ChangeLog +0 -103
  12. data/core/vendor/src/crfsuite/INSTALL +0 -236
  13. data/core/vendor/src/crfsuite/Makefile.am +0 -19
  14. data/core/vendor/src/crfsuite/Makefile.in +0 -783
  15. data/core/vendor/src/crfsuite/README +0 -183
  16. data/core/vendor/src/crfsuite/aclocal.m4 +0 -9018
  17. data/core/vendor/src/crfsuite/autogen.sh +0 -38
  18. data/core/vendor/src/crfsuite/compile +0 -143
  19. data/core/vendor/src/crfsuite/config.guess +0 -1502
  20. data/core/vendor/src/crfsuite/config.h.in +0 -198
  21. data/core/vendor/src/crfsuite/config.sub +0 -1714
  22. data/core/vendor/src/crfsuite/configure +0 -14273
  23. data/core/vendor/src/crfsuite/configure.in +0 -149
  24. data/core/vendor/src/crfsuite/crfsuite.sln +0 -42
  25. data/core/vendor/src/crfsuite/depcomp +0 -630
  26. data/core/vendor/src/crfsuite/example/chunking.py +0 -49
  27. data/core/vendor/src/crfsuite/example/crfutils.py +0 -179
  28. data/core/vendor/src/crfsuite/example/ner.py +0 -270
  29. data/core/vendor/src/crfsuite/example/pos.py +0 -78
  30. data/core/vendor/src/crfsuite/example/template.py +0 -88
  31. data/core/vendor/src/crfsuite/frontend/Makefile.am +0 -29
  32. data/core/vendor/src/crfsuite/frontend/Makefile.in +0 -640
  33. data/core/vendor/src/crfsuite/frontend/dump.c +0 -116
  34. data/core/vendor/src/crfsuite/frontend/frontend.vcxproj +0 -129
  35. data/core/vendor/src/crfsuite/frontend/iwa.c +0 -273
  36. data/core/vendor/src/crfsuite/frontend/iwa.h +0 -65
  37. data/core/vendor/src/crfsuite/frontend/learn.c +0 -439
  38. data/core/vendor/src/crfsuite/frontend/main.c +0 -137
  39. data/core/vendor/src/crfsuite/frontend/option.c +0 -93
  40. data/core/vendor/src/crfsuite/frontend/option.h +0 -86
  41. data/core/vendor/src/crfsuite/frontend/readdata.h +0 -38
  42. data/core/vendor/src/crfsuite/frontend/reader.c +0 -136
  43. data/core/vendor/src/crfsuite/frontend/tag.c +0 -427
  44. data/core/vendor/src/crfsuite/genbinary.sh.in +0 -15
  45. data/core/vendor/src/crfsuite/include/Makefile.am +0 -11
  46. data/core/vendor/src/crfsuite/include/Makefile.in +0 -461
  47. data/core/vendor/src/crfsuite/include/crfsuite.h +0 -1063
  48. data/core/vendor/src/crfsuite/include/crfsuite.hpp +0 -555
  49. data/core/vendor/src/crfsuite/include/crfsuite_api.hpp +0 -400
  50. data/core/vendor/src/crfsuite/include/os.h +0 -61
  51. data/core/vendor/src/crfsuite/install-sh +0 -520
  52. data/core/vendor/src/crfsuite/lib/cqdb/COPYING +0 -28
  53. data/core/vendor/src/crfsuite/lib/cqdb/Makefile.am +0 -21
  54. data/core/vendor/src/crfsuite/lib/cqdb/Makefile.in +0 -549
  55. data/core/vendor/src/crfsuite/lib/cqdb/cqdb.vcxproj +0 -86
  56. data/core/vendor/src/crfsuite/lib/cqdb/include/cqdb.h +0 -524
  57. data/core/vendor/src/crfsuite/lib/cqdb/src/cqdb.c +0 -587
  58. data/core/vendor/src/crfsuite/lib/cqdb/src/lookup3.c +0 -976
  59. data/core/vendor/src/crfsuite/lib/crf/Makefile.am +0 -46
  60. data/core/vendor/src/crfsuite/lib/crf/Makefile.in +0 -721
  61. data/core/vendor/src/crfsuite/lib/crf/crf.vcxproj +0 -216
  62. data/core/vendor/src/crfsuite/lib/crf/src/crf1d.h +0 -353
  63. data/core/vendor/src/crfsuite/lib/crf/src/crf1d_context.c +0 -705
  64. data/core/vendor/src/crfsuite/lib/crf/src/crf1d_encode.c +0 -943
  65. data/core/vendor/src/crfsuite/lib/crf/src/crf1d_feature.c +0 -352
  66. data/core/vendor/src/crfsuite/lib/crf/src/crf1d_model.c +0 -994
  67. data/core/vendor/src/crfsuite/lib/crf/src/crf1d_tag.c +0 -550
  68. data/core/vendor/src/crfsuite/lib/crf/src/crfsuite.c +0 -492
  69. data/core/vendor/src/crfsuite/lib/crf/src/crfsuite_internal.h +0 -236
  70. data/core/vendor/src/crfsuite/lib/crf/src/crfsuite_train.c +0 -272
  71. data/core/vendor/src/crfsuite/lib/crf/src/dataset.c +0 -106
  72. data/core/vendor/src/crfsuite/lib/crf/src/dictionary.c +0 -118
  73. data/core/vendor/src/crfsuite/lib/crf/src/holdout.c +0 -80
  74. data/core/vendor/src/crfsuite/lib/crf/src/logging.c +0 -91
  75. data/core/vendor/src/crfsuite/lib/crf/src/logging.h +0 -48
  76. data/core/vendor/src/crfsuite/lib/crf/src/params.c +0 -335
  77. data/core/vendor/src/crfsuite/lib/crf/src/params.h +0 -80
  78. data/core/vendor/src/crfsuite/lib/crf/src/quark.c +0 -172
  79. data/core/vendor/src/crfsuite/lib/crf/src/quark.h +0 -46
  80. data/core/vendor/src/crfsuite/lib/crf/src/rumavl.c +0 -1107
  81. data/core/vendor/src/crfsuite/lib/crf/src/rumavl.h +0 -160
  82. data/core/vendor/src/crfsuite/lib/crf/src/train_arow.c +0 -408
  83. data/core/vendor/src/crfsuite/lib/crf/src/train_averaged_perceptron.c +0 -242
  84. data/core/vendor/src/crfsuite/lib/crf/src/train_l2sgd.c +0 -507
  85. data/core/vendor/src/crfsuite/lib/crf/src/train_lbfgs.c +0 -338
  86. data/core/vendor/src/crfsuite/lib/crf/src/train_passive_aggressive.c +0 -435
  87. data/core/vendor/src/crfsuite/lib/crf/src/vecmath.h +0 -341
  88. data/core/vendor/src/crfsuite/ltmain.sh +0 -8413
  89. data/core/vendor/src/crfsuite/missing +0 -376
  90. data/core/vendor/src/crfsuite/swig/Makefile.am +0 -13
  91. data/core/vendor/src/crfsuite/swig/Makefile.in +0 -365
  92. data/core/vendor/src/crfsuite/swig/crfsuite.cpp +0 -2
  93. data/core/vendor/src/crfsuite/swig/export.i +0 -32
  94. data/core/vendor/src/crfsuite/swig/python/README +0 -92
  95. data/core/vendor/src/crfsuite/swig/python/crfsuite.py +0 -329
  96. data/core/vendor/src/crfsuite/swig/python/export_wrap.cpp +0 -14355
  97. data/core/vendor/src/crfsuite/swig/python/export_wrap.h +0 -63
  98. data/core/vendor/src/crfsuite/swig/python/prepare.sh +0 -9
  99. data/core/vendor/src/crfsuite/swig/python/sample_tag.py +0 -52
  100. data/core/vendor/src/crfsuite/swig/python/sample_train.py +0 -68
  101. data/core/vendor/src/crfsuite/swig/python/setup.py +0 -44
  102. data/core/vendor/src/crfsuite/win32/stdint.h +0 -679
  103. data/core/vendor/src/liblbfgs/AUTHORS +0 -1
  104. data/core/vendor/src/liblbfgs/COPYING +0 -22
  105. data/core/vendor/src/liblbfgs/ChangeLog +0 -120
  106. data/core/vendor/src/liblbfgs/INSTALL +0 -231
  107. data/core/vendor/src/liblbfgs/Makefile.am +0 -10
  108. data/core/vendor/src/liblbfgs/Makefile.in +0 -638
  109. data/core/vendor/src/liblbfgs/NEWS +0 -0
  110. data/core/vendor/src/liblbfgs/README +0 -71
  111. data/core/vendor/src/liblbfgs/aclocal.m4 +0 -6985
  112. data/core/vendor/src/liblbfgs/autogen.sh +0 -38
  113. data/core/vendor/src/liblbfgs/config.guess +0 -1411
  114. data/core/vendor/src/liblbfgs/config.h.in +0 -64
  115. data/core/vendor/src/liblbfgs/config.sub +0 -1500
  116. data/core/vendor/src/liblbfgs/configure +0 -21146
  117. data/core/vendor/src/liblbfgs/configure.in +0 -107
  118. data/core/vendor/src/liblbfgs/depcomp +0 -522
  119. data/core/vendor/src/liblbfgs/include/lbfgs.h +0 -745
  120. data/core/vendor/src/liblbfgs/install-sh +0 -322
  121. data/core/vendor/src/liblbfgs/lbfgs.sln +0 -26
  122. data/core/vendor/src/liblbfgs/lib/Makefile.am +0 -24
  123. data/core/vendor/src/liblbfgs/lib/Makefile.in +0 -499
  124. data/core/vendor/src/liblbfgs/lib/arithmetic_ansi.h +0 -133
  125. data/core/vendor/src/liblbfgs/lib/arithmetic_sse_double.h +0 -294
  126. data/core/vendor/src/liblbfgs/lib/arithmetic_sse_float.h +0 -298
  127. data/core/vendor/src/liblbfgs/lib/lbfgs.c +0 -1371
  128. data/core/vendor/src/liblbfgs/lib/lib.vcxproj +0 -95
  129. data/core/vendor/src/liblbfgs/ltmain.sh +0 -6426
  130. data/core/vendor/src/liblbfgs/missing +0 -353
  131. data/core/vendor/src/liblbfgs/sample/Makefile.am +0 -15
  132. data/core/vendor/src/liblbfgs/sample/Makefile.in +0 -433
  133. data/core/vendor/src/liblbfgs/sample/sample.c +0 -81
  134. data/core/vendor/src/liblbfgs/sample/sample.cpp +0 -126
  135. data/core/vendor/src/liblbfgs/sample/sample.vcxproj +0 -105
  136. data/core/vendor/src/svm_light/LICENSE.txt +0 -59
  137. data/core/vendor/src/svm_light/Makefile +0 -105
  138. data/core/vendor/src/svm_light/kernel.h +0 -40
  139. data/core/vendor/src/svm_light/svm_classify.c +0 -197
  140. data/core/vendor/src/svm_light/svm_common.c +0 -985
  141. data/core/vendor/src/svm_light/svm_common.h +0 -301
  142. data/core/vendor/src/svm_light/svm_hideo.c +0 -1062
  143. data/core/vendor/src/svm_light/svm_learn.c +0 -4147
  144. data/core/vendor/src/svm_light/svm_learn.h +0 -169
  145. data/core/vendor/src/svm_light/svm_learn_main.c +0 -397
  146. data/core/vendor/src/svm_light/svm_loqo.c +0 -211
  147. data/task/c.rake +0 -36
  148. data/task/submodules.rake +0 -5
@@ -1,1371 +0,0 @@
1
- /*
2
- * Limited memory BFGS (L-BFGS).
3
- *
4
- * Copyright (c) 1990, Jorge Nocedal
5
- * Copyright (c) 2007-2010 Naoaki Okazaki
6
- * All rights reserved.
7
- *
8
- * Permission is hereby granted, free of charge, to any person obtaining a copy
9
- * of this software and associated documentation files (the "Software"), to deal
10
- * in the Software without restriction, including without limitation the rights
11
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- * copies of the Software, and to permit persons to whom the Software is
13
- * furnished to do so, subject to the following conditions:
14
- *
15
- * The above copyright notice and this permission notice shall be included in
16
- * all copies or substantial portions of the Software.
17
- *
18
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- * THE SOFTWARE.
25
- */
26
-
27
- /* $Id$ */
28
-
29
- /*
30
- This library is a C port of the FORTRAN implementation of Limited-memory
31
- Broyden-Fletcher-Goldfarb-Shanno (L-BFGS) method written by Jorge Nocedal.
32
- The original FORTRAN source code is available at:
33
- http://www.ece.northwestern.edu/~nocedal/lbfgs.html
34
-
35
- The L-BFGS algorithm is described in:
36
- - Jorge Nocedal.
37
- Updating Quasi-Newton Matrices with Limited Storage.
38
- <i>Mathematics of Computation</i>, Vol. 35, No. 151, pp. 773--782, 1980.
39
- - Dong C. Liu and Jorge Nocedal.
40
- On the limited memory BFGS method for large scale optimization.
41
- <i>Mathematical Programming</i> B, Vol. 45, No. 3, pp. 503-528, 1989.
42
-
43
- The line search algorithms used in this implementation are described in:
44
- - John E. Dennis and Robert B. Schnabel.
45
- <i>Numerical Methods for Unconstrained Optimization and Nonlinear
46
- Equations</i>, Englewood Cliffs, 1983.
47
- - Jorge J. More and David J. Thuente.
48
- Line search algorithm with guaranteed sufficient decrease.
49
- <i>ACM Transactions on Mathematical Software (TOMS)</i>, Vol. 20, No. 3,
50
- pp. 286-307, 1994.
51
-
52
- This library also implements Orthant-Wise Limited-memory Quasi-Newton (OWL-QN)
53
- method presented in:
54
- - Galen Andrew and Jianfeng Gao.
55
- Scalable training of L1-regularized log-linear models.
56
- In <i>Proceedings of the 24th International Conference on Machine
57
- Learning (ICML 2007)</i>, pp. 33-40, 2007.
58
-
59
- I would like to thank the original author, Jorge Nocedal, who has been
60
- distributing the effieicnt and explanatory implementation in an open source
61
- licence.
62
- */
63
-
64
- #ifdef HAVE_CONFIG_H
65
- #include <config.h>
66
- #endif/*HAVE_CONFIG_H*/
67
-
68
- #include <stdint.h>
69
- #include <stdio.h>
70
- #include <stdlib.h>
71
- #include <math.h>
72
-
73
- #include <lbfgs.h>
74
-
75
- #ifdef _MSC_VER
76
- #define inline __inline
77
- #endif/*_MSC_VER*/
78
-
79
- #if defined(USE_SSE) && defined(__SSE2__) && LBFGS_FLOAT == 64
80
- /* Use SSE2 optimization for 64bit double precision. */
81
- #include "arithmetic_sse_double.h"
82
-
83
- #elif defined(USE_SSE) && defined(__SSE__) && LBFGS_FLOAT == 32
84
- /* Use SSE optimization for 32bit float precision. */
85
- #include "arithmetic_sse_float.h"
86
-
87
- #else
88
- /* No CPU specific optimization. */
89
- #include "arithmetic_ansi.h"
90
-
91
- #endif
92
-
93
- #define min2(a, b) ((a) <= (b) ? (a) : (b))
94
- #define max2(a, b) ((a) >= (b) ? (a) : (b))
95
- #define max3(a, b, c) max2(max2((a), (b)), (c));
96
-
97
- struct tag_callback_data {
98
- int n;
99
- void *instance;
100
- lbfgs_evaluate_t proc_evaluate;
101
- lbfgs_progress_t proc_progress;
102
- };
103
- typedef struct tag_callback_data callback_data_t;
104
-
105
- struct tag_iteration_data {
106
- lbfgsfloatval_t alpha;
107
- lbfgsfloatval_t *s; /* [n] */
108
- lbfgsfloatval_t *y; /* [n] */
109
- lbfgsfloatval_t ys; /* vecdot(y, s) */
110
- };
111
- typedef struct tag_iteration_data iteration_data_t;
112
-
113
- static const lbfgs_parameter_t _defparam = {
114
- 6, 1e-5, 0, 1e-5,
115
- 0, LBFGS_LINESEARCH_DEFAULT, 40,
116
- 1e-20, 1e20, 1e-4, 0.9, 0.9, 1.0e-16,
117
- 0.0, 0, -1,
118
- };
119
-
120
- /* Forward function declarations. */
121
-
122
- typedef int (*line_search_proc)(
123
- int n,
124
- lbfgsfloatval_t *x,
125
- lbfgsfloatval_t *f,
126
- lbfgsfloatval_t *g,
127
- lbfgsfloatval_t *s,
128
- lbfgsfloatval_t *stp,
129
- const lbfgsfloatval_t* xp,
130
- const lbfgsfloatval_t* gp,
131
- lbfgsfloatval_t *wa,
132
- callback_data_t *cd,
133
- const lbfgs_parameter_t *param
134
- );
135
-
136
- static int line_search_backtracking(
137
- int n,
138
- lbfgsfloatval_t *x,
139
- lbfgsfloatval_t *f,
140
- lbfgsfloatval_t *g,
141
- lbfgsfloatval_t *s,
142
- lbfgsfloatval_t *stp,
143
- const lbfgsfloatval_t* xp,
144
- const lbfgsfloatval_t* gp,
145
- lbfgsfloatval_t *wa,
146
- callback_data_t *cd,
147
- const lbfgs_parameter_t *param
148
- );
149
-
150
- static int line_search_backtracking_owlqn(
151
- int n,
152
- lbfgsfloatval_t *x,
153
- lbfgsfloatval_t *f,
154
- lbfgsfloatval_t *g,
155
- lbfgsfloatval_t *s,
156
- lbfgsfloatval_t *stp,
157
- const lbfgsfloatval_t* xp,
158
- const lbfgsfloatval_t* gp,
159
- lbfgsfloatval_t *wp,
160
- callback_data_t *cd,
161
- const lbfgs_parameter_t *param
162
- );
163
-
164
- static int line_search_morethuente(
165
- int n,
166
- lbfgsfloatval_t *x,
167
- lbfgsfloatval_t *f,
168
- lbfgsfloatval_t *g,
169
- lbfgsfloatval_t *s,
170
- lbfgsfloatval_t *stp,
171
- const lbfgsfloatval_t* xp,
172
- const lbfgsfloatval_t* gp,
173
- lbfgsfloatval_t *wa,
174
- callback_data_t *cd,
175
- const lbfgs_parameter_t *param
176
- );
177
-
178
- static int update_trial_interval(
179
- lbfgsfloatval_t *x,
180
- lbfgsfloatval_t *fx,
181
- lbfgsfloatval_t *dx,
182
- lbfgsfloatval_t *y,
183
- lbfgsfloatval_t *fy,
184
- lbfgsfloatval_t *dy,
185
- lbfgsfloatval_t *t,
186
- lbfgsfloatval_t *ft,
187
- lbfgsfloatval_t *dt,
188
- const lbfgsfloatval_t tmin,
189
- const lbfgsfloatval_t tmax,
190
- int *brackt
191
- );
192
-
193
- static lbfgsfloatval_t owlqn_x1norm(
194
- const lbfgsfloatval_t* x,
195
- const int start,
196
- const int n
197
- );
198
-
199
- static void owlqn_pseudo_gradient(
200
- lbfgsfloatval_t* pg,
201
- const lbfgsfloatval_t* x,
202
- const lbfgsfloatval_t* g,
203
- const int n,
204
- const lbfgsfloatval_t c,
205
- const int start,
206
- const int end
207
- );
208
-
209
- static void owlqn_project(
210
- lbfgsfloatval_t* d,
211
- const lbfgsfloatval_t* sign,
212
- const int start,
213
- const int end
214
- );
215
-
216
-
217
- #if defined(USE_SSE) && (defined(__SSE__) || defined(__SSE2__))
218
- static int round_out_variables(int n)
219
- {
220
- n += 7;
221
- n /= 8;
222
- n *= 8;
223
- return n;
224
- }
225
- #endif/*defined(USE_SSE)*/
226
-
227
- lbfgsfloatval_t* lbfgs_malloc(int n)
228
- {
229
- #if defined(USE_SSE) && (defined(__SSE__) || defined(__SSE2__))
230
- n = round_out_variables(n);
231
- #endif/*defined(USE_SSE)*/
232
- return (lbfgsfloatval_t*)vecalloc(sizeof(lbfgsfloatval_t) * n);
233
- }
234
-
235
- void lbfgs_free(lbfgsfloatval_t *x)
236
- {
237
- vecfree(x);
238
- }
239
-
240
- void lbfgs_parameter_init(lbfgs_parameter_t *param)
241
- {
242
- memcpy(param, &_defparam, sizeof(*param));
243
- }
244
-
245
- int lbfgs(
246
- int n,
247
- lbfgsfloatval_t *x,
248
- lbfgsfloatval_t *ptr_fx,
249
- lbfgs_evaluate_t proc_evaluate,
250
- lbfgs_progress_t proc_progress,
251
- void *instance,
252
- lbfgs_parameter_t *_param
253
- )
254
- {
255
- int ret;
256
- int i, j, k, ls, end, bound;
257
- lbfgsfloatval_t step;
258
-
259
- /* Constant parameters and their default values. */
260
- lbfgs_parameter_t param = (_param != NULL) ? (*_param) : _defparam;
261
- const int m = param.m;
262
-
263
- lbfgsfloatval_t *xp = NULL;
264
- lbfgsfloatval_t *g = NULL, *gp = NULL, *pg = NULL;
265
- lbfgsfloatval_t *d = NULL, *w = NULL, *pf = NULL;
266
- iteration_data_t *lm = NULL, *it = NULL;
267
- lbfgsfloatval_t ys, yy;
268
- lbfgsfloatval_t xnorm, gnorm, beta;
269
- lbfgsfloatval_t fx = 0.;
270
- lbfgsfloatval_t rate = 0.;
271
- line_search_proc linesearch = line_search_morethuente;
272
-
273
- /* Construct a callback data. */
274
- callback_data_t cd;
275
- cd.n = n;
276
- cd.instance = instance;
277
- cd.proc_evaluate = proc_evaluate;
278
- cd.proc_progress = proc_progress;
279
-
280
- #if defined(USE_SSE) && (defined(__SSE__) || defined(__SSE2__))
281
- /* Round out the number of variables. */
282
- n = round_out_variables(n);
283
- #endif/*defined(USE_SSE)*/
284
-
285
- /* Check the input parameters for errors. */
286
- if (n <= 0) {
287
- return LBFGSERR_INVALID_N;
288
- }
289
- #if defined(USE_SSE) && (defined(__SSE__) || defined(__SSE2__))
290
- if (n % 8 != 0) {
291
- return LBFGSERR_INVALID_N_SSE;
292
- }
293
- if ((uintptr_t)(const void*)x % 16 != 0) {
294
- return LBFGSERR_INVALID_X_SSE;
295
- }
296
- #endif/*defined(USE_SSE)*/
297
- if (param.epsilon < 0.) {
298
- return LBFGSERR_INVALID_EPSILON;
299
- }
300
- if (param.past < 0) {
301
- return LBFGSERR_INVALID_TESTPERIOD;
302
- }
303
- if (param.delta < 0.) {
304
- return LBFGSERR_INVALID_DELTA;
305
- }
306
- if (param.min_step < 0.) {
307
- return LBFGSERR_INVALID_MINSTEP;
308
- }
309
- if (param.max_step < param.min_step) {
310
- return LBFGSERR_INVALID_MAXSTEP;
311
- }
312
- if (param.ftol < 0.) {
313
- return LBFGSERR_INVALID_FTOL;
314
- }
315
- if (param.linesearch == LBFGS_LINESEARCH_BACKTRACKING_WOLFE ||
316
- param.linesearch == LBFGS_LINESEARCH_BACKTRACKING_STRONG_WOLFE) {
317
- if (param.wolfe <= param.ftol || 1. <= param.wolfe) {
318
- return LBFGSERR_INVALID_WOLFE;
319
- }
320
- }
321
- if (param.gtol < 0.) {
322
- return LBFGSERR_INVALID_GTOL;
323
- }
324
- if (param.xtol < 0.) {
325
- return LBFGSERR_INVALID_XTOL;
326
- }
327
- if (param.max_linesearch <= 0) {
328
- return LBFGSERR_INVALID_MAXLINESEARCH;
329
- }
330
- if (param.orthantwise_c < 0.) {
331
- return LBFGSERR_INVALID_ORTHANTWISE;
332
- }
333
- if (param.orthantwise_start < 0 || n < param.orthantwise_start) {
334
- return LBFGSERR_INVALID_ORTHANTWISE_START;
335
- }
336
- if (param.orthantwise_end < 0) {
337
- param.orthantwise_end = n;
338
- }
339
- if (n < param.orthantwise_end) {
340
- return LBFGSERR_INVALID_ORTHANTWISE_END;
341
- }
342
- if (param.orthantwise_c != 0.) {
343
- switch (param.linesearch) {
344
- case LBFGS_LINESEARCH_BACKTRACKING:
345
- linesearch = line_search_backtracking_owlqn;
346
- break;
347
- default:
348
- /* Only the backtracking method is available. */
349
- return LBFGSERR_INVALID_LINESEARCH;
350
- }
351
- } else {
352
- switch (param.linesearch) {
353
- case LBFGS_LINESEARCH_MORETHUENTE:
354
- linesearch = line_search_morethuente;
355
- break;
356
- case LBFGS_LINESEARCH_BACKTRACKING_ARMIJO:
357
- case LBFGS_LINESEARCH_BACKTRACKING_WOLFE:
358
- case LBFGS_LINESEARCH_BACKTRACKING_STRONG_WOLFE:
359
- linesearch = line_search_backtracking;
360
- break;
361
- default:
362
- return LBFGSERR_INVALID_LINESEARCH;
363
- }
364
- }
365
-
366
- /* Allocate working space. */
367
- xp = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
368
- g = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
369
- gp = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
370
- d = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
371
- w = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
372
- if (xp == NULL || g == NULL || gp == NULL || d == NULL || w == NULL) {
373
- ret = LBFGSERR_OUTOFMEMORY;
374
- goto lbfgs_exit;
375
- }
376
-
377
- if (param.orthantwise_c != 0.) {
378
- /* Allocate working space for OW-LQN. */
379
- pg = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
380
- if (pg == NULL) {
381
- ret = LBFGSERR_OUTOFMEMORY;
382
- goto lbfgs_exit;
383
- }
384
- }
385
-
386
- /* Allocate limited memory storage. */
387
- lm = (iteration_data_t*)vecalloc(m * sizeof(iteration_data_t));
388
- if (lm == NULL) {
389
- ret = LBFGSERR_OUTOFMEMORY;
390
- goto lbfgs_exit;
391
- }
392
-
393
- /* Initialize the limited memory. */
394
- for (i = 0;i < m;++i) {
395
- it = &lm[i];
396
- it->alpha = 0;
397
- it->ys = 0;
398
- it->s = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
399
- it->y = (lbfgsfloatval_t*)vecalloc(n * sizeof(lbfgsfloatval_t));
400
- if (it->s == NULL || it->y == NULL) {
401
- ret = LBFGSERR_OUTOFMEMORY;
402
- goto lbfgs_exit;
403
- }
404
- }
405
-
406
- /* Allocate an array for storing previous values of the objective function. */
407
- if (0 < param.past) {
408
- pf = (lbfgsfloatval_t*)vecalloc(param.past * sizeof(lbfgsfloatval_t));
409
- }
410
-
411
- /* Evaluate the function value and its gradient. */
412
- fx = cd.proc_evaluate(cd.instance, x, g, cd.n, 0);
413
- if (0. != param.orthantwise_c) {
414
- /* Compute the L1 norm of the variable and add it to the object value. */
415
- xnorm = owlqn_x1norm(x, param.orthantwise_start, param.orthantwise_end);
416
- fx += xnorm * param.orthantwise_c;
417
- owlqn_pseudo_gradient(
418
- pg, x, g, n,
419
- param.orthantwise_c, param.orthantwise_start, param.orthantwise_end
420
- );
421
- }
422
-
423
- /* Store the initial value of the objective function. */
424
- if (pf != NULL) {
425
- pf[0] = fx;
426
- }
427
-
428
- /*
429
- Compute the direction;
430
- we assume the initial hessian matrix H_0 as the identity matrix.
431
- */
432
- if (param.orthantwise_c == 0.) {
433
- vecncpy(d, g, n);
434
- } else {
435
- vecncpy(d, pg, n);
436
- }
437
-
438
- /*
439
- Make sure that the initial variables are not a minimizer.
440
- */
441
- vec2norm(&xnorm, x, n);
442
- if (param.orthantwise_c == 0.) {
443
- vec2norm(&gnorm, g, n);
444
- } else {
445
- vec2norm(&gnorm, pg, n);
446
- }
447
- if (xnorm < 1.0) xnorm = 1.0;
448
- if (gnorm / xnorm <= param.epsilon) {
449
- ret = LBFGS_ALREADY_MINIMIZED;
450
- goto lbfgs_exit;
451
- }
452
-
453
- /* Compute the initial step:
454
- step = 1.0 / sqrt(vecdot(d, d, n))
455
- */
456
- vec2norminv(&step, d, n);
457
-
458
- k = 1;
459
- end = 0;
460
- for (;;) {
461
- /* Store the current position and gradient vectors. */
462
- veccpy(xp, x, n);
463
- veccpy(gp, g, n);
464
-
465
- /* Search for an optimal step. */
466
- if (param.orthantwise_c == 0.) {
467
- ls = linesearch(n, x, &fx, g, d, &step, xp, gp, w, &cd, &param);
468
- } else {
469
- ls = linesearch(n, x, &fx, g, d, &step, xp, pg, w, &cd, &param);
470
- owlqn_pseudo_gradient(
471
- pg, x, g, n,
472
- param.orthantwise_c, param.orthantwise_start, param.orthantwise_end
473
- );
474
- }
475
- if (ls < 0) {
476
- /* Revert to the previous point. */
477
- veccpy(x, xp, n);
478
- veccpy(g, gp, n);
479
- ret = ls;
480
- goto lbfgs_exit;
481
- }
482
-
483
- /* Compute x and g norms. */
484
- vec2norm(&xnorm, x, n);
485
- if (param.orthantwise_c == 0.) {
486
- vec2norm(&gnorm, g, n);
487
- } else {
488
- vec2norm(&gnorm, pg, n);
489
- }
490
-
491
- /* Report the progress. */
492
- if (cd.proc_progress) {
493
- if ((ret = cd.proc_progress(cd.instance, x, g, fx, xnorm, gnorm, step, cd.n, k, ls))) {
494
- goto lbfgs_exit;
495
- }
496
- }
497
-
498
- /*
499
- Convergence test.
500
- The criterion is given by the following formula:
501
- |g(x)| / \max(1, |x|) < \epsilon
502
- */
503
- if (xnorm < 1.0) xnorm = 1.0;
504
- if (gnorm / xnorm <= param.epsilon) {
505
- /* Convergence. */
506
- ret = LBFGS_SUCCESS;
507
- break;
508
- }
509
-
510
- /*
511
- Test for stopping criterion.
512
- The criterion is given by the following formula:
513
- (f(past_x) - f(x)) / f(x) < \delta
514
- */
515
- if (pf != NULL) {
516
- /* We don't test the stopping criterion while k < past. */
517
- if (param.past <= k) {
518
- /* Compute the relative improvement from the past. */
519
- rate = (pf[k % param.past] - fx) / fx;
520
-
521
- /* The stopping criterion. */
522
- if (rate < param.delta) {
523
- ret = LBFGS_STOP;
524
- break;
525
- }
526
- }
527
-
528
- /* Store the current value of the objective function. */
529
- pf[k % param.past] = fx;
530
- }
531
-
532
- if (param.max_iterations != 0 && param.max_iterations < k+1) {
533
- /* Maximum number of iterations. */
534
- ret = LBFGSERR_MAXIMUMITERATION;
535
- break;
536
- }
537
-
538
- /*
539
- Update vectors s and y:
540
- s_{k+1} = x_{k+1} - x_{k} = \step * d_{k}.
541
- y_{k+1} = g_{k+1} - g_{k}.
542
- */
543
- it = &lm[end];
544
- vecdiff(it->s, x, xp, n);
545
- vecdiff(it->y, g, gp, n);
546
-
547
- /*
548
- Compute scalars ys and yy:
549
- ys = y^t \cdot s = 1 / \rho.
550
- yy = y^t \cdot y.
551
- Notice that yy is used for scaling the hessian matrix H_0 (Cholesky factor).
552
- */
553
- vecdot(&ys, it->y, it->s, n);
554
- vecdot(&yy, it->y, it->y, n);
555
- it->ys = ys;
556
-
557
- /*
558
- Recursive formula to compute dir = -(H \cdot g).
559
- This is described in page 779 of:
560
- Jorge Nocedal.
561
- Updating Quasi-Newton Matrices with Limited Storage.
562
- Mathematics of Computation, Vol. 35, No. 151,
563
- pp. 773--782, 1980.
564
- */
565
- bound = (m <= k) ? m : k;
566
- ++k;
567
- end = (end + 1) % m;
568
-
569
- /* Compute the steepest direction. */
570
- if (param.orthantwise_c == 0.) {
571
- /* Compute the negative of gradients. */
572
- vecncpy(d, g, n);
573
- } else {
574
- vecncpy(d, pg, n);
575
- }
576
-
577
- j = end;
578
- for (i = 0;i < bound;++i) {
579
- j = (j + m - 1) % m; /* if (--j == -1) j = m-1; */
580
- it = &lm[j];
581
- /* \alpha_{j} = \rho_{j} s^{t}_{j} \cdot q_{k+1}. */
582
- vecdot(&it->alpha, it->s, d, n);
583
- it->alpha /= it->ys;
584
- /* q_{i} = q_{i+1} - \alpha_{i} y_{i}. */
585
- vecadd(d, it->y, -it->alpha, n);
586
- }
587
-
588
- vecscale(d, ys / yy, n);
589
-
590
- for (i = 0;i < bound;++i) {
591
- it = &lm[j];
592
- /* \beta_{j} = \rho_{j} y^t_{j} \cdot \gamma_{i}. */
593
- vecdot(&beta, it->y, d, n);
594
- beta /= it->ys;
595
- /* \gamma_{i+1} = \gamma_{i} + (\alpha_{j} - \beta_{j}) s_{j}. */
596
- vecadd(d, it->s, it->alpha - beta, n);
597
- j = (j + 1) % m; /* if (++j == m) j = 0; */
598
- }
599
-
600
- /*
601
- Constrain the search direction for orthant-wise updates.
602
- */
603
- if (param.orthantwise_c != 0.) {
604
- for (i = param.orthantwise_start;i < param.orthantwise_end;++i) {
605
- if (d[i] * pg[i] >= 0) {
606
- d[i] = 0;
607
- }
608
- }
609
- }
610
-
611
- /*
612
- Now the search direction d is ready. We try step = 1 first.
613
- */
614
- step = 1.0;
615
- }
616
-
617
- lbfgs_exit:
618
- /* Return the final value of the objective function. */
619
- if (ptr_fx != NULL) {
620
- *ptr_fx = fx;
621
- }
622
-
623
- vecfree(pf);
624
-
625
- /* Free memory blocks used by this function. */
626
- if (lm != NULL) {
627
- for (i = 0;i < m;++i) {
628
- vecfree(lm[i].s);
629
- vecfree(lm[i].y);
630
- }
631
- vecfree(lm);
632
- }
633
- vecfree(pg);
634
- vecfree(w);
635
- vecfree(d);
636
- vecfree(gp);
637
- vecfree(g);
638
- vecfree(xp);
639
-
640
- return ret;
641
- }
642
-
643
-
644
-
645
- static int line_search_backtracking(
646
- int n,
647
- lbfgsfloatval_t *x,
648
- lbfgsfloatval_t *f,
649
- lbfgsfloatval_t *g,
650
- lbfgsfloatval_t *s,
651
- lbfgsfloatval_t *stp,
652
- const lbfgsfloatval_t* xp,
653
- const lbfgsfloatval_t* gp,
654
- lbfgsfloatval_t *wp,
655
- callback_data_t *cd,
656
- const lbfgs_parameter_t *param
657
- )
658
- {
659
- int count = 0;
660
- lbfgsfloatval_t width, dg;
661
- lbfgsfloatval_t finit, dginit = 0., dgtest;
662
- const lbfgsfloatval_t dec = 0.5, inc = 2.1;
663
-
664
- /* Check the input parameters for errors. */
665
- if (*stp <= 0.) {
666
- return LBFGSERR_INVALIDPARAMETERS;
667
- }
668
-
669
- /* Compute the initial gradient in the search direction. */
670
- vecdot(&dginit, g, s, n);
671
-
672
- /* Make sure that s points to a descent direction. */
673
- if (0 < dginit) {
674
- return LBFGSERR_INCREASEGRADIENT;
675
- }
676
-
677
- /* The initial value of the objective function. */
678
- finit = *f;
679
- dgtest = param->ftol * dginit;
680
-
681
- for (;;) {
682
- veccpy(x, xp, n);
683
- vecadd(x, s, *stp, n);
684
-
685
- /* Evaluate the function and gradient values. */
686
- *f = cd->proc_evaluate(cd->instance, x, g, cd->n, *stp);
687
-
688
- ++count;
689
-
690
- if (*f > finit + *stp * dgtest) {
691
- width = dec;
692
- } else {
693
- /* The sufficient decrease condition (Armijo condition). */
694
- if (param->linesearch == LBFGS_LINESEARCH_BACKTRACKING_ARMIJO) {
695
- /* Exit with the Armijo condition. */
696
- return count;
697
- }
698
-
699
- /* Check the Wolfe condition. */
700
- vecdot(&dg, g, s, n);
701
- if (dg < param->wolfe * dginit) {
702
- width = inc;
703
- } else {
704
- if(param->linesearch == LBFGS_LINESEARCH_BACKTRACKING_WOLFE) {
705
- /* Exit with the regular Wolfe condition. */
706
- return count;
707
- }
708
-
709
- /* Check the strong Wolfe condition. */
710
- if(dg > -param->wolfe * dginit) {
711
- width = dec;
712
- } else {
713
- /* Exit with the strong Wolfe condition. */
714
- return count;
715
- }
716
- }
717
- }
718
-
719
- if (*stp < param->min_step) {
720
- /* The step is the minimum value. */
721
- return LBFGSERR_MINIMUMSTEP;
722
- }
723
- if (*stp > param->max_step) {
724
- /* The step is the maximum value. */
725
- return LBFGSERR_MAXIMUMSTEP;
726
- }
727
- if (param->max_linesearch <= count) {
728
- /* Maximum number of iteration. */
729
- return LBFGSERR_MAXIMUMLINESEARCH;
730
- }
731
-
732
- (*stp) *= width;
733
- }
734
- }
735
-
736
-
737
-
738
- static int line_search_backtracking_owlqn(
739
- int n,
740
- lbfgsfloatval_t *x,
741
- lbfgsfloatval_t *f,
742
- lbfgsfloatval_t *g,
743
- lbfgsfloatval_t *s,
744
- lbfgsfloatval_t *stp,
745
- const lbfgsfloatval_t* xp,
746
- const lbfgsfloatval_t* gp,
747
- lbfgsfloatval_t *wp,
748
- callback_data_t *cd,
749
- const lbfgs_parameter_t *param
750
- )
751
- {
752
- int i, count = 0;
753
- lbfgsfloatval_t width = 0.5, norm = 0.;
754
- lbfgsfloatval_t finit = *f, dgtest;
755
-
756
- /* Check the input parameters for errors. */
757
- if (*stp <= 0.) {
758
- return LBFGSERR_INVALIDPARAMETERS;
759
- }
760
-
761
- /* Choose the orthant for the new point. */
762
- for (i = 0;i < n;++i) {
763
- wp[i] = (xp[i] == 0.) ? -gp[i] : xp[i];
764
- }
765
-
766
- for (;;) {
767
- /* Update the current point. */
768
- veccpy(x, xp, n);
769
- vecadd(x, s, *stp, n);
770
-
771
- /* The current point is projected onto the orthant. */
772
- owlqn_project(x, wp, param->orthantwise_start, param->orthantwise_end);
773
-
774
- /* Evaluate the function and gradient values. */
775
- *f = cd->proc_evaluate(cd->instance, x, g, cd->n, *stp);
776
-
777
- /* Compute the L1 norm of the variables and add it to the object value. */
778
- norm = owlqn_x1norm(x, param->orthantwise_start, param->orthantwise_end);
779
- *f += norm * param->orthantwise_c;
780
-
781
- ++count;
782
-
783
- dgtest = 0.;
784
- for (i = 0;i < n;++i) {
785
- dgtest += (x[i] - xp[i]) * gp[i];
786
- }
787
-
788
- if (*f <= finit + param->ftol * dgtest) {
789
- /* The sufficient decrease condition. */
790
- return count;
791
- }
792
-
793
- if (*stp < param->min_step) {
794
- /* The step is the minimum value. */
795
- return LBFGSERR_MINIMUMSTEP;
796
- }
797
- if (*stp > param->max_step) {
798
- /* The step is the maximum value. */
799
- return LBFGSERR_MAXIMUMSTEP;
800
- }
801
- if (param->max_linesearch <= count) {
802
- /* Maximum number of iteration. */
803
- return LBFGSERR_MAXIMUMLINESEARCH;
804
- }
805
-
806
- (*stp) *= width;
807
- }
808
- }
809
-
810
-
811
-
812
- static int line_search_morethuente(
813
- int n,
814
- lbfgsfloatval_t *x,
815
- lbfgsfloatval_t *f,
816
- lbfgsfloatval_t *g,
817
- lbfgsfloatval_t *s,
818
- lbfgsfloatval_t *stp,
819
- const lbfgsfloatval_t* xp,
820
- const lbfgsfloatval_t* gp,
821
- lbfgsfloatval_t *wa,
822
- callback_data_t *cd,
823
- const lbfgs_parameter_t *param
824
- )
825
- {
826
- int count = 0;
827
- int brackt, stage1, uinfo = 0;
828
- lbfgsfloatval_t dg;
829
- lbfgsfloatval_t stx, fx, dgx;
830
- lbfgsfloatval_t sty, fy, dgy;
831
- lbfgsfloatval_t fxm, dgxm, fym, dgym, fm, dgm;
832
- lbfgsfloatval_t finit, ftest1, dginit, dgtest;
833
- lbfgsfloatval_t width, prev_width;
834
- lbfgsfloatval_t stmin, stmax;
835
-
836
- /* Check the input parameters for errors. */
837
- if (*stp <= 0.) {
838
- return LBFGSERR_INVALIDPARAMETERS;
839
- }
840
-
841
- /* Compute the initial gradient in the search direction. */
842
- vecdot(&dginit, g, s, n);
843
-
844
- /* Make sure that s points to a descent direction. */
845
- if (0 < dginit) {
846
- return LBFGSERR_INCREASEGRADIENT;
847
- }
848
-
849
- /* Initialize local variables. */
850
- brackt = 0;
851
- stage1 = 1;
852
- finit = *f;
853
- dgtest = param->ftol * dginit;
854
- width = param->max_step - param->min_step;
855
- prev_width = 2.0 * width;
856
-
857
- /*
858
- The variables stx, fx, dgx contain the values of the step,
859
- function, and directional derivative at the best step.
860
- The variables sty, fy, dgy contain the value of the step,
861
- function, and derivative at the other endpoint of
862
- the interval of uncertainty.
863
- The variables stp, f, dg contain the values of the step,
864
- function, and derivative at the current step.
865
- */
866
- stx = sty = 0.;
867
- fx = fy = finit;
868
- dgx = dgy = dginit;
869
-
870
- for (;;) {
871
- /*
872
- Set the minimum and maximum steps to correspond to the
873
- present interval of uncertainty.
874
- */
875
- if (brackt) {
876
- stmin = min2(stx, sty);
877
- stmax = max2(stx, sty);
878
- } else {
879
- stmin = stx;
880
- stmax = *stp + 4.0 * (*stp - stx);
881
- }
882
-
883
- /* Clip the step in the range of [stpmin, stpmax]. */
884
- if (*stp < param->min_step) *stp = param->min_step;
885
- if (param->max_step < *stp) *stp = param->max_step;
886
-
887
- /*
888
- If an unusual termination is to occur then let
889
- stp be the lowest point obtained so far.
890
- */
891
- if ((brackt && ((*stp <= stmin || stmax <= *stp) || param->max_linesearch <= count + 1 || uinfo != 0)) || (brackt && (stmax - stmin <= param->xtol * stmax))) {
892
- *stp = stx;
893
- }
894
-
895
- /*
896
- Compute the current value of x:
897
- x <- x + (*stp) * s.
898
- */
899
- veccpy(x, xp, n);
900
- vecadd(x, s, *stp, n);
901
-
902
- /* Evaluate the function and gradient values. */
903
- *f = cd->proc_evaluate(cd->instance, x, g, cd->n, *stp);
904
- vecdot(&dg, g, s, n);
905
-
906
- ftest1 = finit + *stp * dgtest;
907
- ++count;
908
-
909
- /* Test for errors and convergence. */
910
- if (brackt && ((*stp <= stmin || stmax <= *stp) || uinfo != 0)) {
911
- /* Rounding errors prevent further progress. */
912
- return LBFGSERR_ROUNDING_ERROR;
913
- }
914
- if (*stp == param->max_step && *f <= ftest1 && dg <= dgtest) {
915
- /* The step is the maximum value. */
916
- return LBFGSERR_MAXIMUMSTEP;
917
- }
918
- if (*stp == param->min_step && (ftest1 < *f || dgtest <= dg)) {
919
- /* The step is the minimum value. */
920
- return LBFGSERR_MINIMUMSTEP;
921
- }
922
- if (brackt && (stmax - stmin) <= param->xtol * stmax) {
923
- /* Relative width of the interval of uncertainty is at most xtol. */
924
- return LBFGSERR_WIDTHTOOSMALL;
925
- }
926
- if (param->max_linesearch <= count) {
927
- /* Maximum number of iteration. */
928
- return LBFGSERR_MAXIMUMLINESEARCH;
929
- }
930
- if (*f <= ftest1 && fabs(dg) <= param->gtol * (-dginit)) {
931
- /* The sufficient decrease condition and the directional derivative condition hold. */
932
- return count;
933
- }
934
-
935
- /*
936
- In the first stage we seek a step for which the modified
937
- function has a nonpositive value and nonnegative derivative.
938
- */
939
- if (stage1 && *f <= ftest1 && min2(param->ftol, param->gtol) * dginit <= dg) {
940
- stage1 = 0;
941
- }
942
-
943
- /*
944
- A modified function is used to predict the step only if
945
- we have not obtained a step for which the modified
946
- function has a nonpositive function value and nonnegative
947
- derivative, and if a lower function value has been
948
- obtained but the decrease is not sufficient.
949
- */
950
- if (stage1 && ftest1 < *f && *f <= fx) {
951
- /* Define the modified function and derivative values. */
952
- fm = *f - *stp * dgtest;
953
- fxm = fx - stx * dgtest;
954
- fym = fy - sty * dgtest;
955
- dgm = dg - dgtest;
956
- dgxm = dgx - dgtest;
957
- dgym = dgy - dgtest;
958
-
959
- /*
960
- Call update_trial_interval() to update the interval of
961
- uncertainty and to compute the new step.
962
- */
963
- uinfo = update_trial_interval(
964
- &stx, &fxm, &dgxm,
965
- &sty, &fym, &dgym,
966
- stp, &fm, &dgm,
967
- stmin, stmax, &brackt
968
- );
969
-
970
- /* Reset the function and gradient values for f. */
971
- fx = fxm + stx * dgtest;
972
- fy = fym + sty * dgtest;
973
- dgx = dgxm + dgtest;
974
- dgy = dgym + dgtest;
975
- } else {
976
- /*
977
- Call update_trial_interval() to update the interval of
978
- uncertainty and to compute the new step.
979
- */
980
- uinfo = update_trial_interval(
981
- &stx, &fx, &dgx,
982
- &sty, &fy, &dgy,
983
- stp, f, &dg,
984
- stmin, stmax, &brackt
985
- );
986
- }
987
-
988
- /*
989
- Force a sufficient decrease in the interval of uncertainty.
990
- */
991
- if (brackt) {
992
- if (0.66 * prev_width <= fabs(sty - stx)) {
993
- *stp = stx + 0.5 * (sty - stx);
994
- }
995
- prev_width = width;
996
- width = fabs(sty - stx);
997
- }
998
- }
999
-
1000
- return LBFGSERR_LOGICERROR;
1001
- }
1002
-
1003
-
1004
-
1005
- /**
1006
- * Define the local variables for computing minimizers.
1007
- */
1008
- #define USES_MINIMIZER \
1009
- lbfgsfloatval_t a, d, gamma, theta, p, q, r, s;
1010
-
1011
- /**
1012
- * Find a minimizer of an interpolated cubic function.
1013
- * @param cm The minimizer of the interpolated cubic.
1014
- * @param u The value of one point, u.
1015
- * @param fu The value of f(u).
1016
- * @param du The value of f'(u).
1017
- * @param v The value of another point, v.
1018
- * @param fv The value of f(v).
1019
- * @param du The value of f'(v).
1020
- */
1021
- #define CUBIC_MINIMIZER(cm, u, fu, du, v, fv, dv) \
1022
- d = (v) - (u); \
1023
- theta = ((fu) - (fv)) * 3 / d + (du) + (dv); \
1024
- p = fabs(theta); \
1025
- q = fabs(du); \
1026
- r = fabs(dv); \
1027
- s = max3(p, q, r); \
1028
- /* gamma = s*sqrt((theta/s)**2 - (du/s) * (dv/s)) */ \
1029
- a = theta / s; \
1030
- gamma = s * sqrt(a * a - ((du) / s) * ((dv) / s)); \
1031
- if ((v) < (u)) gamma = -gamma; \
1032
- p = gamma - (du) + theta; \
1033
- q = gamma - (du) + gamma + (dv); \
1034
- r = p / q; \
1035
- (cm) = (u) + r * d;
1036
-
1037
- /**
1038
- * Find a minimizer of an interpolated cubic function.
1039
- * @param cm The minimizer of the interpolated cubic.
1040
- * @param u The value of one point, u.
1041
- * @param fu The value of f(u).
1042
- * @param du The value of f'(u).
1043
- * @param v The value of another point, v.
1044
- * @param fv The value of f(v).
1045
- * @param du The value of f'(v).
1046
- * @param xmin The maximum value.
1047
- * @param xmin The minimum value.
1048
- */
1049
- #define CUBIC_MINIMIZER2(cm, u, fu, du, v, fv, dv, xmin, xmax) \
1050
- d = (v) - (u); \
1051
- theta = ((fu) - (fv)) * 3 / d + (du) + (dv); \
1052
- p = fabs(theta); \
1053
- q = fabs(du); \
1054
- r = fabs(dv); \
1055
- s = max3(p, q, r); \
1056
- /* gamma = s*sqrt((theta/s)**2 - (du/s) * (dv/s)) */ \
1057
- a = theta / s; \
1058
- gamma = s * sqrt(max2(0, a * a - ((du) / s) * ((dv) / s))); \
1059
- if ((u) < (v)) gamma = -gamma; \
1060
- p = gamma - (dv) + theta; \
1061
- q = gamma - (dv) + gamma + (du); \
1062
- r = p / q; \
1063
- if (r < 0. && gamma != 0.) { \
1064
- (cm) = (v) - r * d; \
1065
- } else if (a < 0) { \
1066
- (cm) = (xmax); \
1067
- } else { \
1068
- (cm) = (xmin); \
1069
- }
1070
-
1071
- /**
1072
- * Find a minimizer of an interpolated quadratic function.
1073
- * @param qm The minimizer of the interpolated quadratic.
1074
- * @param u The value of one point, u.
1075
- * @param fu The value of f(u).
1076
- * @param du The value of f'(u).
1077
- * @param v The value of another point, v.
1078
- * @param fv The value of f(v).
1079
- */
1080
- #define QUARD_MINIMIZER(qm, u, fu, du, v, fv) \
1081
- a = (v) - (u); \
1082
- (qm) = (u) + (du) / (((fu) - (fv)) / a + (du)) / 2 * a;
1083
-
1084
- /**
1085
- * Find a minimizer of an interpolated quadratic function.
1086
- * @param qm The minimizer of the interpolated quadratic.
1087
- * @param u The value of one point, u.
1088
- * @param du The value of f'(u).
1089
- * @param v The value of another point, v.
1090
- * @param dv The value of f'(v).
1091
- */
1092
- #define QUARD_MINIMIZER2(qm, u, du, v, dv) \
1093
- a = (u) - (v); \
1094
- (qm) = (v) + (dv) / ((dv) - (du)) * a;
1095
-
1096
- /**
1097
- * Update a safeguarded trial value and interval for line search.
1098
- *
1099
- * The parameter x represents the step with the least function value.
1100
- * The parameter t represents the current step. This function assumes
1101
- * that the derivative at the point of x in the direction of the step.
1102
- * If the bracket is set to true, the minimizer has been bracketed in
1103
- * an interval of uncertainty with endpoints between x and y.
1104
- *
1105
- * @param x The pointer to the value of one endpoint.
1106
- * @param fx The pointer to the value of f(x).
1107
- * @param dx The pointer to the value of f'(x).
1108
- * @param y The pointer to the value of another endpoint.
1109
- * @param fy The pointer to the value of f(y).
1110
- * @param dy The pointer to the value of f'(y).
1111
- * @param t The pointer to the value of the trial value, t.
1112
- * @param ft The pointer to the value of f(t).
1113
- * @param dt The pointer to the value of f'(t).
1114
- * @param tmin The minimum value for the trial value, t.
1115
- * @param tmax The maximum value for the trial value, t.
1116
- * @param brackt The pointer to the predicate if the trial value is
1117
- * bracketed.
1118
- * @retval int Status value. Zero indicates a normal termination.
1119
- *
1120
- * @see
1121
- * Jorge J. More and David J. Thuente. Line search algorithm with
1122
- * guaranteed sufficient decrease. ACM Transactions on Mathematical
1123
- * Software (TOMS), Vol 20, No 3, pp. 286-307, 1994.
1124
- */
1125
- static int update_trial_interval(
1126
- lbfgsfloatval_t *x,
1127
- lbfgsfloatval_t *fx,
1128
- lbfgsfloatval_t *dx,
1129
- lbfgsfloatval_t *y,
1130
- lbfgsfloatval_t *fy,
1131
- lbfgsfloatval_t *dy,
1132
- lbfgsfloatval_t *t,
1133
- lbfgsfloatval_t *ft,
1134
- lbfgsfloatval_t *dt,
1135
- const lbfgsfloatval_t tmin,
1136
- const lbfgsfloatval_t tmax,
1137
- int *brackt
1138
- )
1139
- {
1140
- int bound;
1141
- int dsign = fsigndiff(dt, dx);
1142
- lbfgsfloatval_t mc; /* minimizer of an interpolated cubic. */
1143
- lbfgsfloatval_t mq; /* minimizer of an interpolated quadratic. */
1144
- lbfgsfloatval_t newt; /* new trial value. */
1145
- USES_MINIMIZER; /* for CUBIC_MINIMIZER and QUARD_MINIMIZER. */
1146
-
1147
- /* Check the input parameters for errors. */
1148
- if (*brackt) {
1149
- if (*t <= min2(*x, *y) || max2(*x, *y) <= *t) {
1150
- /* The trival value t is out of the interval. */
1151
- return LBFGSERR_OUTOFINTERVAL;
1152
- }
1153
- if (0. <= *dx * (*t - *x)) {
1154
- /* The function must decrease from x. */
1155
- return LBFGSERR_INCREASEGRADIENT;
1156
- }
1157
- if (tmax < tmin) {
1158
- /* Incorrect tmin and tmax specified. */
1159
- return LBFGSERR_INCORRECT_TMINMAX;
1160
- }
1161
- }
1162
-
1163
- /*
1164
- Trial value selection.
1165
- */
1166
- if (*fx < *ft) {
1167
- /*
1168
- Case 1: a higher function value.
1169
- The minimum is brackt. If the cubic minimizer is closer
1170
- to x than the quadratic one, the cubic one is taken, else
1171
- the average of the minimizers is taken.
1172
- */
1173
- *brackt = 1;
1174
- bound = 1;
1175
- CUBIC_MINIMIZER(mc, *x, *fx, *dx, *t, *ft, *dt);
1176
- QUARD_MINIMIZER(mq, *x, *fx, *dx, *t, *ft);
1177
- if (fabs(mc - *x) < fabs(mq - *x)) {
1178
- newt = mc;
1179
- } else {
1180
- newt = mc + 0.5 * (mq - mc);
1181
- }
1182
- } else if (dsign) {
1183
- /*
1184
- Case 2: a lower function value and derivatives of
1185
- opposite sign. The minimum is brackt. If the cubic
1186
- minimizer is closer to x than the quadratic (secant) one,
1187
- the cubic one is taken, else the quadratic one is taken.
1188
- */
1189
- *brackt = 1;
1190
- bound = 0;
1191
- CUBIC_MINIMIZER(mc, *x, *fx, *dx, *t, *ft, *dt);
1192
- QUARD_MINIMIZER2(mq, *x, *dx, *t, *dt);
1193
- if (fabs(mc - *t) > fabs(mq - *t)) {
1194
- newt = mc;
1195
- } else {
1196
- newt = mq;
1197
- }
1198
- } else if (fabs(*dt) < fabs(*dx)) {
1199
- /*
1200
- Case 3: a lower function value, derivatives of the
1201
- same sign, and the magnitude of the derivative decreases.
1202
- The cubic minimizer is only used if the cubic tends to
1203
- infinity in the direction of the minimizer or if the minimum
1204
- of the cubic is beyond t. Otherwise the cubic minimizer is
1205
- defined to be either tmin or tmax. The quadratic (secant)
1206
- minimizer is also computed and if the minimum is brackt
1207
- then the the minimizer closest to x is taken, else the one
1208
- farthest away is taken.
1209
- */
1210
- bound = 1;
1211
- CUBIC_MINIMIZER2(mc, *x, *fx, *dx, *t, *ft, *dt, tmin, tmax);
1212
- QUARD_MINIMIZER2(mq, *x, *dx, *t, *dt);
1213
- if (*brackt) {
1214
- if (fabs(*t - mc) < fabs(*t - mq)) {
1215
- newt = mc;
1216
- } else {
1217
- newt = mq;
1218
- }
1219
- } else {
1220
- if (fabs(*t - mc) > fabs(*t - mq)) {
1221
- newt = mc;
1222
- } else {
1223
- newt = mq;
1224
- }
1225
- }
1226
- } else {
1227
- /*
1228
- Case 4: a lower function value, derivatives of the
1229
- same sign, and the magnitude of the derivative does
1230
- not decrease. If the minimum is not brackt, the step
1231
- is either tmin or tmax, else the cubic minimizer is taken.
1232
- */
1233
- bound = 0;
1234
- if (*brackt) {
1235
- CUBIC_MINIMIZER(newt, *t, *ft, *dt, *y, *fy, *dy);
1236
- } else if (*x < *t) {
1237
- newt = tmax;
1238
- } else {
1239
- newt = tmin;
1240
- }
1241
- }
1242
-
1243
- /*
1244
- Update the interval of uncertainty. This update does not
1245
- depend on the new step or the case analysis above.
1246
-
1247
- - Case a: if f(x) < f(t),
1248
- x <- x, y <- t.
1249
- - Case b: if f(t) <= f(x) && f'(t)*f'(x) > 0,
1250
- x <- t, y <- y.
1251
- - Case c: if f(t) <= f(x) && f'(t)*f'(x) < 0,
1252
- x <- t, y <- x.
1253
- */
1254
- if (*fx < *ft) {
1255
- /* Case a */
1256
- *y = *t;
1257
- *fy = *ft;
1258
- *dy = *dt;
1259
- } else {
1260
- /* Case c */
1261
- if (dsign) {
1262
- *y = *x;
1263
- *fy = *fx;
1264
- *dy = *dx;
1265
- }
1266
- /* Cases b and c */
1267
- *x = *t;
1268
- *fx = *ft;
1269
- *dx = *dt;
1270
- }
1271
-
1272
- /* Clip the new trial value in [tmin, tmax]. */
1273
- if (tmax < newt) newt = tmax;
1274
- if (newt < tmin) newt = tmin;
1275
-
1276
- /*
1277
- Redefine the new trial value if it is close to the upper bound
1278
- of the interval.
1279
- */
1280
- if (*brackt && bound) {
1281
- mq = *x + 0.66 * (*y - *x);
1282
- if (*x < *y) {
1283
- if (mq < newt) newt = mq;
1284
- } else {
1285
- if (newt < mq) newt = mq;
1286
- }
1287
- }
1288
-
1289
- /* Return the new trial value. */
1290
- *t = newt;
1291
- return 0;
1292
- }
1293
-
1294
-
1295
-
1296
-
1297
-
1298
- static lbfgsfloatval_t owlqn_x1norm(
1299
- const lbfgsfloatval_t* x,
1300
- const int start,
1301
- const int n
1302
- )
1303
- {
1304
- int i;
1305
- lbfgsfloatval_t norm = 0.;
1306
-
1307
- for (i = start;i < n;++i) {
1308
- norm += fabs(x[i]);
1309
- }
1310
-
1311
- return norm;
1312
- }
1313
-
1314
- static void owlqn_pseudo_gradient(
1315
- lbfgsfloatval_t* pg,
1316
- const lbfgsfloatval_t* x,
1317
- const lbfgsfloatval_t* g,
1318
- const int n,
1319
- const lbfgsfloatval_t c,
1320
- const int start,
1321
- const int end
1322
- )
1323
- {
1324
- int i;
1325
-
1326
- /* Compute the negative of gradients. */
1327
- for (i = 0;i < start;++i) {
1328
- pg[i] = g[i];
1329
- }
1330
-
1331
- /* Compute the psuedo-gradients. */
1332
- for (i = start;i < end;++i) {
1333
- if (x[i] < 0.) {
1334
- /* Differentiable. */
1335
- pg[i] = g[i] - c;
1336
- } else if (0. < x[i]) {
1337
- /* Differentiable. */
1338
- pg[i] = g[i] + c;
1339
- } else {
1340
- if (g[i] < -c) {
1341
- /* Take the right partial derivative. */
1342
- pg[i] = g[i] + c;
1343
- } else if (c < g[i]) {
1344
- /* Take the left partial derivative. */
1345
- pg[i] = g[i] - c;
1346
- } else {
1347
- pg[i] = 0.;
1348
- }
1349
- }
1350
- }
1351
-
1352
- for (i = end;i < n;++i) {
1353
- pg[i] = g[i];
1354
- }
1355
- }
1356
-
1357
- static void owlqn_project(
1358
- lbfgsfloatval_t* d,
1359
- const lbfgsfloatval_t* sign,
1360
- const int start,
1361
- const int end
1362
- )
1363
- {
1364
- int i;
1365
-
1366
- for (i = start;i < end;++i) {
1367
- if (d[i] * sign[i] <= 0) {
1368
- d[i] = 0;
1369
- }
1370
- }
1371
- }