lbfgsb 0.1.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,122 +1,81 @@
1
1
  #ifndef LBFGSB_RB_LBFGSB_H_
2
2
  #define LBFGSB_RB_LBFGSB_H_
3
3
 
4
- #include <stdio.h>
5
- #include <stdlib.h>
6
4
  #include <float.h>
7
5
  #include <math.h>
6
+ #include <stdio.h>
7
+ #include <stdlib.h>
8
8
  #include <string.h>
9
9
  #include <time.h>
10
10
 
11
11
  #define TRUE_ (1)
12
12
  #define FALSE_ (0)
13
13
 
14
- extern int setulb_(long *n, long *m, double *x,
15
- double *l, double *u, long *nbd, double *f, double *g,
16
- double *factr, double *pgtol, double *wa, long *iwa,
17
- char *task, long *iprint, char *csave, long *lsave,
18
- long *isave, double *dsave);
19
-
20
- extern int mainlb_(long *n, long *m, double *x,
21
- double *l, double *u, long *nbd, double *f, double *g,
22
- double *factr, double *pgtol, double *ws, double *wy,
23
- double *sy, double *ss, double *wt, double *wn,
24
- double *snd, double *z__, double *r__, double *d__,
25
- double *t, double *xp, double *wa, long *index,
26
- long *iwhere, long *indx2, char *task, long *iprint,
27
- char *csave, long *lsave, long *isave, double *dsave);
28
-
29
- extern int active_(long *n, double *l, double *u,
30
- long *nbd, double *x, long *iwhere, long *iprint,
31
- long *prjctd, long *cnstnd, long *boxed);
32
-
33
- extern int bmv_(long *m, double *sy, double *wt, long
34
- *col, double *v, double *p, long *info);
35
-
36
- extern int cauchy_(long *n, double *x, double *l,
37
- double *u, long *nbd, double *g, long *iorder, long *iwhere,
38
- double *t, double *d__, double *xcp, long *m,
39
- double *wy, double *ws, double *sy, double *wt,
40
- double *theta, long *col, long *head, double *p,
41
- double *c__, double *wbp, double *v, long *nseg,
42
- long *iprint, double *sbgnrm, long *info, double *epsmch);
43
-
44
- extern int cmprlb_(long *n, long *m, double *x,
45
- double *g, double *ws, double *wy, double *sy,
46
- double *wt, double *z__, double *r__, double *wa,
47
- long *index, double *theta, long *col, long *head,
48
- long *nfree, long *cnstnd, long *info);
49
-
50
- extern int errclb_(long *n, long *m, double *factr,
51
- double *l, double *u, long *nbd, char *task, long *info, long *k);
52
-
53
- extern int formk_(long *n, long *nsub, long *ind, long *nenter,
54
- long *ileave, long *indx2, long *iupdat, long *updatd,
55
- double *wn, double *wn1, long *m, double *ws,
56
- double *wy, double *sy, double *theta, long *col,
57
- long *head, long *info);
58
-
59
- extern int formt_(long *m, double *wt, double *sy,
60
- double *ss, long *col, double *theta, long *info);
61
-
62
- extern int freev_(long *n, long *nfree, long *index,
63
- long *nenter, long *ileave, long *indx2, long *iwhere,
64
- long *wrk, long *updatd, long *cnstnd, long *iprint,
65
- long *iter);
66
-
67
- extern int hpsolb_(long *n, double *t, long *iorder, long *iheap);
68
-
69
- extern int lnsrlb_(long *n, double *l, double *u,
70
- long *nbd, double *x, double *f, double *fold,
71
- double *gd, double *gdold, double *g, double *d__,
72
- double *r__, double *t, double *z__, double *stp,
73
- double *dnorm, double *dtd, double *xstep, double *stpmx,
74
- long *iter, long *ifun, long *iback, long *nfgv,
75
- long *info, char *task, long *boxed, long *cnstnd,
76
- char *csave, long *isave, double *dsave);
77
-
78
- extern int matupd_(long *n, long *m, double *ws,
79
- double *wy, double *sy, double *ss, double *d__,
80
- double *r__, long *itail, long *iupdat, long *col,
81
- long *head, double *theta, double *rr, double *dr,
82
- double *stp, double *dtd);
83
-
84
- extern int prn1lb_(long *n, long *m, double *l,
85
- double *u, double *x, long *iprint, long *itfile,
86
- double *epsmch);
87
-
88
- extern int prn2lb_(long *n, double *x, double *f,
89
- double *g, long *iprint, long *itfile, long *iter,
90
- long *nfgv, long *nact, double *sbgnrm, long *nseg, char*word,
91
- long *iword, long *iback, double *stp, double *xstep);
92
-
93
- extern int prn3lb_(long *n, double *x, double *f, char *task,
94
- long *iprint, long *info, long *itfile, long *iter,
95
- long *nfgv, long *nintol, long *nskip, long *nact,
96
- double *sbgnrm, double *time, long *nseg, char *word,
97
- long *iback, double *stp, double *xstep, long *k,
98
- double *cachyt, double *sbtime, double *lnscht);
99
-
100
- extern int projgr_(long *n, double *l, double *u,
101
- long *nbd, double *x, double *g, double *sbgnrm);
102
-
103
- extern int subsm_(long *n, long *m, long *nsub, long *ind,
104
- double *l, double *u, long *nbd, double *x,
105
- double *d__, double *xp, double *ws, double *wy,
106
- double *theta, double *xx, double *gg, long *col,
107
- long *head, long *iword, double *wv, double *wn,
108
- long *iprint, long *info);
109
-
110
- extern int dcsrch_(double *f, double *g, double *stp,
111
- double *ftol, double *gtol, double *xtol,
112
- double *stpmin, double *stpmax,
113
- char *task, long *isave, double *dsave);
114
-
115
- extern int dcstep_(double *stx, double *fx, double *dx,
116
- double *sty, double *fy, double *dy, double *stp,
117
- double *fp, double *dp, long *brackt, double *stpmin,
118
- double *stpmax);
119
-
120
- extern int timer_(double *ttime);
14
+ extern int setulb_(long* n, long* m, double* x, double* l, double* u, long* nbd, double* f, double* g, double* factr,
15
+ double* pgtol, double* wa, long* iwa, char* task, long* iprint, char* csave, long* lsave, long* isave,
16
+ double* dsave);
17
+
18
+ extern int mainlb_(long* n, long* m, double* x, double* l, double* u, long* nbd, double* f, double* g, double* factr,
19
+ double* pgtol, double* ws, double* wy, double* sy, double* ss, double* wt, double* wn, double* snd,
20
+ double* z__, double* r__, double* d__, double* t, double* xp, double* wa, long* index, long* iwhere,
21
+ long* indx2, char* task, long* iprint, char* csave, long* lsave, long* isave, double* dsave);
22
+
23
+ extern int active_(long* n, double* l, double* u, long* nbd, double* x, long* iwhere, long* iprint, long* prjctd, long* cnstnd,
24
+ long* boxed);
25
+
26
+ extern int bmv_(long* m, double* sy, double* wt, long* col, double* v, double* p, long* info);
27
+
28
+ extern int cauchy_(long* n, double* x, double* l, double* u, long* nbd, double* g, long* iorder, long* iwhere, double* t,
29
+ double* d__, double* xcp, long* m, double* wy, double* ws, double* sy, double* wt, double* theta, long* col,
30
+ long* head, double* p, double* c__, double* wbp, double* v, long* nseg, long* iprint, double* sbgnrm,
31
+ long* info, double* epsmch);
32
+
33
+ extern int cmprlb_(long* n, long* m, double* x, double* g, double* ws, double* wy, double* sy, double* wt, double* z__,
34
+ double* r__, double* wa, long* index, double* theta, long* col, long* head, long* nfree, long* cnstnd,
35
+ long* info);
36
+
37
+ extern int errclb_(long* n, long* m, double* factr, double* l, double* u, long* nbd, char* task, long* info, long* k);
38
+
39
+ extern int formk_(long* n, long* nsub, long* ind, long* nenter, long* ileave, long* indx2, long* iupdat, long* updatd,
40
+ double* wn, double* wn1, long* m, double* ws, double* wy, double* sy, double* theta, long* col, long* head,
41
+ long* info);
42
+
43
+ extern int formt_(long* m, double* wt, double* sy, double* ss, long* col, double* theta, long* info);
44
+
45
+ extern int freev_(long* n, long* nfree, long* index, long* nenter, long* ileave, long* indx2, long* iwhere, long* wrk,
46
+ long* updatd, long* cnstnd, long* iprint, long* iter);
47
+
48
+ extern int hpsolb_(long* n, double* t, long* iorder, long* iheap);
49
+
50
+ extern int lnsrlb_(long* n, double* l, double* u, long* nbd, double* x, double* f, double* fold, double* gd, double* gdold,
51
+ double* g, double* d__, double* r__, double* t, double* z__, double* stp, double* dnorm, double* dtd,
52
+ double* xstep, double* stpmx, long* iter, long* ifun, long* iback, long* nfgv, long* info, char* task,
53
+ long* boxed, long* cnstnd, char* csave, long* isave, double* dsave);
54
+
55
+ extern int matupd_(long* n, long* m, double* ws, double* wy, double* sy, double* ss, double* d__, double* r__, long* itail,
56
+ long* iupdat, long* col, long* head, double* theta, double* rr, double* dr, double* stp, double* dtd);
57
+
58
+ extern int prn1lb_(long* n, long* m, double* l, double* u, double* x, long* iprint, long* itfile, double* epsmch);
59
+
60
+ extern int prn2lb_(long* n, double* x, double* f, double* g, long* iprint, long* itfile, long* iter, long* nfgv, long* nact,
61
+ double* sbgnrm, long* nseg, char* word, long* iword, long* iback, double* stp, double* xstep);
62
+
63
+ extern int prn3lb_(long* n, double* x, double* f, char* task, long* iprint, long* info, long* itfile, long* iter, long* nfgv,
64
+ long* nintol, long* nskip, long* nact, double* sbgnrm, double* time, long* nseg, char* word, long* iback,
65
+ double* stp, double* xstep, long* k, double* cachyt, double* sbtime, double* lnscht);
66
+
67
+ extern int projgr_(long* n, double* l, double* u, long* nbd, double* x, double* g, double* sbgnrm);
68
+
69
+ extern int subsm_(long* n, long* m, long* nsub, long* ind, double* l, double* u, long* nbd, double* x, double* d__, double* xp,
70
+ double* ws, double* wy, double* theta, double* xx, double* gg, long* col, long* head, long* iword, double* wv,
71
+ double* wn, long* iprint, long* info);
72
+
73
+ extern int dcsrch_(double* f, double* g, double* stp, double* ftol, double* gtol, double* xtol, double* stpmin, double* stpmax,
74
+ char* task, long* isave, double* dsave);
75
+
76
+ extern int dcstep_(double* stx, double* fx, double* dx, double* sty, double* fy, double* dy, double* stp, double* fp,
77
+ double* dp, long* brackt, double* stpmin, double* stpmax);
78
+
79
+ extern int timer_(double* ttime);
121
80
 
122
81
  #endif /* LBFGSB_RB_LBFGSB_H_ */
@@ -4,8 +4,8 @@
4
4
  * Please read attached file License.txt
5
5
  */
6
6
 
7
- #include "blas.h"
8
7
  #include "linpack.h"
8
+ #include "blas.h"
9
9
 
10
10
  static long c__1 = 1;
11
11
 
@@ -44,8 +44,7 @@ static long c__1 = 1;
44
44
  * linpack. this version dated 08/14/78 .
45
45
  * cleve moler, university of new mexico, argonne national lab.
46
46
  */
47
- int dpofa_(double *a, long *lda, long *n, long *info)
48
- {
47
+ int lbfgsb_rb_dpofa_(double* a, long* lda, long* n, long* info) {
49
48
  long a_dim1, a_offset, i__1, i__2, i__3;
50
49
  static long j, k;
51
50
  static double s, t;
@@ -57,27 +56,27 @@ int dpofa_(double *a, long *lda, long *n, long *info)
57
56
 
58
57
  i__1 = *n;
59
58
  for (j = 1; j <= i__1; ++j) {
60
- *info = j;
61
- s = 0.;
62
- jm1 = j - 1;
63
- if (jm1 < 1) {
64
- goto L20;
65
- }
66
- i__2 = jm1;
67
- for (k = 1; k <= i__2; ++k) {
68
- i__3 = k - 1;
69
- t = a[k + j * a_dim1] - ddot_(&i__3, &a[k * a_dim1 + 1], &c__1, &a[j * a_dim1 + 1], &c__1);
70
- t /= a[k + k * a_dim1];
71
- a[k + j * a_dim1] = t;
72
- s += t * t;
73
- }
74
- L20:
75
- s = a[j + j * a_dim1] - s;
59
+ *info = j;
60
+ s = 0.;
61
+ jm1 = j - 1;
62
+ if (jm1 < 1) {
63
+ goto L20;
64
+ }
65
+ i__2 = jm1;
66
+ for (k = 1; k <= i__2; ++k) {
67
+ i__3 = k - 1;
68
+ t = a[k + j * a_dim1] - lbfgsb_rb_ddot_(&i__3, &a[k * a_dim1 + 1], &c__1, &a[j * a_dim1 + 1], &c__1);
69
+ t /= a[k + k * a_dim1];
70
+ a[k + j * a_dim1] = t;
71
+ s += t * t;
72
+ }
73
+ L20:
74
+ s = a[j + j * a_dim1] - s;
76
75
  /* ......exit */
77
- if (s <= 0.) {
78
- goto L40;
79
- }
80
- a[j + j * a_dim1] = sqrt(s);
76
+ if (s <= 0.) {
77
+ goto L40;
78
+ }
79
+ a[j + j * a_dim1] = sqrt(s);
81
80
  }
82
81
  *info = 0;
83
82
  L40:
@@ -133,8 +132,7 @@ L40:
133
132
  * linpack. this version dated 08/14/78 .
134
133
  * g. w. stewart, university of maryland, argonne national lab.
135
134
  */
136
- int dtrsl_(double *t, long *ldt, long *n, double *b, long *job, long *info)
137
- {
135
+ int lbfgsb_rb_dtrsl_(double* t, long* ldt, long* n, double* b, long* job, long* info) {
138
136
  long t_dim1, t_offset, i__1, i__2;
139
137
  static long j, jj, case__;
140
138
  static double temp;
@@ -148,39 +146,43 @@ int dtrsl_(double *t, long *ldt, long *n, double *b, long *job, long *info)
148
146
  i__1 = *n;
149
147
  for (*info = 1; *info <= i__1; ++(*info)) {
150
148
  /* ......exit */
151
- if (t[*info + *info * t_dim1] == 0.) {
152
- goto L150;
153
- }
149
+ if (t[*info + *info * t_dim1] == 0.) {
150
+ goto L150;
151
+ }
154
152
  }
155
153
  *info = 0;
156
154
 
157
155
  /* determine the task and go to it. */
158
156
  case__ = 1;
159
157
  if (*job % 10 != 0) {
160
- case__ = 2;
158
+ case__ = 2;
161
159
  }
162
160
  if (*job % 100 / 10 != 0) {
163
- case__ += 2;
161
+ case__ += 2;
164
162
  }
165
163
  switch (case__) {
166
- case 1: goto L20;
167
- case 2: goto L50;
168
- case 3: goto L80;
169
- case 4: goto L110;
164
+ case 1:
165
+ goto L20;
166
+ case 2:
167
+ goto L50;
168
+ case 3:
169
+ goto L80;
170
+ case 4:
171
+ goto L110;
170
172
  }
171
173
 
172
174
  /* solve t*x=b for t lower triangular */
173
175
  L20:
174
176
  b[1] /= t[t_dim1 + 1];
175
177
  if (*n < 2) {
176
- goto L40;
178
+ goto L40;
177
179
  }
178
180
  i__1 = *n;
179
181
  for (j = 2; j <= i__1; ++j) {
180
- temp = -b[j - 1];
181
- i__2 = *n - j + 1;
182
- daxpy_(&i__2, &temp, &t[j + (j - 1) * t_dim1], &c__1, &b[j], &c__1);
183
- b[j] /= t[j + j * t_dim1];
182
+ temp = -b[j - 1];
183
+ i__2 = *n - j + 1;
184
+ lbfgsb_rb_daxpy_(&i__2, &temp, &t[j + (j - 1) * t_dim1], &c__1, &b[j], &c__1);
185
+ b[j] /= t[j + j * t_dim1];
184
186
  }
185
187
  L40:
186
188
  goto L140;
@@ -189,14 +191,14 @@ L40:
189
191
  L50:
190
192
  b[*n] /= t[*n + *n * t_dim1];
191
193
  if (*n < 2) {
192
- goto L70;
194
+ goto L70;
193
195
  }
194
196
  i__1 = *n;
195
197
  for (jj = 2; jj <= i__1; ++jj) {
196
- j = *n - jj + 1;
197
- temp = -b[j + 1];
198
- daxpy_(&j, &temp, &t[(j + 1) * t_dim1 + 1], &c__1, &b[1], &c__1);
199
- b[j] /= t[j + j * t_dim1];
198
+ j = *n - jj + 1;
199
+ temp = -b[j + 1];
200
+ lbfgsb_rb_daxpy_(&j, &temp, &t[(j + 1) * t_dim1 + 1], &c__1, &b[1], &c__1);
201
+ b[j] /= t[j + j * t_dim1];
200
202
  }
201
203
  L70:
202
204
  goto L140;
@@ -205,14 +207,14 @@ L70:
205
207
  L80:
206
208
  b[*n] /= t[*n + *n * t_dim1];
207
209
  if (*n < 2) {
208
- goto L100;
210
+ goto L100;
209
211
  }
210
212
  i__1 = *n;
211
213
  for (jj = 2; jj <= i__1; ++jj) {
212
- j = *n - jj + 1;
213
- i__2 = jj - 1;
214
- b[j] -= ddot_(&i__2, &t[j + 1 + j * t_dim1], &c__1, &b[j + 1], &c__1);
215
- b[j] /= t[j + j * t_dim1];
214
+ j = *n - jj + 1;
215
+ i__2 = jj - 1;
216
+ b[j] -= lbfgsb_rb_ddot_(&i__2, &t[j + 1 + j * t_dim1], &c__1, &b[j + 1], &c__1);
217
+ b[j] /= t[j + j * t_dim1];
216
218
  }
217
219
  L100:
218
220
  goto L140;
@@ -221,13 +223,13 @@ L100:
221
223
  L110:
222
224
  b[1] /= t[t_dim1 + 1];
223
225
  if (*n < 2) {
224
- goto L130;
226
+ goto L130;
225
227
  }
226
228
  i__1 = *n;
227
229
  for (j = 2; j <= i__1; ++j) {
228
- i__2 = j - 1;
229
- b[j] -= ddot_(&i__2, &t[j * t_dim1 + 1], &c__1, &b[1], &c__1);
230
- b[j] /= t[j + j * t_dim1];
230
+ i__2 = j - 1;
231
+ b[j] -= lbfgsb_rb_ddot_(&i__2, &t[j * t_dim1 + 1], &c__1, &b[1], &c__1);
232
+ b[j] /= t[j + j * t_dim1];
231
233
  }
232
234
  L130:
233
235
  L140:
@@ -3,7 +3,7 @@
3
3
 
4
4
  #include <math.h>
5
5
 
6
- extern int dpofa_(double *a, long *lda, long *n, long *info);
7
- extern int dtrsl_(double *t, long *ldt, long *n, double *b, long *job, long *info);
6
+ extern int lbfgsb_rb_dpofa_(double* a, long* lda, long* n, long* info);
7
+ extern int lbfgsb_rb_dtrsl_(double* t, long* ldt, long* n, double* b, long* job, long* info);
8
8
 
9
9
  #endif /* LBFGSB_RB_LINPACK_H_ */
data/lbfgsb.gemspec CHANGED
@@ -6,14 +6,18 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ['yoshoku']
7
7
  spec.email = ['yoshoku@outlook.com']
8
8
 
9
- spec.summary = 'Lbfgsb.rb is a Ruby binding for L-BFGS-B'
10
- spec.description = 'Lbfgsb.rb is a Ruby binding for L-BFGS-B'
9
+ spec.summary = 'Lbfgsb.rb is a Ruby binding for L-BFGS-B.'
10
+ spec.description = <<~MSG
11
+ Lbfgsb.rb is a Ruby binding for L-BFGS-B that is a limited-memory algorithm for
12
+ solving large nonlinear optimization problems subject to simple bounds on the variables.
13
+ MSG
11
14
  spec.homepage = 'https://github.com/yoshoku/lbfgsb.rb'
12
15
  spec.license = 'BSD-3-Clause'
13
16
 
14
- spec.metadata['homepage_uri'] = spec.homepage
15
- spec.metadata['source_code_uri'] = 'https://github.com/yoshoku/lbfgsb.rb'
16
- spec.metadata['changelog_uri'] = 'https://github.com/yoshoku/lbfgsb.rb/CHANGELOG.md'
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/yoshoku/lbfgsb.rb'
19
+ spec.metadata['changelog_uri'] = 'https://github.com/yoshoku/lbfgsb.rb/blob/main/CHANGELOG.md'
20
+ spec.metadata['documentation_uri'] = 'https://yoshoku.github.io/lbfgsb.rb/doc/'
17
21
 
18
22
  # Specify which files should be added to the gem when it is released.
19
23
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
data/lib/lbfgsb.rb CHANGED
@@ -12,23 +12,33 @@ module Lbfgsb
12
12
  #
13
13
  # @param fnc [Method/Proc] Method for calculating the function to be minimized.
14
14
  # @param x_init [Numo::DFloat] (shape: [n_elements]) Initial point.
15
- # @param jcb [Method/Proc] Method for calculating the gradient vector.
15
+ # @param jcb [Method/Proc/Boolean] Method for calculating the gradient vector.
16
+ # If true is given, fnc is assumed to return the function value and gardient vector as [f, g] array.
16
17
  # @param args [Object] Arguments pass to the 'fnc' and 'jcb'.
17
18
  # @param bounds [Numo::DFloat/Nil] (shape: [n_elements, 2])
18
19
  # \[lower, upper\] bounds for each element x. If nil is given, x is unbounded.
19
20
  # @param factr [Float] The iteration will be stop when
20
21
  #
21
- # `(f^k - f^\{k+1\})/max{|f^k|,|f^\{k+1\}|,1} <= factr * Lbfgsb::DBL_EPSILON`
22
+ # (f^k - f^\{k+1\})/max{|f^k|,|f^\{k+1\}|,1} <= factr * Lbfgsb::DBL_EPSILON
22
23
  #
23
24
  # Typical values for factr: 1e12 for low accuracy; 1e7 for moderate accuracy; 1e1 for extremely high accuracy.
24
25
  # @param pgtol [Float] The iteration will be stop when
25
26
  #
26
- # `max{|pg_i| i = 1, ..., n} <= pgtol`
27
+ # max{|pg_i| i = 1, ..., n} <= pgtol
27
28
  #
28
29
  # where pg_i is the ith component of the projected gradient.
29
30
  # @param maxcor [Integer] The maximum number of variable metric corrections used to define the limited memory matrix.
30
31
  # @param maxiter [Integer] The maximum number of iterations.
31
32
  # @param verbose [Integer/Nil] If negative value or nil is given, no display output is generated.
33
+ # @return [Hash] Optimization results; { x:, n_fev:, n_jev:, n_iter:, fnc:, jcb:, task:, success: }
34
+ # - x [Numo::DFloat] Updated vector by optimization.
35
+ # - n_fev [Interger] Number of calls of the objective function.
36
+ # - n_jev [Integer] Number of calls of the jacobian.
37
+ # - n_iter [Integer] Number of iterations.
38
+ # - fnc [Float] Value of the objective function.
39
+ # - jcb [Numo::Narray] Values of the jacobian
40
+ # - task [String] Description of the cause of the termination.
41
+ # - success [Boolean] Whether or not the optimization exited successfully.
32
42
  def minimize(fnc:, x_init:, jcb:, args: nil, bounds: nil, factr: 1e7, pgtol: 1e-5, maxcor: 10, maxiter: 15_000, verbose: nil)
33
43
  n_elements = x_init.size
34
44
  l = Numo::DFloat.zeros(n_elements)